@clickview/lite 0.70.1-dev.2 → 0.70.1-dev.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundles.json +1 -1
- package/dist/languages/en.json +1 -1
- package/dist/scripts/3596-7f32e7d4c0-lite.chunk.js +3 -0
- package/dist/scripts/3596-7f32e7d4c0-lite.chunk.js.map +1 -0
- package/dist/scripts/4050-cd4d18058a-lite.chunk.js +3 -0
- package/dist/scripts/4050-cd4d18058a-lite.chunk.js.map +1 -0
- package/dist/scripts/5829-689f5be5d1-lite.chunk.js +3 -0
- package/dist/scripts/5829-689f5be5d1-lite.chunk.js.map +1 -0
- package/dist/scripts/7042-65a932d16b-lite.chunk.js +2 -0
- package/dist/scripts/{7042-aaaf6e286f-lite.chunk.js.map → 7042-65a932d16b-lite.chunk.js.map} +1 -1
- package/dist/scripts/7428-546d62999f-lite.chunk.js +2 -0
- package/dist/scripts/7428-546d62999f-lite.chunk.js.map +1 -0
- package/dist/scripts/{8280-287760fb57-lite.chunk.js → 8280-8bb89d0a89-lite.chunk.js} +2 -2
- package/dist/scripts/8280-8bb89d0a89-lite.chunk.js.map +1 -0
- package/dist/scripts/8832-73ffd39e2a-lite.chunk.js +2 -0
- package/dist/scripts/{8832-aa3df17f66-lite.chunk.js.map → 8832-73ffd39e2a-lite.chunk.js.map} +1 -1
- package/dist/scripts/9973-648be9b72a-lite.chunk.js +2 -0
- package/dist/scripts/9973-648be9b72a-lite.chunk.js.map +1 -0
- package/dist/scripts/bundle-7514add562.min.js +3 -0
- package/dist/scripts/{bundle-4b10174000.min.js.map → bundle-7514add562.min.js.map} +1 -1
- package/package.json +1 -1
- package/dist/scripts/3596-191624e307-lite.chunk.js +0 -3
- package/dist/scripts/3596-191624e307-lite.chunk.js.map +0 -1
- package/dist/scripts/4050-74aa5394f6-lite.chunk.js +0 -3
- package/dist/scripts/4050-74aa5394f6-lite.chunk.js.map +0 -1
- package/dist/scripts/5829-5b395badf2-lite.chunk.js +0 -3
- package/dist/scripts/5829-5b395badf2-lite.chunk.js.map +0 -1
- package/dist/scripts/7042-aaaf6e286f-lite.chunk.js +0 -2
- package/dist/scripts/741-98a532e970-lite.chunk.js +0 -2
- package/dist/scripts/741-98a532e970-lite.chunk.js.map +0 -1
- package/dist/scripts/7428-6dd787bc07-lite.chunk.js +0 -2
- package/dist/scripts/7428-6dd787bc07-lite.chunk.js.map +0 -1
- package/dist/scripts/8280-287760fb57-lite.chunk.js.map +0 -1
- package/dist/scripts/8832-aa3df17f66-lite.chunk.js +0 -2
- package/dist/scripts/bundle-4b10174000.min.js +0 -3
- /package/dist/scripts/{3596-191624e307-lite.chunk.js.LICENSE.txt → 3596-7f32e7d4c0-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{4050-74aa5394f6-lite.chunk.js.LICENSE.txt → 4050-cd4d18058a-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{5829-5b395badf2-lite.chunk.js.LICENSE.txt → 5829-689f5be5d1-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{bundle-4b10174000.min.js.LICENSE.txt → bundle-7514add562.min.js.LICENSE.txt} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scripts/3596-191624e307-lite.chunk.js","mappings":"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","sources":["file:///app/packages/projects/player/src/components/cog-button/collapsible-heading-menu-item.ts","file:///app/packages/projects/player/src/components/menu/menu.ts","file:///app/packages/projects/player/src/components/search-input-menu-item/search-input-menu-item.ts","file:///app/packages/projects/player/src/interfaces/models/ApiError.ts","file:///app/packages/projects/player/src/components/cog-button/cog-button.ts","file:///app/packages/projects/player/src/components/subtitle-size-button/subtitle-size-button.ts","file:///app/packages/projects/player/src/components/subtitle-search-button/subtitle-result-menu-item.ts","file:///app/packages/projects/player/src/components/subtitle-search-button/subtitle-search-button.ts","file:///app/packages/projects/player/src/components/keyboard-shortcuts-button/keyboard-shortcuts-button.ts","file:///app/packages/projects/player/src/components/collapserator/collapserator.ts","file:///app/packages/projects/player/src/services/analytics-service.ts","file:///app/packages/projects/player/src/utils/hotkeys.ts","file:///app/packages/projects/player/src/interfaces/models/PlayerApiErrorType.ts","file:///app/packages/projects/player/src/plugins/configure-menu-dimensions-plugin/configure-menu-dimensions-plugin.ts","file:///app/packages/projects/player/src/plugins/persist-volume-plugin/persist-volume-plugin.ts","file:///app/packages/projects/player/src/plugins/persist-playback-rate-plugin/persist-playback-rate-plugin.ts","file:///app/packages/projects/player/src/plugins/fullscreen-on-rotate-plugin/fullscreen-on-rotate-plugin.ts","file:///app/packages/projects/player/src/components/logo/clickview-logo.ts","file:///app/packages/projects/player/src/plugins/open-externally-plugin/components/open-externally-button.ts","file:///app/packages/projects/player/src/plugins/open-externally-plugin/open-externally-plugin.ts","file:///app/packages/projects/player/src/plugins/touch-controls-plugin/components/touch-controls/touch-controls.ts","file:///app/packages/projects/player/src/plugins/touch-controls-plugin/touch-controls-plugin.ts","file:///app/packages/projects/player/src/plugins/progressive-files-plugin/ProgressiveRepresentation.ts","file:///app/packages/projects/player/src/plugins/progressive-files-plugin/progressive-files-plugin.ts","file:///app/packages/projects/player/src/utils/quality-helper.ts","file:///app/packages/projects/player/src/plugins/localcache-plugin/LocalCache.ts","file:///app/packages/projects/player/src/plugins/localcache-plugin/localcache-middleware.ts","file:///app/packages/projects/player/src/plugins/localcache-plugin/compontents/local-cache-indicator.ts","file:///app/packages/projects/player/src/plugins/localcache-plugin/localcache-plugin.ts","file:///app/packages/projects/player/src/plugins/handle-network-errors-plugin/handle-network-errors-plugin.ts","file:///app/packages/projects/player/src/plugins/persist-subtitle-settings-plugin/persist-subtitle-settings-plugin.ts","file:///app/packages/projects/player/src/plugins/persist-quality-settings-plugin/persist-quality-settings-plugin.ts","file:///app/packages/projects/player/src/plugins/progress-reporter-plugin/components/progress-reporter-display.ts","file:///app/packages/projects/player/src/plugins/progress-reporter-plugin/progress-reporter-plugin.ts","file:///app/packages/projects/player/src/plugins/whiteboard-mode-plugin/components/drag-handle/drag-handle.ts","file:///app/packages/projects/player/src/plugins/whiteboard-mode-plugin/contants/WhiteboardSides.ts","file:///app/packages/projects/player/src/plugins/whiteboard-mode-plugin/components/drag-targets/drag-targets.ts","file:///app/packages/projects/player/src/plugins/whiteboard-mode-plugin/components/whiteboard-mode-button/whiteboard-mode-menu-item.ts","file:///app/packages/projects/player/src/plugins/whiteboard-mode-plugin/components/whiteboard-mode-button/whiteboard-mode-button.ts","file:///app/packages/projects/player/src/plugins/whiteboard-mode-plugin/whiteboard-mode-plugin.ts","file:///app/packages/projects/player/src/plugins/defer-menus-plugin/defer-menus-plugin.ts","file:///app/packages/projects/player/src/components/mute-button/mute-button.ts","file:///app/packages/projects/player/src/components/player-overlay/player-overlay.ts","file:///app/packages/projects/player/src/plugins/player-mode-plugin/player-mode-plugin.ts","file:///app/packages/projects/player/src/plugins/favourite-plugin/components/favourite-button.ts","file:///app/packages/projects/player/src/plugins/favourite-plugin/favourite-plugin.ts","file:///app/packages/projects/player/src/components/menu-button/menu-button.ts","file:///app/packages/projects/player/src/components/time-wrapper/time-wrapper.ts","file:///app/packages/projects/player/src/components/seek-bar/seek-bar.ts","file:///app/packages/projects/player/src/components/chapter-bar-items/chapter-bar-load-progress.ts","file:///app/packages/projects/player/src/components/chapter-bar-items/chapter-bar-play-progress.ts","file:///app/packages/projects/player/src/components/chapter-bar-items/chapter-bar-item.ts","file:///app/packages/projects/player/src/components/chapter-bar-items/chapter-bar-items.ts","file:///app/packages/projects/player/src/components/chapter-seek-bar/chapter-seek-bar.ts","file:///app/packages/projects/player/src/components/progress-control/progress-control.ts","file:///app/packages/projects/player/src/components/time-tooltip/time-tooltip.ts","file:///app/packages/projects/player/src/components/thumbnail-display/thumbnail-display.ts","file:///app/packages/projects/player/src/components/mouse-time-display/mouse-time-display.ts","file:///app/packages/projects/player/src/components/chapters-button/chapter-menu-item.ts","file:///app/packages/projects/player/src/components/chapters-button/chapters-button.ts","file:///app/packages/projects/player/src/components/text-track-button/off-text-track-menu-item.ts","file:///app/packages/projects/player/src/components/text-track-button/text-track-button.ts","file:///app/packages/projects/player/src/components/subs-caps-button/SubCapsMenuItem.ts","file:///app/packages/projects/player/src/components/subs-caps-button/subtitle-search-menu-item.ts","file:///app/packages/projects/player/src/components/subs-caps-button/subtitle-size-menu-item.ts","file:///app/packages/projects/player/src/components/subs-caps-button/toggle-transcript-menu-item.ts","file:///app/packages/projects/player/src/components/subs-caps-button/subs-caps-button.ts","file:///app/packages/projects/player/src/components/quality-selector/quality-menu-item.ts","file:///app/packages/projects/player/src/components/quality-selector/quality-button.ts","file:///app/packages/projects/player/src/components/playback-rate-button/playback-rate-button.ts","file:///app/packages/projects/player/src/components/text-track-settings/text-track-settings.ts","file:///app/packages/projects/player/src/components/player/player.ts","file:///app/packages/projects/player/src/components/play-pause-feedback/play-pause-feedback.ts","file:///app/packages/projects/player/src/components/play-toggle/play-toggle.ts","file:///app/packages/projects/player/src/components/text-track-display/text-track-display.ts","file:///app/packages/projects/player/src/components/control-bar/control-bar-gradient.ts","file:///app/packages/projects/player/src/components/poster-image/metadata/splash-title/splash-title.ts","file:///app/packages/projects/player/src/components/poster-image/metadata/splash-warning/splash-warning.ts","file:///app/packages/projects/player/src/components/poster-image/metadata/splash-metadata.ts","file:///app/packages/projects/player/src/components/poster-image/poster-image.ts","file:///app/packages/projects/player/src/components/error-display/error-display.ts","file:///app/packages/projects/player/src/components/fullscreen-toggle/fullscreen-toggle.tsx","file:///app/packages/projects/player/src/players/base-player.ts","file:///app/packages/projects/player/src/plugins/prevent-scrubbing-plugin/components/prevent-scrubbing-tooltip.ts","file:///app/packages/projects/player/src/plugins/prevent-scrubbing-plugin/prevent-scrubbing-plugin.ts","file:///app/packages/projects/player/src/plugins/prevent-scrubbing-plugin/utils/prevent-scrubbing-helper.ts","file:///app/packages/projects/player/src/plugins/theatre-mode-plugin/components/theatre-mode-button.ts","file:///app/packages/projects/player/src/plugins/theatre-mode-plugin/theatre-mode-plugin.ts","file:///app/packages/projects/player/src/plugins/transcript-plugin/components/transcript-header/transcript-header.scss","file:///app/packages/projects/player/src/plugins/transcript-plugin/components/transcript-header/TranscriptHeader.tsx","file:///app/packages/projects/player/src/plugins/transcript-plugin/components/transcript-component.tsx","file:///app/packages/projects/player/src/plugins/transcript-plugin/transcript-plugin.ts","file:///app/packages/projects/player/src/react/react-component.ts","file:///app/packages/projects/player/src/utils/PlayerRatingHelper.ts","file:///app/packages/projects/player/src/utils/ajax-helper.ts","file:///app/packages/projects/player/src/utils/fn.ts","file:///app/packages/projects/player/src/utils/formatTime.ts","file:///app/packages/projects/player/src/utils/getBufferedEnd.ts","file:///app/packages/projects/player/src/utils/track-helper.ts"],"sourcesContent":["import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { CogButton } from './cog-button';\n\nconst MenuItem = videojs.getComponent('MenuItem');\n\ninterface CollapsibleHeadingMenuItemOptions extends videojs.MenuItemOptions {\n onClickBack?: () => void;\n}\n\nexport class CollapsibleHeadingMenuItem extends MenuItem {\n public options_: CollapsibleHeadingMenuItemOptions;\n\n constructor(player: VideoJsPlayer, options?: CollapsibleHeadingMenuItemOptions) {\n super(player, options);\n }\n\n public createEl(): HTMLLIElement {\n return videojs.dom.createEl('li', {\n className: 'vjs-menu-item cv-collapsible-menu-heading cv-divider-after-menu-item',\n innerHTML: `<span class=\"vjs-menu-item-text\">${this.localize(this.options_.label)}</span>`,\n tabIndex: -1\n }) as HTMLLIElement;\n }\n\n public handleClick(event: videojs.EventTarget.Event): void {\n super.handleClick(event);\n\n if (this.options_.onClickBack) {\n this.options_.onClickBack();\n return;\n }\n\n /**\n * The MenuItem handle click and then the corresponding blur\n * event have to fire, otherwise the below line will not run\n * so we execute our click handle in the next frame\n */\n this.requestAnimationFrame(() => {\n const cogButton = this.player_.getChild('collapserator').getChild('cogButton') as CogButton;\n cogButton.pressButton();\n });\n }\n}","import SimpleBar from 'simplebar';\nimport videojs from 'video.js';\n\n/**\n * NOTE: About overriding prototype methods.\n * \n * VideoJS does not use it's component system to retrieve the Menu component before it's used by menu-button.js.\n * Because of this, we have to directly update the prototype of the menu it is importing, rather than using \n * the video.js component system to simply extend and re-assign menu.\n * \n * - Sha\n */\nconst BaseMenu = videojs.getComponent('Menu');\n\nexport const baseMenuCreateEl = BaseMenu.prototype.createEl;\nBaseMenu.prototype.createEl = function createEl(): HTMLDivElement {\n const el = baseMenuCreateEl.call(this);\n\n this.simpleBar = new SimpleBar(this.contentEl() as HTMLElement, { autoHide: false });\n\n return el;\n};\n\nconst _contentEl = BaseMenu.prototype.contentEl;\nBaseMenu.prototype.contentEl = function contentEl(): Element {\n if (!this.simpleBar)\n return _contentEl.call(this);\n\n return this.simpleBar.getContentElement();\n};\n\nconst _dispose = BaseMenu.prototype.dispose;\nBaseMenu.prototype.dispose = function dispose(): void {\n if (this.simpleBar) {\n (this.simpleBar as any).unMount();\n delete this.simpleBar;\n }\n _dispose.call(this);\n};\n\nconst _addItem = BaseMenu.prototype.addItem;\nBaseMenu.prototype.addItem = function addItem(component: string | videojs.MenuItem): void {\n _addItem.call(this, component);\n this.simpleBar.recalculate();\n};\n\nconst _lockShowing = BaseMenu.prototype.lockShowing;\nBaseMenu.prototype.lockShowing = function lockShowing(): void {\n _lockShowing.call(this);\n this.simpleBar.recalculate();\n};\n\n(BaseMenu.prototype as any).recalculateScrollBar = function recalculateScrollBar(): void {\n this.simpleBar.recalculate();\n};\n\n/**\n * The video.js Menu handleBlur function checks if the target is an immediate child\n * but we have scenarios where the target is not an immediate child\n * so we've overridden it here so the target can be any child and \n * the menu will not close.\n */\nconst _handleBlur = (BaseMenu.prototype as any).handleBlur;\n(BaseMenu.prototype as any).handleBlur = function handleBlur(event: videojs.EventTarget.Event): void {\n const relatedTarget = (event.relatedTarget || document.activeElement) as Element;\n\n if (this.el().contains(relatedTarget))\n return;\n\n _handleBlur.call(this, event);\n};","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { debounce } from 'projects/player/utils/fn';\n\nimport './search-input-menu-item.scss';\n\nconst MenuItem = videojs.getComponent('MenuItem');\n\ninterface SearchInputOptions extends videojs.ComponentOptions {\n menuButton: videojs.MenuButton;\n search: (text: string) => void;\n className?: string;\n}\n\nexport class SearchInputMenuItem extends MenuItem {\n public options_: SearchInputOptions;\n\n constructor(player: VideoJsPlayer, options: SearchInputOptions) {\n super(player, options);\n\n this.onChange = debounce(this.onChange, 100, false, this);\n\n this.bindEventListeners();\n }\n\n public createEl(): HTMLLIElement {\n const placeholder = this.localize('Search');\n\n return super.createEl('li', {\n className: `vjs-menu-item cv-search-input-menu-item-container ${this.options_.className || ''}`.trim(),\n innerHTML: `\n <div class=\"cv-search-input-menu-item\">\n <span class=\"cv-search-icon\">\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M15.803 14.306l3.917 3.954a1 1 0 0 1-.007 1.417l-.018.018-.018.018a.997.997 0 0 1-1.41 0l-3.918-3.953-.3.214c-1.14.713-2.323 1.07-3.549 1.07-1.796 0-3.328-.642-4.597-1.925C4.634 13.836 4 12.296 4 10.5c0-1.796.634-3.328 1.903-4.597C7.172 4.634 8.704 4 10.5 4c1.796 0 3.329.634 4.597 1.903 1.27 1.269 1.904 2.801 1.904 4.597a6.447 6.447 0 0 1-1.027 3.507l-.17.3zM10.5 5.368c-1.425 0-2.637.5-3.635 1.497-.998.998-1.497 2.21-1.497 3.635 0 1.426.5 2.637 1.497 3.635.998.998 2.21 1.497 3.635 1.497 1.426 0 2.637-.499 3.635-1.497 1.027-1.026 1.54-2.238 1.54-3.635 0-1.397-.513-2.608-1.54-3.635-.998-.998-2.21-1.497-3.635-1.497z\"/>\n </svg>\n </span><input placeholder=\"${placeholder}\" type=\"text\" autocomplete=\"off\" spellcheck=\"false\" aria-label=\"${placeholder}\" />\n </div>\n `\n });\n }\n\n public focus(): void {\n (this.$('input') as HTMLInputElement).focus();\n }\n\n /**\n * Because we extend MenuItem which will close the menu by default\n * we need to halt the event propogation here\n */\n public handleClick(event: videojs.EventTarget.Event): void {\n event.stopImmediatePropagation();\n (this.$('input') as HTMLInputElement).focus();\n }\n\n /**\n * Prevent the videojs MenuItem intercepting keydowns on the input\n * which is preventing space from working\n */\n public handleKeyDown(): void {\n this.focus();\n }\n\n private bindEventListeners(): void {\n const el = this.$('input');\n\n this.onChange = this.onChange.bind(this);\n el.addEventListener('keyup', this.onChange);\n el.addEventListener('blur', (e: videojs.EventTarget.Event) => {\n (this.options_.menuButton.menu as any).handleBlur(e);\n });\n }\n\n private onChange(event: Event): void {\n const target = event.target as HTMLInputElement;\n this.options_.search(target.value);\n }\n}\n\nvideojs.registerComponent('SearchInputMenuItem', SearchInputMenuItem);\n\nexport class NoMatchingResultsMenuItem extends MenuItem {\n public createEl(tag: string, props: any, attrs: any): HTMLLIElement {\n return super.createEl(tag, {\n ...props,\n className: 'vjs-menu-item cv-no-results'\n }, attrs);\n }\n\n public setLabel(newLabel: string): void {\n const span = this.$('.vjs-menu-item-text');\n \n if (span)\n span.innerHTML = newLabel;\n }\n}\n\nvideojs.registerComponent('NoMatchingResultsMenuItem', NoMatchingResultsMenuItem);","import { ErrorResponse } from 'projects/player/interfaces/models/ErrorResponse';\n\nexport class ApiError extends Error {\n public url: string;\n public response: ErrorResponse;\n\n constructor(url: string, response?: ErrorResponse) {\n super(response?.title || 'Ajax error');\n\n this.url = url;\n this.response = response;\n }\n}\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { CollapsibleComponent } from 'projects/player/interfaces/CollapsibleComponent';\n\nimport './cog-button.scss';\n\nconst MenuItem = videojs.getComponent('MenuItem');\n\ninterface AdditionalMenuItem {\n index: number;\n name: string;\n ctor: typeof MenuItem;\n options?: HashObject;\n}\n\ninterface CogMenuItemOptions extends videojs.ComponentOptions {\n item: CollapsibleComponent;\n}\n\nclass CogMenuItem extends MenuItem {\n // tslint:disable-next-line\n public options_: CogMenuItemOptions;\n private valueHolder_: Element;\n\n constructor(player: VideoJsPlayer, options: CogMenuItemOptions) {\n super(player, options);\n }\n\n public handleClick(event: videojs.EventTarget.Event): void {\n super.handleClick(event);\n\n /**\n * The MenuItem handle click and then the corresponding blur\n * event have to fire, otherwise the below line will not run\n * so we execute our click handle in the next frame\n */\n this.requestAnimationFrame(() => {\n this.options_.item.showCollapsibleMenu();\n });\n }\n\n public createEl(tagName?: string, properties?: any, attributes?: any): HTMLLIElement {\n if (!this.options_.item)\n return super.createEl(tagName, properties, attributes);\n\n const label = this.options_.item.getCollabsibleName();\n const val = this.options_.item.getCollabsibleValue();\n const className = this.options_.item.className;\n\n const innerHTML = `<span class=\"vjs-menu-item-text\">${label}</span>`;\n\n this.valueHolder_ = videojs.dom.createEl('span', {\n innerHTML: val\n });\n\n const el = super.createEl(tagName, {\n className: `vjs-menu-item cv-cog-menu-item ${val ? 'cv-has-cog-value' : ''} ${className || ''}`.trim(),\n innerHTML\n }, attributes);\n el.appendChild(this.valueHolder_);\n return el;\n }\n\n public updateCollapsibleValue(): void {\n this.valueHolder_.innerHTML = this.options_.item.getCollabsibleValue();\n }\n}\n\nconst MenuButton = videojs.getComponent('MenuButton');\n\ninterface CogButtonOptions extends videojs.ComponentOptions {\n items: CollapsibleComponent[];\n}\n\nexport class CogButton extends MenuButton {\n // tslint:disable-next-line\n public options_: CogButtonOptions;\n\n private additionalItems: AdditionalMenuItem[];\n\n constructor(player: VideoJsPlayer, options: CogButtonOptions) {\n super(player, options);\n this.controlText('Settings');\n }\n\n public buildWrapperCSSClass() {\n return `cv-menu-small cv-cog-menu-button ${super.buildWrapperCSSClass()}`;\n }\n\n public buildCSSClass(): string {\n return `cv-cog-button ${super.buildCSSClass()}`;\n }\n\n public pressButton(): void {\n if (this.player_.options_.deferMenus) {\n this.player_.deferMenusPlugin().deferMenu();\n return;\n }\n\n \n this.menu.children_.forEach((c: CogMenuItem) => {\n if (c.updateCollapsibleValue)\n c.updateCollapsibleValue();\n });\n\n super.pressButton();\n }\n\n /**\n * Create the list of menu items. Specific to each subclass.\n *\n * @abstract\n */\n public createItems(): CogMenuItem[] {\n const items: CogMenuItem[] = [];\n\n for (let i = 0; i < this.options_.items.length; i++) {\n const item = this.options_.items[i];\n\n if (!item.isCollabsible)\n continue;\n\n if (!item.showInCollabsibleMenu())\n continue;\n\n if (!item.isCollapsed)\n continue;\n\n items.push(new CogMenuItem(this.player_, {\n item\n }));\n }\n\n if (this.additionalItems?.length) {\n this.additionalItems.forEach(item => {\n const menuItem = new item.ctor(this.player_, { ...this.options_, ...(item.options ?? {}) }) as CogMenuItem;\n items.splice(item.index, 0, menuItem);\n });\n }\n\n return items;\n }\n\n public update(): void {\n super.update();\n this.player_.trigger('resizemenus');\n }\n\n public addItem(item: AdditionalMenuItem): void {\n if (!this.additionalItems)\n this.additionalItems = [];\n\n /**\n * Prevent the same item being added multiple times\n */\n if (this.additionalItems.some(i => i.name === item.name))\n return;\n\n this.additionalItems.push(item);\n this.update();\n }\n}\n\nvideojs.registerComponent('cogButton', CogButton);\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { SubtitleSizes, TextTrackSettings } from 'projects/player/components/text-track-settings/text-track-settings';\nimport { CollapsibleComponent } from 'projects/player/interfaces/CollapsibleComponent';\n\nimport { CollapsibleHeadingMenuItem } from '../cog-button/collapsible-heading-menu-item';\n\nconst MenuItem = videojs.getComponent('MenuItem');\nconst MenuButton = videojs.getComponent('MenuButton') as unknown as typeof videojs.MenuButton;\n\nconst SIZES: SubtitleSizes[] = [ 'large', 'medium', 'small' ];\n\ninterface SubtitleSizeMenuItems extends videojs.MenuItemOptions{\n value: SubtitleSizes;\n}\n\nclass SubtitleSizeMenuItem extends MenuItem {\n public options_: SubtitleSizeMenuItems;\n\n constructor(player: VideoJsPlayer, options: SubtitleSizeMenuItems) {\n super(player, options);\n }\n\n public handleClick(): void {\n const textTrackSettings = (this.player_ as any).textTrackSettings as TextTrackSettings;\n textTrackSettings.setSizeSetting(this.options_.value);\n }\n}\n\nclass SubtitleSizeButton extends MenuButton implements CollapsibleComponent {\n constructor(player: VideoJsPlayer, options?: videojs.MenuButtonOptions) {\n super(player, options);\n\n this.player_.ready(() => {\n this.update();\n });\n }\n\n public createItems(): SubtitleSizeMenuItem[] {\n const textTrackSettings = (this.player_ as any).textTrackSettings as TextTrackSettings;\n\n if (!textTrackSettings)\n return;\n\n const size = textTrackSettings.getSizeSetting();\n\n const items: SubtitleSizeMenuItem[] = [\n new CollapsibleHeadingMenuItem(this.player_, {\n label: 'Caption Text Size',\n onClickBack: () => {\n this.requestAnimationFrame(() => {\n const subCapsButton = this.player_.getChild('collapserator').getChild('subsCapsButton') as any;\n subCapsButton.pressButton();\n });\n }\n }) as any\n ];\n\n SIZES.map(s => {\n items.push(new SubtitleSizeMenuItem(this.player_, {\n label: s.charAt(0).toUpperCase() + s.substring(1),\n selectable: true,\n multiSelectable: false,\n selected: s === size,\n value: s\n }));\n });\n\n return items;\n }\n\n public buildWrapperCSSClass(): string {\n return `cv-menu-small cv-has-left-icons ${super.buildWrapperCSSClass()}`;\n }\n\n /**\n * CollapsibileComponent interface implementation\n * from here onward\n */\n public alwaysCollapsed: boolean = true;\n public isCollapsed: boolean = false;\n public isCollabsible: boolean = true;\n\n public getCollabsibleName(): string {\n return 'Subtitle Size';\n }\n\n public getCollabsibleValue(): string {\n return '';\n }\n\n public showInCollabsibleMenu(): boolean {\n return false;\n }\n\n public showCollapsibleMenu(): void {\n MenuButton.prototype.handleClick.apply(this);\n }\n}\n\nvideojs.registerComponent('SubtitleSizeButton', SubtitleSizeButton);","import videojs, { VideoJsPlayer } from 'video.js';\n\nconst MenuItem = videojs.getComponent('MenuItem');\n\ninterface SubtitleResultMenuItemOptions extends videojs.MenuItemOptions {\n cue: TextTrackCue;\n}\n\nexport class SubtitleResultMenuItem extends MenuItem {\n public options_: SubtitleResultMenuItemOptions;\n\n constructor(player: VideoJsPlayer, options: SubtitleResultMenuItemOptions) {\n super(player, options);\n }\n\n public update(matches: number[], length: number): void {\n if (!matches?.length) {\n this.el().innerHTML = `<span class=\"vjs-menu-item-text\">${this.options_.label}</span>`;\n return;\n }\n\n const parts: string[] = [];\n\n let progress = 0;\n matches.forEach(m => {\n // Adds the starting string before matches\n const start = this.options_.label.substr(progress, m);\n start && parts.push(start);\n\n parts.push('<span class=\"cv-highlight\">');\n parts.push(this.options_.label.substr(m, length));\n parts.push('</span>');\n\n progress = m + length;\n });\n\n // Adds the ending string after matches\n parts.push(this.options_.label.substring(progress, this.options_.label.length));\n\n this.el().innerHTML = `<span class=\"vjs-menu-item-text\">${parts.join('')}</span>`;\n }\n\n public handleClick(event: videojs.EventTarget.Event): void {\n event.stopImmediatePropagation();\n this.player_.currentTime(this.options_.cue.startTime);\n }\n}\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { CollapsibleComponent } from 'projects/player/interfaces/CollapsibleComponent';\nimport { TrackHelper } from 'projects/player/utils/track-helper';\n\nimport { NoMatchingResultsMenuItem, SearchInputMenuItem } from '../search-input-menu-item/search-input-menu-item';\n\nimport { SubtitleResultMenuItem } from './subtitle-result-menu-item';\n\nimport './subtitle-search-button.scss';\n\ntype Matches = {[key: number]: number[]};\n\nconst MenuButton = videojs.getComponent('MenuButton') as unknown as typeof videojs.MenuButton;\n\nexport class SubtitleSearchButton extends MenuButton implements CollapsibleComponent {\n constructor(player: VideoJsPlayer, options?: videojs.MenuButtonOptions) {\n super(player, options);\n\n this.update = this.update.bind(this);\n this.search = this.search.bind(this);\n\n const tracks = this.player_.textTracks();\n tracks.addEventListener('selectedlanguagechange', this.update);\n }\n\n private bindTrackEvents(track: TextTrack): void {\n /**\n * Because theoretically bindTrackEvents could be called multiple times\n * if a track has no cues. We unbind any listners on this event before adding.\n */\n track.removeEventListener('loadeddata', this.update);\n\n track.addEventListener('loadeddata', this.update);\n this.player_.one('dispose', () => {\n track.removeEventListener('loadeddata', this.update);\n });\n }\n\n public createItems(): SubtitleResultMenuItem[] {\n const track = TrackHelper.getCurrentTextTrack(this.player_);\n\n if (!track)\n return;\n\n if (!track.cues?.length) {\n this.bindTrackEvents(track);\n return;\n }\n\n // Adding the search input\n const items: SubtitleResultMenuItem[] = [\n new SearchInputMenuItem(this.player_, {\n menuButton: this,\n search: this.search\n }) as any\n ];\n\n for (let i = 0; i < track.cues.length; i++) {\n const cue = track.cues[i];\n items.push(new SubtitleResultMenuItem(this.player_, {\n cue,\n label: (cue as any).text,\n selected: false,\n multiSelectable: false\n }));\n }\n\n // Adding the no matching results display as the last item\n const noResults = new NoMatchingResultsMenuItem(this.player_, {\n label: 'No matching results',\n selected: false,\n selectable: false,\n multiSelectable: false\n });\n noResults.hide();\n items.push(noResults as any);\n\n return items;\n }\n\n public search(text: string): void {\n text = text.trim();\n\n const track = TrackHelper.getCurrentTextTrack(this.player_);\n\n if (!track?.cues?.length)\n return;\n \n const matches = this.findMatches(text, track);\n this.toggleItemVisibility(text, matches);\n this.toggleNoResults(text, matches);\n }\n\n private findMatches(text: string, track: TextTrack): Matches {\n const matches: any = {};\n\n if (!text)\n return matches;\n\n const regex = new RegExp(text, 'gi');\n\n for (let i = 0; i < track.cues.length; i++) {\n const cue = track.cues[i];\n const cueText = (cue as any).text as string;\n\n const internalMatches: number[] = [];\n let result: RegExpExecArray;\n\n while ((result = regex.exec(cueText)))\n internalMatches.push(result.index);\n\n if (internalMatches.length)\n matches[i] = internalMatches;\n }\n\n return matches;\n }\n\n private toggleItemVisibility(text: string, matches: Matches): void {\n const items = this.menu.children_.slice(1, this.menu.children_.length - 1);\n items.forEach((c, index) => {\n if (!text || matches[index])\n c.show();\n else\n c.hide();\n\n (c as any).update(matches[index], text.length);\n });\n }\n\n private toggleNoResults(text: string, matches: Matches): void {\n const noResults = this.menu.children_[this.menu.children_.length - 1];\n if (!text || Object.keys(matches).length)\n noResults.hide();\n else\n noResults.show();\n }\n\n public buildWrapperCSSClass(): string {\n return `cv-menu-big cv-subtitle-search-button ${super.buildWrapperCSSClass()}`;\n }\n\n public update(): void {\n super.update();\n this.player_.trigger('resizemenus');\n }\n\n public pressButton(): void {\n super.pressButton();\n\n const firstChild = this.menu.children_[0];\n firstChild?.focus && firstChild?.focus();\n }\n\n /**\n * CollapsibileComponent interface implementation\n * from here onward\n */\n public alwaysCollapsed: boolean = true;\n public isCollapsed: boolean = false;\n public isCollabsible: boolean = true;\n \n public getCollabsibleName(): string {\n return 'Subtitle Size';\n }\n \n public getCollabsibleValue(): string {\n return '';\n }\n \n public showInCollabsibleMenu(): boolean {\n return false;\n }\n \n public showCollapsibleMenu(): void {\n MenuButton.prototype.handleClick.apply(this);\n }\n}\n\nvideojs.registerComponent('subtitleSearchButton', SubtitleSearchButton);","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { CollapsibleComponent } from 'projects/player/interfaces/CollapsibleComponent';\n\nimport { CollapsibleHeadingMenuItem } from '../cog-button/collapsible-heading-menu-item';\n\nimport './keyboard-shortcuts-button.scss';\n\nconst MenuItem = videojs.getComponent('MenuItem');\nconst MenuButton = videojs.getComponent('MenuButton') as unknown as typeof videojs.MenuButton;\n\nconst shortcuts: any[] = [\n {\n label: 'Play / Pause',\n type: 'play-pause'\n },\n {\n label: 'Volume',\n type: 'volume'\n },\n {\n label: 'Mute',\n type: 'mute'\n },\n {\n label: 'Toggle fullscreen',\n type: 'fullscreen'\n },\n {\n label: 'Exit fullscreen',\n type: 'exit-fullscreen'\n },\n {\n label: 'Toggle theatre mode',\n type: 'theatre-mode'\n }\n];\n\n\ninterface KeyboardShortcutMenuItemOptions extends videojs.MenuItemOptions {\n label: string;\n type: string;\n}\n\nclass KeyboardShortcutMenuItem extends MenuItem {\n public options_: KeyboardShortcutMenuItemOptions;\n\n constructor(player: VideoJsPlayer, options: KeyboardShortcutMenuItemOptions) {\n super(player, options);\n }\n\n public createEl(): HTMLLIElement {\n return videojs.dom.createEl('li', {\n className: 'vjs-menu-item',\n tabIndex: -1,\n innerHTML: `\n <span class=\"vjs-menu-item-text\">${this.options_.label}</span>\n <span>${this.getDisplayHtml(this.options_.type)}\n `\n }) as HTMLLIElement;\n }\n\n public getDisplayHtml(type: string): string {\n switch (type) {\n case 'play-pause':\n return `<span class=\"cv-keyboard-button\">Spacebar</span>`;\n\n case 'volume':\n return `<span class=\"cv-keyboard-button\">Shift</span> + \n <span class=\"cv-keyboard-button cv-single-key\">⇑</span> / \n <span class=\"cv-keyboard-button\">Shift</span> +\n <span class=\"cv-keyboard-button cv-single-key\">⇓</span>`;\n\n case 'mute':\n return `<span class=\"cv-keyboard-button cv-single-key\">m</span>`;\n\n case 'fullscreen':\n return `<span class=\"cv-keyboard-button cv-single-key\">f</span>`;\n\n case 'exit-fullscreen':\n return `<span class=\"cv-keyboard-button cv-single-key\">esc</span>`;\n\n case 'theatre-mode':\n return `<span class=\"cv-keyboard-button cv-single-key\">t</span>`;\n }\n return '';\n }\n}\n\nclass KeyboardShortcutsButton extends MenuButton implements CollapsibleComponent {\n public createItems(): KeyboardShortcutMenuItem[] {\n const items: KeyboardShortcutMenuItem[] = [];\n\n items.push(new CollapsibleHeadingMenuItem(this.player_, {\n label: 'Keyboard Shortcuts'\n }) as any);\n\n shortcuts.forEach(s => {\n items.push(new KeyboardShortcutMenuItem(this.player_, s));\n });\n\n return items;\n }\n\n public buildWrapperCSSClass(): string {\n return `cv-menu-small cv-keyboard-shortcuts ${super.buildWrapperCSSClass()}`;\n }\n\n /**\n * CollapsibileComponent interface implementation\n * from here onward\n */\n public alwaysCollapsed: boolean = true;\n public isCollapsed: boolean = false;\n public isCollabsible: boolean = true;\n \n public getCollabsibleName(): string {\n return 'Keyboard Shortcuts';\n }\n \n public getCollabsibleValue(): string {\n return '';\n }\n \n public showInCollabsibleMenu(): boolean {\n return !this.player_.options_.mobile;\n }\n \n public showCollapsibleMenu(): void {\n MenuButton.prototype.handleClick.apply(this);\n }\n}\n\nvideojs.registerComponent('KeyboardShortcutsButton', KeyboardShortcutsButton);","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { CogButton } from 'projects/player/components/cog-button/cog-button';\nimport { CollapsibleComponent } from 'projects/player/interfaces/CollapsibleComponent';\n\nimport './collapserator.scss';\nimport '../fullscreen-toggle/fullscreen-toggle.scss';\n\nimport 'projects/player/components/cog-button/cog-button';\nimport 'projects/player/components/subtitle-size-button/subtitle-size-button';\nimport 'projects/player/components/subtitle-search-button/subtitle-search-button';\nimport 'projects/player/components/keyboard-shortcuts-button/keyboard-shortcuts-button';\n\nconst COMPACT_LENGTH = 600;\nconst COMPACT_LENGTH_LG = 1200;\nconst COLLAPSED_CLASS = 'cv-collapsed';\n\nconst Component = videojs.getComponent('Component');\n\nclass Collapserator extends Component {\n // eslint-disable-next-line\n public options_: videojs.ComponentOptions;\n\n constructor(player: VideoJsPlayer, options: videojs.ComponentOptions) {\n super(player, options);\n\n this.addChild('cogButton', {\n items: this.children_\n }, this.children_.length - 1);\n\n /**\n * no need to throttle or debounce update\n * because the playerresize event is\n * already debounced\n */\n this.update = this.update.bind(this);\n\n this.player_.on('cv-updatecog', this.update);\n this.player_.on('playerresize', this.update);\n /**\n * We need to hide menus on first play for the defer menu plugin.\n * Otherwise menu items will show when they're not supposed to.\n */\n this.player_.one('play', this.update);\n\n this.player_.on('dispose', () => {\n this.player_.off('cv-updatecog', this.update);\n this.player_.off('playerresize', this.update);\n this.player_.off('play', this.update);\n });\n }\n\n private toggleHidden(hide: boolean): void {\n for (let i = 0; i < this.children_.length; i++) {\n const item = this.children_[i] as CollapsibleComponent;\n\n if (!item.isCollabsible) continue;\n\n if (item.alwaysCollapsed) {\n item.isCollapsed = true;\n item.addClass(COLLAPSED_CLASS);\n continue;\n }\n\n if (hide) {\n item.isCollapsed = true;\n item.addClass(COLLAPSED_CLASS);\n } else {\n item.isCollapsed = false;\n item.removeClass(COLLAPSED_CLASS);\n }\n }\n (this.getChild('cogButton') as CogButton).update();\n }\n\n public update(): void {\n const isFullscreen = this.player_.isFullscreen();\n \n const side = this.player_.whiteboardModePlugin().side;\n \n const playerRect = this.player_.el().getBoundingClientRect();\n\n const comparisonEdge = isFullscreen && (side === 'left' || side === 'right') ?\n playerRect.height :\n playerRect.width;\n\n /**\n * In case our update function runs before our\n * player has properly rendered within the DOM\n */\n if (!comparisonEdge)\n return;\n\n /**\n * Once the player has been properly rendered within the DOM,\n * we add this class for any custom styling that may be desired.\n * \n * e.g. reports-player makes the collapserator visible before playback\n * has started but it waits for the class to be added before doing so.\n */\n this.addClass('cv-collapsorator-ready');\n\n const collapsedThreshold = isFullscreen && (side === 'left' || side === 'right' || side === 'top') ?\n COMPACT_LENGTH_LG :\n COMPACT_LENGTH;\n \n let hide = comparisonEdge < collapsedThreshold;\n\n if (this.player_.options_.deferMenus)\n hide = true;\n\n this.toggleHidden(hide);\n }\n\n public buildCSSClass(): string {\n return `cv-collapsorator ${super.buildCSSClass()}`;\n }\n\n public createEl(tagName?: string, properties?: any, attributes?: any): Element {\n return super.createEl(tagName, {\n ...properties,\n className: this.buildCSSClass()\n }, attributes);\n }\n}\n\nvideojs.registerComponent('collapserator', Collapserator);\n\nexport const COLLAPSERATOR_CHILDREN = [\n 'playToggle',\n 'volumePanel',\n 'customControlSpacer',\n 'playbackRateMenuButton',\n 'chaptersButton',\n 'qualityButton',\n 'keyboardShortcutsButton',\n 'subsCapsButton',\n 'whiteboardModeButton',\n 'subtitleSizeButton',\n 'subtitleSearchButton',\n 'fullscreenToggle'\n];","import { LocalStorageHelper } from 'libs/common/backbone/utils/LocalStorageHelper';\n\nimport { CollectionApiClient } from 'libs/analytics/clients/CollectionApiClient';\nimport { RegionName } from 'libs/analytics/enums/RegionName';\nimport { ActionContext, AnalyticsOptions, AnalyticsUser, EntityType, EventVersion, HashObject, LocationContext, PlayerDescriptor, RegionalUrl, UserAction } from 'libs/analytics/interfaces';\nimport { CollectionApiClientHelper } from 'libs/analytics/utils/CollectionApiClientHelper';\n\nimport { ProgressEventPair } from 'projects/player/plugins/progress-reporter-plugin/interfaces/ProgressEvent';\n\nexport type AnalyticsPlayerType = 'player' | 'interactive-player' | 'create-clip-player' | 'reports-player';\n\ninterface AnalyticsServiceOptions {\n collectionApiUrls: RegionalUrl;\n collectionApiClientId: string;\n productVersion: string;\n regionName: RegionName;\n videoId: string;\n mediaId: string;\n userId: string;\n shareId?: string;\n customerId: string;\n mediaType: 'MasterVideo' | 'MasterClip' | 'MasterInteractive';\n playerType: AnalyticsPlayerType;\n isEmbedded: boolean;\n isUsingLocalCache: boolean;\n additionalAnalyticsData?: HashObject;\n}\n\nexport class AnalyticsService {\n private options: AnalyticsServiceOptions;\n private collectionApiClient: CollectionApiClient;\n\n public constructor(options: AnalyticsServiceOptions) {\n this.options = options;\n this.initialize();\n }\n\n public logStream(): void {\n const cacheKey = `v:${this.options.videoId}`;\n\n // See LocalStorageHelper.cacheSet below\n if (LocalStorageHelper.cacheExists(cacheKey))\n return;\n \n this.collectionApiClient.log({\n type: UserAction.WebPlayerStream,\n actionContext: this.getActionContext(),\n data: this.getAnalyticsData(),\n eventVersion: EventVersion.V3\n });\n\n // Only record one view per 5 minutes.\n if (LocalStorageHelper)\n LocalStorageHelper.cacheSet(cacheKey, null, 300);\n }\n\n public logVideoProgress(events: ProgressEventPair[]): void {\n const data = this.getAnalyticsData();\n\n this.collectionApiClient.log(events.map(ev => {\n return {\n type: UserAction.StreamProgress,\n actionContext: this.getActionContext(),\n data: {\n ...data,\n progress: ev\n },\n eventVersion: EventVersion.V2\n };\n }));\n }\n\n public logUserAction(analyticsData: HashObject | HashObject[], analyticsOptions: AnalyticsOptions): void {\n const data = {\n ...this.getAnalyticsData(),\n ...analyticsData\n };\n\n const actionContext = {\n ...this.getActionContext(),\n ...analyticsOptions\n };\n\n this.collectionApiClient.log({\n type: analyticsOptions.actionType,\n data,\n actionContext,\n eventVersion: analyticsOptions.eventVersion || EventVersion.V2\n });\n }\n\n private getAnalyticsData(): HashObject {\n const data: HashObject = {\n video: {\n id: this.options.videoId\n },\n flags: {\n isUsingLocalCache: this.options.isUsingLocalCache\n },\n ...(this.options.additionalAnalyticsData || {})\n };\n\n if (this.options.shareId)\n data.video.shareId = this.options.shareId;\n\n const entityType = this.getEntityType();\n if (entityType === EntityType.Interactive)\n data.interactive = { id: +this.options.mediaId };\n else if (entityType === EntityType.Clip)\n data.clip = { id: +this.options.mediaId };\n\n return data;\n }\n \n private initialize(): void {\n this.setupCollectionApiClient();\n }\n\n private setupCollectionApiClient(): void {\n this.collectionApiClient = new CollectionApiClient({\n productName: 'player.web',\n productVersion: this.options.productVersion,\n regionName: this.options.regionName,\n collectionApiUrls: this.options.collectionApiUrls,\n collectionApiClientId: this.options.collectionApiClientId,\n getUser: () => this.getCurrentUser(),\n shouldLog: CollectionApiClientHelper.shouldLog,\n formatData: CollectionApiClientHelper.formatData\n });\n }\n\n /**\n * We are intentionally logging the bare minimum user properties here to keep this lightweight.\n */\n private async getCurrentUser(): Promise<AnalyticsUser> {\n return {\n id: this.options.userId,\n customerId: this.options.customerId\n };\n }\n\n private getActionContext(): ActionContext {\n return {\n entity: this.getEntityType(),\n location: this.getLocationContext(),\n productArea: undefined,\n descriptor: this.options.isEmbedded ? PlayerDescriptor.Embedded : undefined,\n workflowPhase: undefined\n };\n }\n\n private getEntityType(): EntityType {\n switch (this.options.mediaType) {\n case 'MasterVideo':\n return EntityType.Video;\n\n case 'MasterInteractive':\n return EntityType.Interactive;\n\n case 'MasterClip':\n return EntityType.Clip;\n }\n }\n\n private getLocationContext(): LocationContext {\n switch (this.options.playerType) {\n case 'player':\n return LocationContext.Player;\n\n case 'interactive-player':\n return LocationContext.InteractivePlayer;\n\n case 'create-clip-player':\n return LocationContext.CreateClipPlayer;\n }\n }\n}","import keycode from 'keycode';\nimport { VideoJsPlayer } from 'video.js';\n\nimport { BasePlayerOptions } from 'projects/player/players/base-player';\n\nfunction handleFullscreenKey(player: VideoJsPlayer): void {\n // Copied from player in videojs\n if (!(document as any)[(player as any).fsApi_.fullscreenEnabled])\n return;\n\n if (!player.isFullscreen()) {\n player.requestFullscreen();\n } else {\n player.exitFullscreen();\n }\n}\n\nfunction handleTheatreModeKey(player: VideoJsPlayer): void {\n const isTheatreMode = player.theatreModePlugin().getTheatreMode();\n\n player.theatreModePlugin().toggleTheatreMode(!isTheatreMode);\n}\n\nfunction handleMuteKey(player: VideoJsPlayer): void {\n const vol = player.volume();\n const lastVolume = (player as any).lastVolume_();\n\n if (vol === 0) {\n const volumeToSet = lastVolume < 0.1 ? 0.1 : lastVolume;\n player.volume(volumeToSet);\n player.muted(false);\n } else {\n player.muted(!player.muted());\n }\n}\n\nfunction handlePlayPauseKey(player: VideoJsPlayer): void {\n if (player.paused()) {\n player.play();\n } else {\n player.pause();\n }\n}\n\nfunction handleSeekKey(player: VideoJsPlayer, step: number): void {\n player.currentTime(player.currentTime() + step);\n}\n\nfunction handleVolumeKey(player: VideoJsPlayer, step: number): void {\n player.volume(player.volume() + step);\n}\n\nfunction didEventOriginateFromPlayer(event: videojs.default.KeyboardEvent): boolean {\n const target = event.target as HTMLElement;\n\n return target.tagName.toLowerCase() === 'video' && target.className === 'vjs-tech';\n}\n\nconst KeycodeHandlers: { [key: string]: (player: VideoJsPlayer, event: videojs.default.KeyboardEvent) => void} = {\n ['f']: handleFullscreenKey,\n ['m']: handleMuteKey,\n ['k']: handlePlayPauseKey,\n ['space']: handlePlayPauseKey,\n ['t']: handleTheatreModeKey,\n ['left']: (player: VideoJsPlayer) => handleSeekKey(player, -5),\n ['right']: (player: VideoJsPlayer) => handleSeekKey(player, 5),\n ['j']: (player: VideoJsPlayer) => handleSeekKey(player, -10),\n ['l']: (player: VideoJsPlayer) => handleSeekKey(player, 10),\n ['up']: (player: VideoJsPlayer) => handleVolumeKey(player, 0.05),\n ['down']: (player: VideoJsPlayer) => handleVolumeKey(player, -0.05)\n};\n\n/**\n * handleHotKeys is to be used as userActions.hotkeys in VideoJsPlayerOptions.\n * `this` will be a reference to the player.\n */\nexport function handleHotKeys(\n event: videojs.default.KeyboardEvent,\n player: VideoJsPlayer,\n options: BasePlayerOptions\n): void {\n // Ignore shortcuts when any modifier keys are pressed. metaKey refers to the Mac command button. - Sha\n if (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey)\n return;\n\n const code = keycode(event);\n\n if (code === 'f' && !options.allowFullscreen)\n return;\n\n if (!KeycodeHandlers[code])\n return;\n\n KeycodeHandlers[code](player, event);\n\n /**\n * If we've just handled a keypress that originated from our player, we want to stop the event\n * from propagating to the rest of the page. This is because we're also adding keydown listeners\n * to the body to handle global shortcuts, and we don't want those to be re-triggered by \n * keydown events that originated from the player.\n */\n const eventOriginatedFromPlayer = didEventOriginateFromPlayer(event);\n\n /**\n * We want to prevent propagation and default behaviour for some keys, even if they originated \n * outside the player. Once such example is the space key, whose default behaviour will scroll\n * the whole page down and cause a janky experience.\n */\n const preventPropagationAndDefaultBehaviour = ['space'].includes(code);\n \n if (eventOriginatedFromPlayer || preventPropagationAndDefaultBehaviour) {\n event.preventDefault();\n event.stopPropagation();\n }\n}","export enum PlayerApiErrorType {\n /**\n * Video is comprised of multiple mp4 files. A relic from old ClickView Publisher days\n */\n PhysicallyChapteredVideo = 'physically-chaptered-video'\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\ninterface ConfiureMenuDimensionPluginOptions {\n mobile: boolean;\n seekBarName: string;\n overflowControls?: boolean;\n}\n\nconst PlayerMenuBreakpoints = {\n SMALL: 450,\n MEDIUM: 650\n};\n\nconst Plugin = videojs.getPlugin('plugin');\n\nclass ConfigureMenuDimensionsPlugin extends Plugin {\n private options: ConfiureMenuDimensionPluginOptions;\n\n constructor(player: VideoJsPlayer, options: ConfiureMenuDimensionPluginOptions) {\n super(player);\n\n this.options = options;\n this.configureMenuDimensions = this.configureMenuDimensions.bind(this);\n this.initialize();\n }\n\n private initialize(): void {\n this.player.ready(this.configureMenuDimensions);\n this.player.one('play', this.configureMenuDimensions);\n\n this.player.on('resize', this.configureMenuDimensions);\n this.player.on('fullscreenchange', this.configureMenuDimensions);\n this.player.on('resizemenus', this.configureMenuDimensions);\n this.player.on('ready', this.configureMenuDimensions);\n }\n\n public dispose(): void {\n this.player.off('resize', this.configureMenuDimensions);\n this.player.off('fullscreenchange', this.configureMenuDimensions);\n this.player.off('resizemenus', this.configureMenuDimensions);\n this.player.off('ready', this.configureMenuDimensions);\n\n super.dispose();\n }\n\n private configureMenuDimensions(): void {\n const resetVolumePanelToInline = (setVolumeInline: boolean) => {\n // Don't reset (or re-insert) the volumePanel when in mobile mode\n if (this.options.mobile)\n return;\n\n const collapserator = this.player.getChild('collapserator');\n const volumePanel = collapserator.getChild('volumePanel');\n const index = collapserator.children_.indexOf(volumePanel);\n\n collapserator.removeChild(volumePanel);\n collapserator.addChild('volumePanel', { inline: setVolumeInline }, index);\n\n // Cause the volume bar to read in the current volume after being re-initialized\n this.player.trigger('volumechange');\n };\n\n const isFullscreen = this.player.isFullscreen();\n\n if (isFullscreen && !this.options.mobile) {\n const side = this.player.whiteboardModePlugin().side;\n resetVolumePanelToInline(side !== 'top');\n \n if (side === 'left' || side === 'right' || side === 'top') {\n const playerWidth1 = this.player.currentWidth();\n const menuEls1 = this.player.el().querySelectorAll('.vjs-menu');\n\n menuEls1.forEach((el: HTMLElement) => {\n el.style.paddingTop = null;\n el.style.marginBottom = null;\n el.style.width = `calc(${playerWidth1}px - 4em)`;\n });\n\n return;\n }\n }\n\n if (!isFullscreen)\n resetVolumePanelToInline(true);\n\n const playerWidth = this.player.currentWidth();\n const playerHeight = this.player.currentHeight();\n const aspectRatio = playerHeight / playerWidth * 100;\n \n const controlBarEl: HTMLElement = this.player.el().querySelector('.cv-collapsorator');\n const menuEls = this.player.el().querySelectorAll('.vjs-menu');\n\n let controlBarHeight = controlBarEl && controlBarEl.offsetHeight;\n\n // If control bar isn't yet visible, wait for the play event\n if (!controlBarHeight) {\n this.player.one('play', this.configureMenuDimensions);\n return;\n }\n\n /**\n * This isn't permanent. This entire function needs to be refactored to\n * not need to constantly be updating the styles on each menu item.\n * At which point different seekbar heights can be factored in.\n */\n if (this.options.seekBarName === 'CreateClipSeekBar')\n controlBarHeight += 22;\n\n if (!menuEls || !menuEls.length)\n return;\n\n menuEls.forEach((el: HTMLElement) => {\n if (!isFullscreen && this.options.overflowControls)\n el.style.paddingTop = '80%';\n else\n el.style.paddingTop = `calc(${aspectRatio}% - ${controlBarHeight}px)`;\n\n el.style.marginBottom = `${controlBarHeight}px`;\n el.style.width = null;\n\n const menuContentEl: HTMLElement = el.querySelector('.vjs-menu-content');\n\n if (!menuContentEl)\n return;\n\n if (playerWidth <= PlayerMenuBreakpoints.SMALL)\n this.player.addClass('cv-player-small');\n else\n this.player.removeClass('cv-player-small');\n\n // /**\n // * Adjust max-width of menu content so that it takes up more width\n // * on smaller players.\n // */\n // if (playerWidth <= PlayerMenuBreakpoints.MEDIUM)\n // menuContentEl.style.maxWidth = '50%';\n\n // if (playerWidth <= PlayerMenuBreakpoints.SMALL)\n // menuContentEl.style.maxWidth = '75%';\n });\n }\n}\n\nvideojs.registerPlugin('configureMenuDimensionsPlugin', ConfigureMenuDimensionsPlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n configureMenuDimensionsPlugin(options: ConfiureMenuDimensionPluginOptions): ConfigureMenuDimensionsPlugin;\n }\n}\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { LocalStorageHelper } from 'projects/player/utils/local-storage-helper';\n\nconst Plugin = videojs.getPlugin('plugin');\n\n/* Local Storage keys */\nconst VOLUME = 'cvplayer-volume';\nconst MUTE = 'cvplayer-mute';\n\nclass PersistVolumePlugin extends Plugin {\n private enabled: boolean = true;\n\n constructor(player: VideoJsPlayer) {\n super(player);\n\n this.player.ready(() => this.initialize());\n }\n\n private initialize(): void {\n if (this.player.options_.mobile) {\n this.removeVolumeControl();\n return;\n }\n\n if (!LocalStorageHelper.hasLocalStorage())\n return;\n\n this.saveVolumeState = this.saveVolumeState.bind(this);\n\n this.player.on('volumechange', this.saveVolumeState);\n\n this.applyUserPreferences();\n }\n\n public applyUserPreferences(): void {\n const volume = LocalStorageHelper.get(VOLUME);\n const mute = LocalStorageHelper.get(MUTE);\n\n if (volume)\n this.player.volume(+volume);\n\n if (mute)\n this.player.muted(mute === 'true');\n }\n\n private saveVolumeState(): void {\n if (!this.enabled)\n return;\n\n LocalStorageHelper.set(VOLUME, this.player.volume().toString());\n LocalStorageHelper.set(MUTE, this.player.muted().toString());\n }\n\n private removeVolumeControl(): void {\n this.player.volume(1);\n const collapserator = this.player.getChild('collapserator');\n const volumePanel = collapserator.getChild('volumePanel');\n collapserator.removeChild(volumePanel);\n }\n\n /**\n * Enable and disable used to turn off persisting user preferences\n * while the player is in hover mode. See player-mode-plugin.ts\n */\n public enable(): void {\n this.enabled = true;\n }\n\n public disable(): void {\n this.enabled = false;\n }\n\n public dispose(): void {\n this.player.off('volumechange', this.saveVolumeState);\n\n super.dispose();\n }\n}\n\nvideojs.registerPlugin('persistVolumePlugin', PersistVolumePlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n persistVolumePlugin(): PersistVolumePlugin;\n }\n}\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { EntityType, EventVersion, PlaybackDescriptor, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { AnalyticsService } from 'projects/player/services/analytics-service';\nimport { LocalStorageHelper } from 'projects/player/utils/local-storage-helper';\n\nconst Plugin = videojs.getPlugin('plugin');\n\n/* Local Storage key */\nconst PLAYBACK_RATE = 'cvplayer-playback-rate';\n\ninterface PersistPlaybackRatePluginOptions {\n analyticsService?: AnalyticsService;\n}\n\nclass PersistPlaybackRatePlugin extends Plugin {\n private options: PersistPlaybackRatePluginOptions;\n\n constructor(player: VideoJsPlayer, options: PersistPlaybackRatePluginOptions) {\n super(player);\n\n this.options = options;\n\n this.player.dataLoaded(() => this.initialize());\n }\n\n private initialize(): void {\n if (!LocalStorageHelper.hasLocalStorage())\n return;\n\n this.savePlaybackRate = this.savePlaybackRate.bind(this);\n\n this.player.on('ratechange', this.savePlaybackRate);\n this.one('dispose', () => {\n this.player.off('ratechange', this.savePlaybackRate);\n });\n\n // NOTE: We're immediately casting the value to a number\n const playbackRate = +LocalStorageHelper.get(PLAYBACK_RATE);\n\n /**\n * Ensure that the playback rate in local storage is one we offer\n * in our player's options\n */\n const isValid = this.player.options_.playbackRates?.some(v => v === playbackRate);\n\n if (isValid)\n this.player.playbackRate(playbackRate);\n }\n\n private savePlaybackRate(): void {\n const rate = this.player.playbackRate().toString();\n\n LocalStorageHelper.set(PLAYBACK_RATE, rate);\n\n this.options.analyticsService?.logUserAction({ rate }, {\n actionType: UserAction.Select,\n workflowPhase: WorkflowPhase.Complete,\n descriptor: PlaybackDescriptor.ChangeSpeed,\n entity: EntityType.PlaybackSpeed,\n eventVersion: EventVersion.V3\n });\n }\n}\n\nvideojs.registerPlugin('persistPlaybackRatePlugin', PersistPlaybackRatePlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n persistPlaybackRatePlugin(options: PersistPlaybackRatePluginOptions): PersistPlaybackRatePlugin;\n }\n}\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nconst Plugin = videojs.getPlugin('plugin');\n\nclass FullscreenOnRotatePlugin extends Plugin {\n private fullscreenBecauseOfRotate: boolean = false;\n\n constructor(player: VideoJsPlayer) {\n super(player);\n\n /**\n * Likewise if the browser doesn't support fullscreen\n * don't do anything\n */\n if (!this.player.supportsFullScreen())\n return;\n\n this.onRotate = this.onRotate.bind(this);\n this.onFullscreenChange = this.onFullscreenChange.bind(this);\n\n this.player.ready(() => this.initialize());\n }\n\n private initialize(): void {\n this.player.on('fullscreenchange', this.onFullscreenChange);\n window.addEventListener('orientationchange', this.onRotate);\n }\n\n public dispose(): void {\n this.player.off('fullscreenchange', this.onFullscreenChange);\n window.removeEventListener('orientationchange', this.onRotate);\n }\n\n public onFullscreenChange(): void {\n if (!this.player.isFullscreen())\n this.fullscreenBecauseOfRotate = false;\n }\n\n private onRotate(): void {\n const angle = this.getAngle();\n\n /**\n * Landscape angles\n */\n if (angle !== 90 && angle !== -90 && angle !== 270) {\n if (this.fullscreenBecauseOfRotate && this.player.isFullscreen())\n this.player.exitFullscreen();\n return;\n }\n\n this.player.requestFullscreen();\n this.fullscreenBecauseOfRotate = true;\n }\n\n private getAngle(): number {\n if (typeof window.screen?.orientation?.angle === 'number')\n return window.screen.orientation.angle;\n\n return 0;\n }\n}\n\nvideojs.registerPlugin('fullscreenOnRotatePlugin', FullscreenOnRotatePlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n fullscreenOnRotatePlugin(): FullscreenOnRotatePlugin;\n }\n}","export const ClickViewLogo = `\n <svg viewBox='0 0 434 71'>\n <g>\n <path fill='#FFFFFF' d='M114.44 56.57l3.5 3.5a32.87 32.87 0 0 1-25.16 11.26c-19.63 0-33.62-15.54-33.62-35.16C59.16 16.55 73.16 1 92.78 1a32.31 32.31 0 0 1 24.19 10.4l-3.6 3.3a27.32 27.32 0 0 0-20.59-8.74c-16.91 0-28.39 13.5-28.39 30.21s11.48 30.21 28.39 30.21a28.08 28.08 0 0 0 21.66-9.81zM126.64 1h4.55v70.22h-4.73L126.64 1zm17.3 10.6a3.7 3.7 0 1 1 0 7.4 3.7 3.7 0 0 1 0-7.4zm-2.41 15.07h4.81v44.56h-4.81V26.67zm48 33.15l3.33 3.15a21.8 21.8 0 0 1-17.31 8.61c-12.59 0-21.76-10-21.76-22.22 0-12.22 9.17-22.22 21.76-22.22a21.84 21.84 0 0 1 16.85 8l-3.43 3.06a17.15 17.15 0 0 0-13.42-6.3c-10.09 0-16.76 8.15-16.76 17.5s6.67 17.5 16.76 17.5a17.38 17.38 0 0 0 13.98-7.08zm14.99-9.33v20.74h-4.73V1.01h4.73v47.75l20.74-19.02h6.64l-21.56 19.84L234 71.23h-7.01l-22.47-20.74z'/>\n <path fill='#F8981D' d='M304.09 19.4a5.56 5.56 0 1 1 0-11.12 5.56 5.56 0 0 1 0 11.12zm-5.56 7.27h11.11v44.56h-11.11V26.67zm61.42 22.15c0 .81 0 2.42-.09 4h-31.75c.8 3.77 5.2 8.61 11.93 8.61a17.11 17.11 0 0 0 11.66-4.31l5.38 8.16a27.23 27.23 0 0 1-17 6.1c-12.92 0-22.88-9.87-22.88-22.34s9.06-22.33 21.35-22.33c11.62-.04 21.4 9.02 21.4 22.11zm-10.77-3.76c-.18-3.68-3.58-8.62-10.67-8.62-6.91 0-10.05 4.85-10.4 8.62h21.07zM385.92 71h-6.42l-19.64-44.37h13.97l9.16 23.98 9.72-23.98h8.31l9.63 23.98 9.16-23.98h13.97L414.24 71h-6.52l-10.85-23.7L385.92 71zm-120.22.35h-6L226.11 1.01h17.01l19.42 44.18 18.08-44.18h16.91L265.7 71.35zM0 1l41 35L0 71V1z'/>\n </g>\n </svg>\n`;","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { ClickViewLogo } from 'projects/player/components/logo/clickview-logo';\nimport { ExternalLinkOptions } from 'projects/player/plugins/open-externally-plugin/interfaces/ExternalLinkOptions';\nimport { throttle } from 'projects/player/utils/fn';\n\nimport './open-externally-button.scss';\n\nconst Button = videojs.getComponent('Button');\n\ninterface OpenExternallyButtonOptions extends videojs.ComponentOptions {\n getExternalLink: (options: ExternalLinkOptions) => string;\n}\n\nclass OpenExternallyButton extends Button {\n // eslint-disable-next-line\n private el_: HTMLButtonElement;\n // eslint-disable-next-line\n public options_: OpenExternallyButtonOptions;\n // eslint-disable-next-line\n public controlText_: string;\n\n constructor(player: VideoJsPlayer, options: videojs.ComponentOptions) {\n super(player, options);\n\n this.update = throttle(this.update.bind(this), 1000);\n\n player.on('timeupdate', this.update);\n\n player.one('dispose', () => {\n player.off('timeupdate', this.update);\n this.el_.removeEventListener('click', this.pause);\n });\n }\n\n public update(): void {\n const currentTime = this.player_.currentTime();\n (this.el_ as any).href = this.options_.getExternalLink({\n currentTime: Math.round(currentTime)\n });\n }\n\n public buildCSSClass(): string {\n return 'cv-open-externally-button';\n }\n\n public createEl(): HTMLButtonElement {\n const tag = 'a';\n\n const props = {\n innerHTML: ClickViewLogo,\n className: this.buildCSSClass()\n };\n\n const attributes = {\n type: 'button',\n href: this.options_.getExternalLink({ currentTime: 0 }),\n target: '_blank'\n };\n\n const el = videojs.dom.createEl(tag, props, attributes) as HTMLButtonElement;\n\n this.createControlTextEl(el);\n\n el.addEventListener('click', this.pause.bind(this));\n\n return el;\n }\n\n private pause(): void {\n this.player_.pause();\n }\n}\n\nOpenExternallyButton.prototype.controlText_ = 'Open in ClickView';\n\nvideojs.registerComponent('OpenExternallyButton', OpenExternallyButton);\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { ExternalLinkOptions } from 'projects/player/plugins/open-externally-plugin/interfaces/ExternalLinkOptions';\n\nimport 'projects/player/plugins/open-externally-plugin/components/open-externally-button';\n\nconst Plugin = videojs.getPlugin('plugin');\n\ninterface OpenExternallyPluginOptions {\n getExternalLink: (options: ExternalLinkOptions) => string;\n}\n\nclass OpenExternallyPlugin extends Plugin {\n private options: OpenExternallyPluginOptions;\n\n constructor(player: VideoJsPlayer, options: OpenExternallyPluginOptions) {\n super(player, options);\n\n this.options = options;\n\n player.ready(() => this.onReady());\n }\n\n private onReady(): void {\n const collapserator = this.player.getChild('collapserator');\n const spacer = collapserator.getChild('customControlSpacer');\n const index = collapserator.children_.indexOf(spacer);\n \n collapserator.addChild('OpenExternallyButton', {\n getExternalLink: this.options.getExternalLink\n }, index + 1);\n }\n}\n\nvideojs.registerPlugin('openExternallyPlugin', OpenExternallyPlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n openExternallyPlugin(oprions: OpenExternallyPluginOptions): OpenExternallyPlugin;\n }\n}\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport './touch-controls.scss';\n\nconst Component = videojs.getComponent('component');\n\nexport class TouchControls extends Component {\n // tslint:disable-next-line\n private el_: HTMLDivElement;\n private timeoutId: number;\n\n constructor(player: VideoJsPlayer, options?: videojs.ComponentOptions) {\n super(player, options);\n }\n\n public buildCSSClass(): string {\n return `cv-touch-control-ui ${super.buildCSSClass()}`;\n }\n\n public createEl(tagName?: string, properties?: any, attributes?: any): Element {\n return super.createEl(tagName, {\n ...properties,\n className: this.buildCSSClass()\n }, attributes);\n }\n\n public setUi(amount: number, timeout: number): void {\n const isPositive = amount > 0;\n const className = isPositive ? 'cv-touch-right' : 'cv-touch-left';\n this.el_.className = this.buildCSSClass() + ' cv-ui-touch-active';\n this.el_.innerHTML = `\n <div class='${className}'>\n <div class='cv-touch-text'>\n ${isPositive ? '+' : ''}${amount * 10}s\n </div>\n </div>\n `;\n\n window.clearTimeout(this.timeoutId);\n this.timeoutId = window.setTimeout(() => {\n this.removeText();\n }, timeout);\n }\n\n public removeText(): void {\n this.el_.className = this.buildCSSClass();\n this.el_.innerHTML = '';\n }\n}\n\nvideojs.registerComponent('TouchControls', TouchControls);\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { TouchControls } from './components/touch-controls/touch-controls';\n\nimport './components/touch-controls/touch-controls';\n\nconst Plugin = videojs.getPlugin('plugin');\n\nconst TIMEOUT = 300;\n\nclass TouchControlsPlugin extends Plugin {\n private tech: videojs.Tech;\n\n private touchControls: TouchControls;\n\n private touchStartTime: number;\n private lastTouchTime: number;\n private doubleTouchCount: number = 0;\n private seekStartTime: number = 0;\n private directionModifier: number = 0;\n private userActive: boolean;\n\n constructor(player: VideoJsPlayer) {\n super(player);\n\n this.bindFunctions();\n this.player.ready(() => this.initialize()) ;\n }\n\n private bindFunctions(): void {\n this.onTouchStart = this.onTouchStart.bind(this);\n this.onTouchEnd = this.onTouchEnd.bind(this);\n this.reBindEventListeners = this.reBindEventListeners.bind(this);\n this.unBindEventListeners = this.unBindEventListeners.bind(this);\n }\n\n private initialize(): void {\n this.player.addChild('TouchControls');\n this.touchControls = this.player.getChild('TouchControls') as TouchControls;\n\n /**\n * Ready is fired on the player when the tech is changed\n * so we rebind listeners then\n */\n this.player.on('ready', this.reBindEventListeners);\n this.one('dispose', () => {\n this.player.off('ready', this.reBindEventListeners);\n });\n\n this.reBindEventListeners();\n }\n\n private reBindEventListeners(): void {\n this.unBindEventListeners();\n\n this.tech = this.player.tech(true);\n\n if (this.tech.name() !== 'Html5')\n return;\n \n this.tech.on('touchstart', this.onTouchStart);\n this.tech.on('touchend', this.onTouchEnd);\n }\n\n private unBindEventListeners(): void {\n if (!this.tech)\n return;\n\n if (this.tech.name() !== 'Html5')\n return;\n\n this.tech.off('touchstart', this.onTouchStart);\n this.tech.off('touchend', this.onTouchEnd);\n }\n\n public dispose(): void {\n super.dispose();\n this.unBindEventListeners();\n }\n\n private onTouchStart(event: TouchEvent): void {\n this.touchStartTime = event.timeStamp;\n this.userActive = this.player.userActive();\n }\n\n private onTouchEnd(event: TouchEvent): void {\n /**\n * Ignore multi finger touches\n */\n if (!event.changedTouches.length)\n return;\n\n /**\n * If the last touch was within our threshold\n * we know it's a double touch\n */\n if ((event.timeStamp - this.lastTouchTime) < TIMEOUT) {\n this.onDoubleTouch(event);\n this.lastTouchTime = event.timeStamp;\n return;\n }\n\n /**\n * Hasn't been a double touch in TIMEOUT time\n * so we reset our counts\n */\n this.resetProperties();\n\n this.lastTouchTime = event.timeStamp;\n\n /**\n * On the first tap we set a timeout to play/pause\n * for a single tap. If we don't receive a second tap\n * within the timeout, then we toggle play/pause\n */\n if ((event.timeStamp - this.touchStartTime) < TIMEOUT) {\n window.setTimeout(() => {\n if (this.doubleTouchCount)\n return;\n\n if (this.player.paused()) {\n this.player.play();\n } else if (this.userActive) {\n this.player.pause();\n }\n }, TIMEOUT);\n return;\n }\n }\n\n private resetProperties(): void {\n this.doubleTouchCount = 0;\n this.seekStartTime = 0;\n this.directionModifier = 0;\n }\n\n private onDoubleTouch(event: TouchEvent): void {\n const rect = this.player.el().getBoundingClientRect();\n const middle = rect.left + (rect.width / 2);\n\n if (this.doubleTouchCount === 0) {\n this.seekStartTime = this.player.currentTime();\n\n /**\n * The direction is set on the first tap and the location\n * of subsequent tabs are ignored\n */\n if (event.changedTouches[0].pageX < middle) {\n this.directionModifier = -1;\n } else {\n this.directionModifier = 1;\n }\n }\n\n this.doubleTouchCount++;\n\n /**\n * Going backwards\n */\n if (this.directionModifier < 0) {\n /**\n * Can't seek past the start of the video;\n */\n if (this.doubleTouchCount * 10 > (this.seekStartTime + 10))\n return;\n\n this.touchControls.setUi(-this.doubleTouchCount, TIMEOUT * 3);\n this.player.currentTime(this.player.currentTime() - 10);\n return;\n }\n\n /**\n * Going forwards\n */\n\n const remainingTime = this.player.duration() - this.seekStartTime;\n\n /**\n * Can't seek past the end of the video\n */\n if (this.doubleTouchCount * 10 > (remainingTime + 10))\n return;\n\n this.touchControls.setUi(this.doubleTouchCount, TIMEOUT * 3);\n this.player.currentTime(this.player.currentTime() + 10);\n }\n}\n\nvideojs.registerPlugin('touchControls', TouchControlsPlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n touchControls(): TouchControlsPlugin;\n }\n}","import { Representation } from 'videojs-contrib-quality-levels';\n\nimport { Source } from 'projects/player/plugins/progressive-files-plugin/interfaces/Source';\nimport { ProgressiveFilesPlugin } from 'projects/player/plugins/progressive-files-plugin/progressive-files-plugin';\n\nexport class ProgressiveRepresentation implements Representation {\n public id: string;\n private plugin: ProgressiveFilesPlugin;\n private source: Source;\n\n constructor(plugin: ProgressiveFilesPlugin, source: Source) {\n this.id = source.id;\n this.plugin = plugin;\n this.source = source;\n\n this.enabled = this.enabled.bind(this);\n }\n\n public enabled(enabled: boolean): boolean {\n if (enabled === undefined)\n return this.plugin.currentSource === this.source;\n\n if (enabled)\n this.plugin.setSource(this.source.id);\n\n /**\n * note, this function will not unset a source if false is provided.\n * this is because setting source to null causes the browser to throw an error saying the source is not known.\n */\n return enabled;\n }\n}\n","import videojs, { VideoJsPlayer } from 'video.js';\nimport { QualityLevelList } from 'videojs-contrib-quality-levels';\n\nimport { Source } from 'projects/player/plugins/progressive-files-plugin/interfaces/Source';\nimport { ProgressiveFilesPluginOptions } from 'projects/player/plugins/progressive-files-plugin/ProgressiveFilesPluginOptions';\nimport { ProgressiveRepresentation } from 'projects/player/plugins/progressive-files-plugin/ProgressiveRepresentation';\n\nconst Plugin = videojs.getPlugin('plugin');\n\nexport class ProgressiveFilesPlugin extends Plugin {\n private sources: Source[];\n private _currentSource: Source;\n private qualityLevels: QualityLevelList;\n private options_: ProgressiveFilesPluginOptions;\n\n constructor(player: VideoJsPlayer, options: ProgressiveFilesPluginOptions) {\n super(player);\n\n this.options_ = options;\n this.player.ready(() => this.initialize());\n }\n\n private initialize(): void {\n this.sources = [];\n this.qualityLevels = this.player.qualityLevels();\n this.populateSources(this.options_.sources);\n\n this.onQualityChange = this.onQualityChange.bind(this);\n this.qualityLevels.on('change', this.onQualityChange);\n this.player.one('dispose', () => {\n this.qualityLevels.off('change', this.onQualityChange);\n });\n }\n\n public get currentSource(): Source {\n return this._currentSource;\n }\n\n private onQualityChange(): void {\n const currentQuality = this.qualityLevels[this.qualityLevels.selectedIndex];\n this.player.trigger('cv-quality-change', currentQuality.id);\n }\n\n /**\n * Sets the current player source. If the id cannot be found, the current source is returned\n * @param id the id of the source to set\n */\n public setSource(id: string): Source {\n const source = this.getSourceById(id);\n\n if (source === null)\n return this.currentSource;\n\n const currentTime = this.player.currentTime();\n const isPlaying = !this.player.paused();\n\n this._currentSource = source;\n const playbackRate = this.player.playbackRate();\n\n const hasStarted = this.player.hasStarted();\n\n // change the source\n this.player.src({\n src: source.url,\n type: source.mimeType\n });\n \n const onLoadedMetadata = () => {\n // Set the playback rate to what it was before we changed the src\n this.player.playbackRate(playbackRate);\n\n // check that our current time has not been set yet\n if (this.player.currentTime() !== currentTime) {\n this.player.currentTime(currentTime);\n }\n\n // continue playing if we were already playing\n if (isPlaying)\n this.player.play();\n\n // Ensure the controls do not stay hidden\n if (hasStarted)\n this.player.hasStarted(true);\n };\n\n // seek to the previous time\n // we need to this only once the metadata has been loaded\n this.player.one('loadedmetadata', onLoadedMetadata);\n\n this.trigger({ event: 'sourcechange', source });\n this.sourceChangeUpdateQualityLevels(source);\n\n return source;\n }\n\n public getSourceById(id: string): Source {\n return this.sources.find(source => source.id === id);\n }\n\n public repopulateSources(sources: Source[]): void {\n let currentQuality: string = null;\n\n // Clear our qualities and sources while saving the selected quality\n while (this.qualityLevels.length) {\n if (this.qualityLevels[0].enabled)\n currentQuality = this.qualityLevels[0].id;\n\n this.qualityLevels.removeQualityLevel(this.qualityLevels[0]);\n }\n this.sources = [];\n\n this.populateSources(sources, currentQuality);\n }\n\n private sortSources(sources: Source[]): Source[] {\n return sources.sort((a, b) => {\n if (a.id === b.id)\n return 0;\n\n if (+a.id > +b.id)\n return -1;\n return 1;\n });\n }\n\n private populateSources(sources: Source[], selectSourceId: string = null): void {\n let currentSource: Source = null;\n\n sources = this.sortSources(sources);\n\n sources.forEach(source => {\n this.qualityLevels.addQualityLevel(new ProgressiveRepresentation(this, source));\n this.sources.push(source);\n this.trigger({ event: 'addsource', source });\n\n if (selectSourceId !== null) {\n if (source.id === selectSourceId)\n currentSource = source;\n\n return;\n }\n\n if (source.default)\n currentSource = source;\n });\n\n // the current source to the first if we have no default\n if (currentSource === null)\n currentSource = this.sources[0];\n\n if (currentSource !== null)\n this.setSource(currentSource.id);\n }\n\n private sourceChangeUpdateQualityLevels(source: Source): void {\n const qualityLevels = this.qualityLevels as any;\n let selectedIndex = -1;\n\n for (let i = 0; i < qualityLevels.length; i++) {\n if (qualityLevels[i].id === source.id) {\n selectedIndex = i;\n break;\n }\n }\n\n qualityLevels.selectedIndex_ = selectedIndex;\n qualityLevels.trigger({\n selectedIndex,\n type: 'change'\n });\n }\n}\n\nvideojs.registerPlugin('progressiveFiles', ProgressiveFilesPlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n progressiveFiles(options?: ProgressiveFilesPluginOptions): ProgressiveFilesPlugin;\n }\n}\n","import { QualityLevel, QualityLevelList } from 'videojs-contrib-quality-levels';\n\nexport class QualityHelper {\n /**\n * Returns a list of known profiles, ordered from best to worst\n */\n static getKnownProfiles(): string[] {\n return [\n '1080',\n '720',\n '480',\n '360',\n '240'\n ];\n }\n\n /**\n * Enables the provided profile, or the next best option\n * @param qualities\n * @param profile The profile which we want to select\n */\n static enableProfileOrNextBest(qualities: QualityLevelList, profile: string): QualityLevel | null {\n // check that the profile profile is in the list\n let quality = qualities.getQualityLevelById(profile);\n\n if (!quality) {\n // we don't have the profiled profile, so try and get the next best\n quality = this.getNextBestQuality(qualities, profile);\n }\n\n // no quality was found, so do nothing\n if (!quality)\n return null;\n\n // disable all qualities\n for (let i = 0; i < qualities.length; i++) {\n const q = qualities[i];\n\n // enable the selected quality, but disable all others\n q.enabled = quality.id === q.id;\n }\n\n return quality;\n }\n\n /**\n * Gets the next best quality for the given profile\n * @param qualities\n * @param profile\n */\n private static getNextBestQuality(qualities: QualityLevelList, profile: string): QualityLevel | null {\n const knownProfiles = this.getKnownProfiles();\n const index = knownProfiles.indexOf(profile);\n\n // iterate through the qualities to find the next best quality\n if (index >= 0) {\n // first try and find the next lowest quality\n for (let i = index + 1; i < knownProfiles.length; i++) {\n const p = knownProfiles[i];\n const quality = qualities.getQualityLevelById(p);\n\n if (quality) {\n return quality;\n }\n }\n\n // if we found nothing lower, try the next highest\n for (let i = index - 1; i > 0; i--) {\n const p = knownProfiles[i];\n const quality = qualities.getQualityLevelById(p);\n\n if (quality) {\n return quality;\n }\n }\n }\n\n return null;\n }\n}\n","import { LocalCacheAddress } from 'projects/player/interfaces/models/PlaybackObject';\n\nexport class LocalCache {\n public name: string;\n public playbackProfile?: string;\n public address: URL;\n\n constructor(address: LocalCacheAddress) {\n this.name = address.name;\n this.playbackProfile = address.playbackProfile;\n this.address = new URL(address.httpsAddress);\n }\n\n public getUrl(url: string): string {\n if (!url)\n return null;\n\n return this.address + 'cache?file=' + encodeURIComponent(url);\n }\n\n /**\n * Pings the local cache. Returns true if the local cache is accessible\n */\n public async ping(): Promise<boolean> {\n const timeout = 1000;\n\n const controller = new AbortController();\n const id = setTimeout(() => controller.abort(), timeout);\n\n try {\n // fetch with a 1second timeout\n const response = await fetch(this.address + 'ping', {\n method: 'GET',\n mode: 'cors',\n signal: controller.signal\n });\n\n // ready the text before we clear the timeout because it needs to be part of the whole request\n const text = await response.text();\n\n // clear the timeout so we dont abort now that we've gotten a response\n clearTimeout(id);\n\n return text === 'PONG';\n } catch {\n return false;\n }\n }\n}\n","import videojs, { VideoJsPlayer } from 'video.js';\n\n/**\n * Middleware used to update the src of a video to call the active local cache\n */\nclass LocalCacheMiddleware implements videojs.Middleware {\n private player: VideoJsPlayer;\n private logger: videojs.Log;\n\n constructor(player: VideoJsPlayer) {\n this.player = player;\n this.logger = videojs.log.createLogger('localcache');\n }\n\n public async setSource(src: videojs.Tech.SourceObject, next: any): Promise<void> {\n // only set the source if the local cache plugin has been registered, and we have a src string\n if (this.player.localCache && src?.src !== undefined) {\n const activeLocalCache = await this.player.localCache().getActiveLocalCache();\n\n if (activeLocalCache !== null) {\n this.logger.debug('Using Local Cache', activeLocalCache);\n src.src = activeLocalCache.getUrl(src.src);\n }\n }\n\n // call the next function in the pipeline\n next(null, src);\n }\n}\n\nvideojs.use('*', (player: VideoJsPlayer) => new LocalCacheMiddleware(player));\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { LocalCachePlugin } from 'projects/player/plugins/localcache-plugin/localcache-plugin';\n\nexport const LocalCacheIconSvg = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<svg width=\"24px\" height=\"24px\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">' +\n '<g id=\"Artboard\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" opacity=\"0.9\">' +\n '<g id=\"Local-Cache\" transform=\"translate(2.000000, 2.000000)\">' +\n '<rect id=\"Rectangle\" fill=\"#FFFFFF\" x=\"0\" y=\"2.4\" width=\"18.8\" height=\"15.2\"></rect>' +\n '<ellipse id=\"Oval\" fill=\"#FFFFFF\" cx=\"9.4\" cy=\"2.4\" rx=\"9.4\" ry=\"2.4\"></ellipse>' +\n '<ellipse id=\"Oval-Copy\" fill=\"#FFFFFF\" cx=\"9.4\" cy=\"17.6\" rx=\"9.4\" ry=\"2.4\"></ellipse>' +\n '<g id=\"Logo/Circle\" transform=\"translate(2.500000, 3.000000)\">' +\n '<circle id=\"Oval\" fill=\"#FFFFFF\" cx=\"7\" cy=\"7\" r=\"7\"></circle>' +\n '<polygon id=\"Fill-1\" fill=\"#F8981D\" points=\"4.66666667 2.33333333 4.66666667 11.4245258 10.0383286 6.87866667\"></polygon>' +\n '</g>' +\n '</g>' +\n '</g>' +\n'</svg>';\n\nimport './local-cache-indicator.scss';\n\nconst Component = videojs.getComponent('Component');\n\nclass LocalCacheIndicator extends Component {\n private localCachePlugin: LocalCachePlugin;\n\n constructor(player: VideoJsPlayer, options: videojs.ComponentOptions) {\n super(player, options);\n\n this.hide();\n\n this.onLocalCacheChange = this.onLocalCacheChange.bind(this);\n\n player.ready(() => {\n this.initialize();\n });\n }\n\n public createEl(): Element {\n return super.createEl('div', {\n className: 'vjs-local-cache-indicator',\n innerHTML: `<div class=\"vjs-local-cache-indicator-icon\">${LocalCacheIconSvg}</div>`\n }, {\n title: 'Streaming from ClickView Local Cache'\n });\n }\n\n private initialize(): void {\n // we have to set this after the player is ready otherwise it will try to initialize the plugin\n this.localCachePlugin = this.player_.localCache();\n\n // only bind events if the local cache plugin has been reigstered\n if (this.localCachePlugin) {\n this.localCachePlugin.on('localcachechanged', this.onLocalCacheChange);\n\n this.player_.on('dispose', () => {\n this.localCachePlugin.off('localcachechanged', this.onLocalCacheChange);\n });\n\n this.onLocalCacheChange();\n }\n }\n\n private async onLocalCacheChange(): Promise<void> {\n const activeLocalCache = await this.localCachePlugin.getActiveLocalCache();\n\n if (activeLocalCache)\n this.show();\n else\n this.hide();\n }\n}\n\nvideojs.registerComponent('localCacheIndicator', LocalCacheIndicator);\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { LocalCacheAddress } from 'projects/player/interfaces/models/PlaybackObject';\nimport { QualityHelper } from 'projects/player/utils/quality-helper';\n\nimport { LocalCache } from './LocalCache';\n\n// import middleware just so it get registered in videojs\nimport 'projects/player/plugins/localcache-plugin/localcache-middleware';\nimport 'projects/player/plugins/localcache-plugin/compontents/local-cache-indicator';\n\n\nconst Plugin = videojs.getPlugin('plugin');\n\ninterface LocalCachePluginOptions {\n localCacheAddresses: LocalCacheAddress[];\n enabled: boolean;\n}\n\nexport class LocalCachePlugin extends Plugin {\n private localCaches_: LocalCache[];\n private activeLocalCache_: Promise<LocalCache | null>;\n private enabled_: boolean;\n private logger_: videojs.Log;\n\n constructor(player: VideoJsPlayer, options?: LocalCachePluginOptions) {\n super(player);\n\n this.logger_ = videojs.log.createLogger('localcache');\n\n if (options === undefined)\n throw Error('no options defined');\n\n this.localCaches_ = options.localCacheAddresses.map(lca => {\n return new LocalCache(lca);\n });\n\n this.player.ready(() => {\n this.initialize();\n\n if (options.enabled)\n this.enable();\n });\n }\n\n get isEnabled(): boolean {\n return this.enabled_;\n }\n\n /**\n * Enable local cache support\n */\n public enable(): void {\n this.enabled_ = true;\n this.resetActiveLocalCache();\n }\n\n /**\n * Disable local cache support\n */\n public disable(): void {\n this.enabled_ = false;\n }\n\n /**\n * Get the active local cache\n */\n public getActiveLocalCache(): Promise<LocalCache | null> {\n if (!this.enabled_)\n return null;\n\n return this.activeLocalCache_;\n }\n\n /**\n * Resets the active local cache and starts the checks to find a new active local cache\n */\n public resetActiveLocalCache(): void {\n this.clearActiveLocalCache();\n this.activeLocalCache_ = this.getActiveLocalCacheInternal();\n }\n\n /**\n * Clears the active local cache\n */\n public clearActiveLocalCache(): void {\n if (!this.activeLocalCache_)\n return;\n\n this.activeLocalCache_ = null;\n this.onLocalCacheChange(null);\n }\n\n /**\n * Called if a local cache can be pinged, but we cannot\n * stream videos from it.\n */\n private removeLocalCache(localCache: LocalCache): void {\n this.localCaches_ = this.localCaches_.filter(l => l !== localCache);\n }\n\n public dispose() {\n super.dispose();\n }\n\n private initialize(): void {\n this.player.controlBar.addChild('localCacheIndicator');\n }\n\n public async handleNetworkError(): Promise<boolean> {\n const activeCache = await this.getActiveLocalCache();\n\n if (activeCache) {\n const canReachActiveCache = await activeCache.ping();\n\n // If we can reach our local cache, it means it's erroring\n // when fetching the video file, so we remove it from our list.\n canReachActiveCache && this.removeLocalCache(activeCache);\n }\n\n // Reset the active local cache in case that was the issue\n this.resetActiveLocalCache();\n\n // Wait for our new local cache to connect before we reset the source\n await this.getActiveLocalCache();\n\n // Set the source again, which will either go to the cloud\n // or trying using the alternate local cache\n this.resetSource();\n\n // Our network error handlers return whether or not they set the src\n // of the video. Our handler here will always result in .src() being called\n // so we just always return true.\n return true;\n }\n\n private resetSource(): void {\n const qualityLevels = this.player.qualityLevels();\n \n // Setting enabled true will cause it to call .src() again\n // Which should update the src to an appropriate url\n for (let i = 0; i < qualityLevels.length; i++) {\n if (qualityLevels[i].enabled)\n qualityLevels[i].enabled = true;\n }\n }\n\n private async getActiveLocalCacheInternal(): Promise<LocalCache | null> {\n const onlineCaches: (LocalCache)[] = [];\n\n // ping the cache then push it into the array\n // we do this so the cache which responds first is the one we use\n // otherwise id just return them and use the result from Promise.all\n const ping = async (localCache: LocalCache) => {\n if (await localCache.ping())\n onlineCaches.push(localCache);\n };\n\n await Promise.all(this.localCaches_.map(lc => ping(lc)));\n\n if (onlineCaches.length > 0) {\n const activeLocalCache = onlineCaches[0];\n\n this.onLocalCacheChange(activeLocalCache);\n\n return activeLocalCache;\n }\n\n return null;\n }\n\n private onLocalCacheChange(localCache?: LocalCache): void {\n this.logger_.debug('Local Cache changed', localCache);\n\n // trigger the change event\n this.trigger('localcachechanged', {\n localCache: localCache\n });\n\n let profileChanged = false;\n\n if (localCache) {\n // if we have a playback quality, select it\n if (localCache.playbackProfile) {\n this.logger_.debug('Changing active profile for local cache', localCache.playbackProfile);\n\n QualityHelper.enableProfileOrNextBest(this.player.qualityLevels(), localCache.playbackProfile);\n profileChanged = true;\n }\n }\n\n // if the profile was not changed, we need to reset the source to get the middleware to load in the new src url\n if (!profileChanged) {\n this.player.src(this.player.src());\n }\n }\n}\n\nvideojs.registerPlugin('localCache', LocalCachePlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n localCache(options?: LocalCachePluginOptions): LocalCachePlugin;\n }\n}\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { Files } from 'projects/player/interfaces/models/PlaybackObject';\nimport { AjaxHelper } from 'projects/player/utils/ajax-helper';\n\nimport { Source } from '../progressive-files-plugin/interfaces/Source';\n\n/**\n * We will only attempt to re-fetch out files\n * once every 15 minutes.\n */\nconst FETCH_TIMEOUT = 900000;\n\nconst Plugin = videojs.getPlugin('plugin');\n\ninterface HandleNetworkErrorsOptions {\n fileToken: string;\n playerApi: URL;\n}\n\nexport class HandleNetworkErrorsPlugin extends Plugin {\n private playerApi: URL;\n private fileToken: string;\n private logger: videojs.Log;\n\n constructor(player: VideoJsPlayer, options: HandleNetworkErrorsOptions) {\n super(player);\n \n this.playerApi = options.playerApi;\n this.fileToken = options.fileToken;\n this.logger = videojs.log.createLogger('video-signature-expiry-plugin');\n\n this.bindErrorHandlers();\n }\n\n private bindErrorHandlers(): void {\n this.onError = this.onError.bind(this);\n\n this.player.on('error', this.onError);\n }\n\n public dispose(): void {\n this.player.off('error', this.onError);\n super.dispose();\n }\n\n private async onError(): Promise<void> {\n const errorCode = this.player.error().code;\n\n // If it's not a network error or an unsupported media error\n // we have nothing else to do.\n if (errorCode !== MediaError.MEDIA_ERR_NETWORK\n && errorCode !== MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED)\n return;\n \n // If we have an active local cache, we let the the local cache plugin handle the error.\n // We have no way of knowing if it's an expired signature error\n // But if it is, the local cache plugin will remove all the caches, and the \n // handleVideoSignatureExpiry() function will be called eventually.\n if (await this.player.localCache().getActiveLocalCache()) {\n this.callErrorHandler(() => this.player.localCache().handleNetworkError());\n return;\n }\n\n this.callErrorHandler(() => this.handleVideoSignatureExpiry());\n }\n\n private refetchedSourcesTimestamp: number;\n private async handleVideoSignatureExpiry(): Promise<boolean> {\n if (!this.playerApi || !this.fileToken)\n return false;\n\n /**\n * If it hasn't been 15 minutes since we last tried to refetch our files, do nothing.\n */\n if (this.refetchedSourcesTimestamp + FETCH_TIMEOUT > Date.now())\n return false;\n\n this.refetchedSourcesTimestamp = Date.now();\n\n let files: Files = null;\n try {\n this.logger.debug('Detected expired mp4 urls, attempting to refetch');\n \n const fetchUrl = `${this.playerApi.origin}/api/files?fileToken=${this.fileToken}`;\n files = await AjaxHelper.get<Files>(fetchUrl);\n } catch {\n this.logger.error('Failed to refetch expired mp4 urls');\n return false;\n }\n \n this.logger.debug('Mp4 urls successfully refetched');\n\n this.player.progressiveFiles().repopulateSources(files.progressive.map(file => <Source> {\n id: file.profile,\n mimeType: file.mimeType,\n url: file.url\n }));\n this.fileToken = files.fileToken;\n return true;\n }\n\n private async callErrorHandler(errorHandler: () => Promise<boolean>): Promise<void> {\n const currentTime = this.player.currentTime();\n const isPlaying = !this.player.paused();\n const playbackRate = this.player.playbackRate();\n\n const onLoadedMetadata = () => {\n this.player.playbackRate(playbackRate);\n this.player.currentTime(currentTime);\n if (isPlaying) this.player.play();\n this.player.error(null);\n };\n\n this.player.one('loadedmetadata', onLoadedMetadata);\n\n if (await errorHandler())\n return;\n\n this.player.off('loadedmetadata', onLoadedMetadata);\n }\n}\n\nvideojs.registerPlugin('handleNetworkErrors', HandleNetworkErrorsPlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n handleNetworkErrors(options: HandleNetworkErrorsOptions): HandleNetworkErrorsPlugin;\n }\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { EntityType, EventVersion, ToggleDescriptor, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { SubtitleSizes, TextTrackSettings } from 'projects/player/components/text-track-settings/text-track-settings';\nimport { AnalyticsService } from 'projects/player/services/analytics-service';\nimport { LocalStorageHelper } from 'projects/player/utils/local-storage-helper';\n\nconst Plugin = videojs.getPlugin('plugin');\n\n/* Local Storage keys */\nconst USER_SHOW_SUBTITLES = 'cvplayer-show-subtitles';\nconst SELECTED_LANGUAGE = 'cvplayer-selected-language';\nconst USER_SUBTITLE_SIZE = 'cvplayer-subtitle-size';\n\ninterface PersistSubtitleSettingsPluginOptions {\n showSubtitles: boolean;\n subtitleSize: SubtitleSizes;\n analyticsService?: AnalyticsService;\n}\n\nclass PersistSubtitleSettingsPlugin extends Plugin {\n private options: PersistSubtitleSettingsPluginOptions;\n\n constructor(player: VideoJsPlayer, options: PersistSubtitleSettingsPluginOptions) {\n super(player);\n\n this.options = options;\n\n this.initialize();\n }\n\n private initialize(): void {\n this.applyUserPreferences = this.applyUserPreferences.bind(this);\n\n const tracks = this.player.textTracks();\n\n /**\n * No subtitles means do nothing\n */\n if (!tracks.length)\n return;\n\n this.bindEventListeners();\n\n this.applyUserPreferences();\n }\n\n public applyUserPreferences(): void {\n let showSubtitles = !!this.options.showSubtitles;\n\n const userShowSubtitles = this.safeGet(USER_SHOW_SUBTITLES);\n\n if (userShowSubtitles === 'true')\n showSubtitles = true;\n\n if (userShowSubtitles === 'false')\n showSubtitles = false;\n\n if (showSubtitles) {\n /**\n * Guess which track is best and enable it\n */\n const track = this.guessWhichTrack();\n\n if (track)\n track.mode = 'showing';\n } else {\n // we hide the subtitles instead of disabling them so the cueChange event would be triggered\n this.hideSubtitles();\n }\n\n let subtitleSize = this.safeGet(USER_SUBTITLE_SIZE) as SubtitleSizes;\n\n if (!subtitleSize)\n subtitleSize = this.options.subtitleSize;\n\n if (this.player.options_.mobile)\n subtitleSize = 'medium';\n\n if (subtitleSize) {\n const textTrackSettings = (this.player as any).textTrackSettings as TextTrackSettings;\n textTrackSettings.setSizeSetting(subtitleSize);\n }\n }\n\n private safeGet(key: string): string {\n if (!LocalStorageHelper.hasLocalStorage())\n return undefined;\n\n return LocalStorageHelper.get(key);\n }\n\n private onSelectedLanguageChange(): void {\n const tracks = this.player.textTracks();\n\n for (let i = 0; i < tracks.length; i++) {\n const track = tracks[i];\n\n if (track.mode === 'showing') {\n LocalStorageHelper.set(USER_SHOW_SUBTITLES, 'true');\n LocalStorageHelper.set(SELECTED_LANGUAGE, track.language);\n \n this.options.analyticsService?.logUserAction({ language: track.language }, {\n actionType: UserAction.Select,\n entity: EntityType.Subtitle,\n workflowPhase: WorkflowPhase.Complete,\n descriptor: ToggleDescriptor.On\n });\n \n return;\n }\n }\n\n /**\n * User has turned off subtitles\n */\n LocalStorageHelper.set(USER_SHOW_SUBTITLES, 'false');\n LocalStorageHelper.remove(SELECTED_LANGUAGE);\n\n this.options.analyticsService?.logUserAction({ language: '' }, {\n actionType: UserAction.Select,\n entity: EntityType.Subtitle,\n workflowPhase: WorkflowPhase.Complete,\n descriptor: ToggleDescriptor.Off,\n eventVersion: EventVersion.V3\n });\n }\n\n private bindEventListeners(): void {\n /**\n * Don't bind out event listeners if the user doesn't have local storage\n */\n if (!LocalStorageHelper.hasLocalStorage())\n return;\n\n this.onSelectedLanguageChange = this.onSelectedLanguageChange.bind(this);\n this.onChangeSubtitleSize = this.onChangeSubtitleSize.bind(this);\n\n this.player.on('cv:languageselected', this.onSelectedLanguageChange);\n this.player.on('changesubtitlesize', this.onChangeSubtitleSize);\n\n this.one('dispose', () => {\n this.player.off('cv:languageselected', this.onSelectedLanguageChange);\n this.player.off('changesubtitlesize', this.onChangeSubtitleSize);\n });\n }\n\n private onChangeSubtitleSize(): void {\n const textTrackSettings = (this.player as any).textTrackSettings as TextTrackSettings;\n const size = textTrackSettings.getSizeSetting();\n LocalStorageHelper.set(USER_SUBTITLE_SIZE, size);\n }\n\n private guessWhichTrack(): TextTrack {\n const selectedLanguage = this.safeGet(SELECTED_LANGUAGE) || window.navigator.language;\n\n const {\n language: userLanguage,\n country: userCountry\n } = this.getLanguageParts(selectedLanguage);\n\n let bestGuess: TextTrack;\n let langOnlyMatch: TextTrack;\n\n const tracks = this.player.textTracks();\n\n for (let i = 0; i < tracks.length; i++) {\n const track = tracks[i];\n\n const { language, country } = this.getLanguageParts(track.language);\n\n /**\n * If the language matches we store\n * it and keep looking and will return\n * this if we can't find anything else\n */\n if (language === userLanguage) {\n bestGuess = track;\n\n if (!country)\n langOnlyMatch = track;\n\n /**\n * If it's an exact match we return\n */\n if (country === userCountry)\n return bestGuess;\n }\n }\n\n /**\n * If we've gotten this far we don't have an exact match\n * So we'll prefer any subtitles that match\n * on language only before we use our best guess.\n */\n if (langOnlyMatch)\n return langOnlyMatch;\n\n if (bestGuess)\n return bestGuess;\n\n /**\n * Just take the first if we can't find anything\n */\n return null;\n }\n\n private getLanguageParts(lang: string): { language: string, country: string} {\n const langParts = lang.toLowerCase().split('-');\n const language = langParts[0];\n const country = langParts[1];\n\n return {\n language,\n country\n };\n }\n\n private hideSubtitles(): void {\n const tracks = this.player.textTracks();\n for (let i = 0; i < tracks.length; i++) {\n const track = tracks[i];\n track.mode = 'hidden';\n }\n }\n\n public previewModeSubtitles(): void {\n /**\n * Guess which track is best and enable it\n */\n const track = this.guessWhichTrack();\n\n if (track)\n track.mode = 'showing';\n\n /**\n * Need to disable our event listener as we set the subtitle size, then re-add it afterwards.\n */\n this.player.off('changesubtitlesize', this.onChangeSubtitleSize);\n const textTrackSettings = (this.player as any).textTrackSettings as TextTrackSettings;\n textTrackSettings.setSizeSetting('large');\n this.player.on('changesubtitlesize', this.onChangeSubtitleSize);\n }\n}\n\nvideojs.registerPlugin('persistSubtitleSettingsPlugin', PersistSubtitleSettingsPlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n persistSubtitleSettingsPlugin(options?: PersistSubtitleSettingsPluginOptions): PersistSubtitleSettingsPlugin;\n }\n}\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { EntityType, EventVersion, PlaybackDescriptor, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { LocalCache } from 'projects/player/plugins/localcache-plugin/LocalCache';\nimport { AnalyticsService } from 'projects/player/services/analytics-service';\nimport { LocalStorageHelper } from 'projects/player/utils/local-storage-helper';\nimport { QualityHelper } from 'projects/player/utils/quality-helper';\n\nconst Plugin = videojs.getPlugin('plugin');\n\nconst USER_PLAYBACK_QUALITY = 'cvplayer-playback-quality';\nconst USER_LC_PLAYBACK_QUALITY = 'cvplayer-localcache-playback-quality';\n\nconst PUBLIC_PLAYBACK_PROFILE = '1080';\n\ninterface PersistQualitySettingsPluginOptions {\n playbackProfile: string;\n playbackProfileLocalCache: string;\n analyticsService?: AnalyticsService;\n}\n\nclass PersistQualitySettingsPlugin extends Plugin {\n private options: PersistQualitySettingsPluginOptions;\n\n constructor(player: VideoJsPlayer, options: PersistQualitySettingsPluginOptions) {\n super(player);\n\n this.options = options;\n\n this.player.ready(() => this.initialize());\n }\n\n private async initialize(): Promise<void> {\n const activeLocalCache = await this.getActiveLocalCache();\n\n let quality = activeLocalCache ?\n this.options.playbackProfileLocalCache :\n this.options.playbackProfile;\n\n // No settings are passed in if the user is not signed in\n if (!quality)\n quality = PUBLIC_PLAYBACK_PROFILE;\n\n if (LocalStorageHelper.hasLocalStorage()) {\n const userQuality = LocalStorageHelper.get(this.getStorageKey(!!activeLocalCache));\n\n if (userQuality)\n quality = userQuality;\n }\n\n const qualityLevels = this.player.qualityLevels();\n if (!activeLocalCache?.playbackProfile)\n QualityHelper.enableProfileOrNextBest(qualityLevels, quality);\n\n if (!LocalStorageHelper.hasLocalStorage())\n return;\n\n this.onQualityLevelsChange = this.onQualityLevelsChange.bind(this);\n\n qualityLevels.on('change', this.onQualityLevelsChange);\n this.on('dispose', () => {\n qualityLevels.off('change', this.onQualityLevelsChange);\n });\n }\n\n private async onQualityLevelsChange(): Promise<void> {\n const localCacheIsActive = await this.isLocalCacheActive();\n\n const qualityLevels = this.player.qualityLevels();\n const currentQuality = qualityLevels[qualityLevels.selectedIndex];\n\n LocalStorageHelper.set(this.getStorageKey(localCacheIsActive), currentQuality.id);\n\n this.options.analyticsService?.logUserAction({ quality: currentQuality.id }, {\n actionType: UserAction.Select,\n workflowPhase: WorkflowPhase.Complete,\n descriptor: PlaybackDescriptor.ChangeResolution,\n entity: EntityType.Resolution,\n eventVersion: EventVersion.V3\n });\n }\n\n private async isLocalCacheActive(): Promise<boolean> {\n return !!(await this.player.localCache().getActiveLocalCache());\n }\n\n private getActiveLocalCache(): Promise<LocalCache> {\n return this.player.localCache().getActiveLocalCache();\n }\n\n private getStorageKey(localCacheIsActive: boolean): string {\n return localCacheIsActive ? USER_LC_PLAYBACK_QUALITY : USER_PLAYBACK_QUALITY ;\n }\n}\n\nvideojs.registerPlugin('persistQualitySettingsPlugin', PersistQualitySettingsPlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n persistQualitySettingsPlugin(options: PersistQualitySettingsPluginOptions): PersistQualitySettingsPlugin;\n }\n}\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { ProgressEventPair } from 'projects/player/plugins/progress-reporter-plugin/interfaces/ProgressEvent';\n\nimport './progress-reporter-display.scss';\n\nconst Component = videojs.getComponent('Component');\n\ninterface ProgressItemOptions extends videojs.ComponentOptions {\n event: ProgressEventPair;\n}\n\nclass ProgressItem extends Component {\n private el_: HTMLElement;\n public options_: ProgressItemOptions;\n\n constructor(player: VideoJsPlayer, options: ProgressItemOptions) {\n super(player, options);\n }\n\n public createEl(): HTMLDivElement {\n return videojs.dom.createEl('div', {\n className: 'cv-progress-reporter-item'\n }) as HTMLDivElement;\n }\n\n public update(): void {\n const event = this.options_.event;\n const duration = this.player_.duration();\n \n\n const eventDuration = event.end.time - event.start.time;\n const width = eventDuration / duration;\n this.el_.style.width = (width * 100) + '%';\n\n const start = event.start.time / duration;\n this.el_.style.left = (start * 100) + '%';\n }\n}\n\nexport class ProgressReporterDisplay extends Component {\n private events_: ProgressEventPair[] = [];\n\n public update(): void {\n const children = this.children();\n\n for (let i = children.length; i > 0; i--) {\n this.removeChild(children[i]);\n }\n\n this.events_.forEach(event => {\n const item = new ProgressItem(this.player(), {\n event\n });\n this.addChild(item);\n item.update();\n });\n }\n\n public addEvents(events: ProgressEventPair[]): void {\n this.events_.push(...events);\n this.update();\n }\n\n public createEl(): HTMLDivElement {\n return videojs.dom.createEl('div', {\n className: 'cv-progress-reporter-display'\n }) as HTMLDivElement;\n }\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { ProgressEvent, ProgressEventPair } from 'projects/player/plugins/progress-reporter-plugin/interfaces/ProgressEvent';\n\nimport { ProgressReporterDisplay } from './components/progress-reporter-display';\n\nconst Plugin = videojs.getPlugin('plugin');\n\nconst DEFAULT_REPORTING_INTERVAL = 5000; // Time in ms\n\nconst KONAMI_CODE = 'ArrowUpArrowUpArrowDownArrowDownArrowLeftArrowRightArrowLeftArrowRightba';\n\nconst Events = {\n PLAY: 'play',\n PLAYING: 'playing',\n PAUSE: 'pause',\n SEEKING: 'seeking',\n SEEK_START: 'seekstart',\n SEEK_END: 'seekend',\n ENDED: 'ended',\n PAUSED_SEEK: 'pausedseek',\n TIME_UPDATE: 'timeupdate'\n};\n\ninterface ProgressReporterPluginOptions {\n onFlush: (events: ProgressEventPair[]) => void;\n interval?: number; // Time in ms. Defaults to DEFAULT_REPORTING_INTERVAL\n}\n\nclass ProgressReporterPlugin extends Plugin {\n private options: ProgressReporterPluginOptions;\n private progressReporterDisplay: ProgressReporterDisplay;\n\n private eventBuffer: ProgressEvent[] = [];\n private latestTime: number = 0;\n /**\n * Used to clean up data while flushing the buffer\n * It's stored on the instance because it needs to maintain state\n * between buffers.\n */\n private lastPlayingTime: number = 0;\n private previousLatestTime: number;\n private isPlaying: boolean = false;\n private isSeeking: boolean = false;\n private hasEnded: boolean = false;\n /**\n * We use our timeupdate event instead of asking for\n * a function to add a single event listener in our options.\n */\n private shouldLogPlayOnTimeUpdate: boolean = false;\n private pauseTimeout: number;\n\n constructor(player: VideoJsPlayer, options: ProgressReporterPluginOptions) {\n super(player, options);\n\n this.options = options;\n this.player.ready(() => this.initialize());\n }\n\n private initialize(): void {\n this.validateOptions();\n this.bindListeners();\n this.startInterval();\n\n // Uncomment below to turn on progress reporter display in dev\n // this.addDisplay();\n this.addEasterEgg();\n }\n\n private validateOptions(): void {\n if (!(typeof this.options.onFlush === 'function'))\n throw new Error('Please provide the onFlush option');\n }\n\n private bindListeners(): void {\n const eventHash: { [index: string]: () => void } = {\n [Events.PLAY]: () => this.onPlay(),\n [Events.PAUSE]: () => this.onPause(),\n [Events.TIME_UPDATE]: () => this.onTimeUpdate(),\n [Events.SEEKING]: () => this.onSeeking(),\n [Events.ENDED]: () => this.onEnded(),\n [Events.PLAYING]: () => this.onPlaying()\n };\n\n const keys = Object.keys(eventHash);\n\n keys.forEach(k => this.player.on(k, eventHash[k]));\n\n // Uncomment for debugging all player events\n // Object.keys(Events).forEach(key => {\n // this.player.on((Events as any)[key], event => {\n // console.log(event.type);\n // });\n // });\n\n this.one('dispose', () => {\n keys.forEach(k => this.player.off(k, eventHash[k]));\n });\n }\n\n private interval: number;\n private startInterval(): void {\n const interval = this.options.interval || DEFAULT_REPORTING_INTERVAL;\n this.interval = window.setInterval(() => this.flushBuffer(), interval);\n\n this.player.one('dispose', () => window.clearInterval(this.interval));\n }\n\n private addEasterEgg(): void {\n /**\n * Type in the konami code in order to see the progress reporting display\n */\n let phrase = '';\n let keyUpTimeout: number;\n\n const onKeyUp = (event: KeyboardEvent) => {\n phrase = phrase + event.key;\n\n if (phrase === KONAMI_CODE)\n this.addDisplay();\n \n window.clearTimeout(keyUpTimeout);\n keyUpTimeout = window.setTimeout(() => {\n phrase = '';\n }, 500);\n };\n\n /**\n * OR if you're on a touch device, tap and hold the play button for 10 seconds\n */\n let touching = false;\n let touchTimeout: number;\n\n const onTouchStart = () => {\n touching = true;\n touchTimeout = window.setTimeout(() => {\n if (touching)\n this.addDisplay();\n }, 10000);\n };\n\n function onTouchEnd(): void {\n touching = false;\n window.clearTimeout(touchTimeout);\n }\n\n this.player.el().addEventListener('keyup', onKeyUp);\n\n const playToggle = this.player.getChild('Collapserator')\n .getChild('PlayToggle');\n \n playToggle.on('touchstart', onTouchStart);\n playToggle.on('touchend', onTouchEnd);\n\n this.player.one('dispose', () => {\n this.player?.el()?.removeEventListener('keyup', onKeyUp);\n \n playToggle.off('touchstart', onTouchStart);\n playToggle.off('touchend', onTouchEnd);\n });\n }\n\n private addDisplay(): void {\n if (this.progressReporterDisplay)\n return;\n \n this.progressReporterDisplay = new ProgressReporterDisplay(this.player);\n this.player.addChild(this.progressReporterDisplay);\n this.player.options_.inactivityTimeout = 0;\n\n /**\n * Prevent our interval from asking this component to render\n * after we've disposed\n */\n this.player.one('dispose', () => {\n this.progressReporterDisplay = undefined;\n });\n }\n\n private onPlay(): void {\n this.isPlaying = true;\n\n /**\n * If we're seeking, we treat the next play event as a seek end.\n */\n if (this.isSeeking) {\n this.logEvent(Events.SEEK_END);\n this.isSeeking = false;\n return;\n }\n\n /**\n * If the video has already ended, the currentTime won't be accurate\n * on the first play event, so instead we use the subsequent time update.\n */\n if (this.hasEnded) {\n this.shouldLogPlayOnTimeUpdate = true;\n this.hasEnded = false;\n return;\n }\n\n this.logEvent(Events.PLAY);\n }\n\n private onPause(): void {\n if (this.isSeeking)\n return;\n\n /**\n * Because some players (Firefox) fire a PAUSE immediately followed by a SEEKING\n * when the user seeks while the video is playing. We don't fire the pause immediately\n * instead we do it in a timeout. This gives the onSeeking handler a chance to cancel\n * the PAUSE event if it's been fired immediately after a pause.\n * \n * Sha's thoughts: It's humanly impossible to seek 25ms after a pause... Probably.\n */\n this.pauseTimeout = window.setTimeout(() => {\n this.isPlaying = false;\n this.logEvent(Events.PAUSE);\n delete this.pauseTimeout;\n }, 50);\n }\n\n private onTimeUpdate(): void {\n if (this.shouldLogPlayOnTimeUpdate) {\n this.shouldLogPlayOnTimeUpdate = false;\n this.logEvent(Events.PLAY);\n }\n\n /**\n * We don't log playing if we're not playing or we're currently seeking.\n */\n if (!this.isPlaying || this.isSeeking)\n return;\n\n this.logEvent(Events.PLAYING);\n }\n\n private onSeeking(): void {\n /**\n * Because some players (Firefox) don't follow the specification.\n * When the following event series happens in firefox: TIMEUPDATE, TIMEUPDATE, PAUSE, SEEK\n * We need to use the first TIMEUPDATE event to accurately record where\n * the user has started scrubbing from. This is why we constantly store \n * previousLatestTime, which will always be the time of the event 2 events ago.\n * \n * When we detect a SEEK in firefox (PAUSE immediately followed by SEEK)\n * we use the time from 2 events ago as the latest time.\n */\n if (this.pauseTimeout) {\n this.latestTime = this.previousLatestTime;\n window.clearTimeout(this.pauseTimeout);\n delete this.pauseTimeout;\n }\n\n if (!this.isPlaying)\n this.logEvent(Events.PAUSED_SEEK);\n\n /**\n * We only fire the first seeking event\n * We don't fire seeking if we're not playing.\n */\n if (this.isSeeking || !this.isPlaying)\n return;\n\n this.isSeeking = true;\n\n this.logEvent(Events.SEEK_START);\n }\n\n private onEnded(): void {\n this.hasEnded = true;\n this.logEvent(Events.ENDED);\n }\n\n /**\n * Our onPlay event handler handles this for 90% of scenarios\n * however if the player is programmatically seeked (e.g player.currentTime(5);)\n * our onSeeking event is fired without a follow up onPlay event.\n * \n * This event handler just makes sure to put the progress reporter back into the right\n * state to continue collecting events - Sha\n */\n private onPlaying(): void {\n this.isSeeking = false;\n this.isPlaying = true;\n }\n\n private logEvent(eventType: string): void {\n if (!this.player)\n return;\n\n let time = this.player.currentTime();\n\n /**\n * When seekstart is fired, the currentTime is the scrubbing time which isn't useful to us\n * we want to instead use the last time we've recorded.\n */\n if (eventType === Events.SEEK_START) {\n time = this.latestTime;\n }\n\n this.previousLatestTime = this.latestTime;\n this.latestTime = this.player.currentTime();\n\n this.eventBuffer.push({\n time: time,\n type: eventType\n });\n }\n\n private shouldUseCarriedOverTime(eventType: string): boolean {\n return this.lastPlayingTime && (eventType === Events.PLAYING || eventType === Events.PLAY);\n }\n\n private shouldSaveCarriedOverTime(eventType: string): boolean {\n return eventType === Events.PLAYING || eventType === Events.PAUSE;\n }\n\n private shouldClearCarriedOverTime(eventType: string): boolean {\n return eventType === Events.ENDED || eventType === Events.PAUSED_SEEK;\n }\n\n private flushBuffer(): void {\n const events = [];\n let slice: ProgressEventPair = {} as ProgressEventPair;\n\n while (this.eventBuffer.length) {\n const current = this.eventBuffer.shift();\n\n /**\n * We don't carry over the pause time from the end of \n * the video or if the user has seeked during a pause.\n */\n if (this.shouldClearCarriedOverTime(current.type)) {\n delete this.lastPlayingTime;\n continue;\n }\n\n /**\n * If the slice we're building doesn't have a start event.\n */\n if (!slice.start) {\n if (this.shouldUseCarriedOverTime(current.type)) {\n current.time = this.lastPlayingTime;\n delete this.lastPlayingTime;\n }\n\n slice.start = current;\n continue;\n }\n\n /**\n * We skip over all playing events except the last one\n */\n if (current.type === Events.PLAYING && this.eventBuffer.length > 0)\n continue;\n\n /**\n * End times for playing and pause events need to carry forward\n * onto the next slice's playing or play events\n */\n if (this.shouldSaveCarriedOverTime(current.type))\n this.lastPlayingTime = current.time;\n\n slice.end = current;\n events.push(slice);\n slice = {} as ProgressEventPair;\n }\n\n this.eventBuffer = [];\n\n if (!events.length)\n return;\n\n if (!this.validateEvents(events))\n return;\n\n this.options.onFlush(events);\n\n this.player?.trigger('progressflush');\n this.progressReporterDisplay?.addEvents(events);\n }\n\n private validateEvents(events: ProgressEventPair[]): boolean {\n /**\n * This is a failsafe for if event recording has horribly broken.\n * The user can't watch more than 5 seconds of video within 5 seconds.\n * If our events total to more than 5 seconds, something has gone wrong.\n */\n let totalTime = 0;\n events.forEach(e => {\n totalTime += e.end.time - e.start.time;\n });\n\n /**\n * We're dividing by 1000 because interval is in miliseconds but the player time\n * is in seconds.\n * \n * We're also adding 0.5 seconds because the video times are not accurate and regular playback\n * could be like 5.005 seconds for example.\n * \n * Finally we're scaling the time by the playback rate, which will be something like 0.5, 1, 1.5, 2 etc.\n */\n let interval = this.options.interval || DEFAULT_REPORTING_INTERVAL;\n interval = interval / 1000;\n interval += 0.5;\n interval = interval * this.player.playbackRate();\n\n return totalTime < interval;\n }\n}\n\nvideojs.registerPlugin('progressReporterPlugin', ProgressReporterPlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n progressReporterPlugin(options?: ProgressReporterPluginOptions): ProgressReporterPlugin;\n }\n}","import videojs from 'video.js';\n\nimport './drag-handle.scss';\n\nconst Component = videojs.getComponent('Component');\n\nexport class DragHandle extends Component {\n public createEl(): HTMLButtonElement {\n const tag = 'span';\n\n const props = {\n innerHTML: '<span class=\"vjs-icon-placeholder\"></span>',\n className: 'cv-drag-handle vjs-control vjs-button'\n };\n\n const el = videojs.dom.createEl(tag, props, {}) as HTMLButtonElement;\n\n return el;\n }\n}","import { WhiteboardSide } from '../interfaces/WhiteboardSide';\n\nexport const WhiteboardSides: WhiteboardSide[] = [ 'top', 'left', 'right', 'bottom' ];\n\nexport const WhiteboardSideNames: {[key in WhiteboardSide]: string} = {\n top: 'Top',\n left: 'Left',\n right: 'Right',\n bottom: 'Bottom'\n};","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { WhiteboardSides } from '../../contants/WhiteboardSides';\nimport { WhiteboardSide } from '../../interfaces/WhiteboardSide';\n\nimport './drag-targets.scss';\n\nconst Component = videojs.getComponent('Component');\n\ninterface DragTargetOptions extends videojs.ComponentOptions {\n side: WhiteboardSide;\n}\n\nclass DragTarget extends Component {\n public options_: DragTargetOptions;\n\n constructor(player: VideoJsPlayer, options: DragTargetOptions) {\n super(player, options);\n\n this.bindEventListeners();\n }\n\n public createEl(): HTMLDivElement {\n return super.createEl('div', {}, {\n class: `cv-drop-target cv-drop-${this.options_.side}`\n }) as HTMLDivElement;\n }\n\n private bindEventListeners(): void {\n const el = this.el();\n\n const dragover = (e: DragEvent) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'move';\n this.addClass('cv-drag-over');\n };\n\n const drop = (e: DragEvent) => {\n e.preventDefault();\n\n this.removeClass('cv-drag-over');\n this.player_.whiteboardModePlugin().setWhiteboardMode(this.options_.side);\n };\n\n const dragleave = () => {\n this.removeClass('cv-drag-over');\n };\n\n el.addEventListener('dragover', dragover);\n el.addEventListener('drop', drop);\n el.addEventListener('dragleave', dragleave);\n this.on('dispose', () => {\n el.removeEventListener('dragover', dragover);\n el.removeEventListener('drop', drop);\n el.removeEventListener('dragleave', dragleave);\n });\n }\n}\n\nexport class DragTargets extends Component {\n constructor(player: VideoJsPlayer, options?: videojs.ComponentOptions) {\n super(player, options);\n\n this.addChildren();\n }\n\n private addChildren(): void {\n WhiteboardSides.forEach(side => {\n this.addChild(new DragTarget(this.player_, {\n side\n }));\n });\n }\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { WhiteboardSide } from '../../interfaces/WhiteboardSide';\n\nconst MenuItem = videojs.getComponent('MenuItem');\n\ninterface WhiteboardModeMenuItemOptions extends videojs.MenuItemOptions {\n side: WhiteboardSide;\n}\n\nexport class WhiteboardModeMenuItem extends MenuItem {\n public options_: WhiteboardModeMenuItemOptions;\n\n constructor(player: VideoJsPlayer, options: WhiteboardModeMenuItemOptions) {\n super(player, options);\n }\n\n public handleClick(): void {\n this.player_.whiteboardModePlugin().setWhiteboardMode(this.options_.side);\n }\n}\n","import videojs from 'video.js';\n\nimport { CollapsibleHeadingMenuItem } from 'projects/player/components/cog-button/collapsible-heading-menu-item';\nimport { CollapsibleComponent } from 'projects/player/interfaces/CollapsibleComponent';\n\nimport { WhiteboardSideNames, WhiteboardSides } from '../../contants/WhiteboardSides';\n\nimport { WhiteboardModeMenuItem } from './whiteboard-mode-menu-item';\n\nconst MenuButton = videojs.getComponent('MenuButton') as unknown as typeof videojs.MenuButton;\n\n\nexport class WhiteboardModeButton extends MenuButton implements CollapsibleComponent {\n public createItems(): WhiteboardModeMenuItem[] {\n const side = this.player_.whiteboardModePlugin().side;\n\n const items: WhiteboardModeMenuItem[] = [\n new CollapsibleHeadingMenuItem(this.player_, {\n label: 'Video Controls'\n }) as any\n ];\n\n WhiteboardSides.forEach(i => {\n items.push(new WhiteboardModeMenuItem(this.player_, {\n side: i,\n label: WhiteboardSideNames[i],\n selectable: true,\n multiSelectable: false,\n selected: i === side\n }));\n });\n\n return items;\n }\n\n public buildWrapperCSSClass(): string {\n return `cv-menu-small cv-has-left-icons ${super.buildWrapperCSSClass()}`;\n }\n\n /**\n * CollapsibileComponent interface implementation\n * from here onward\n */\n public alwaysCollapsed: boolean = true;\n public isCollapsed: boolean = false;\n public isCollabsible: boolean = true;\n \n public getCollabsibleName(): string {\n return 'Video Controls';\n }\n \n public getCollabsibleValue(): string {\n const side = this.player_.whiteboardModePlugin().side;\n return WhiteboardSideNames[side];\n }\n \n public showInCollabsibleMenu(): boolean {\n if (!this.player_.whiteboardModePlugin().isEnabled())\n return false;\n\n return this.player_.isFullscreen();\n }\n \n public showCollapsibleMenu(): void {\n MenuButton.prototype.handleClick.apply(this);\n }\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { LocalStorageHelper } from 'projects/player/utils/local-storage-helper';\n\nimport { DragHandle } from './components/drag-handle/drag-handle';\nimport { DragTargets } from './components/drag-targets/drag-targets';\nimport { WhiteboardModeButton } from './components/whiteboard-mode-button/whiteboard-mode-button';\nimport { WhiteboardSide } from './interfaces/WhiteboardSide';\n\nimport './whiteboard-mode.scss';\n\nconst SIDE = 'cv-whiteboard-side';\n\nconst Plugin = videojs.getPlugin('plugin');\n\nclass WhiteboardModePlugin extends Plugin {\n public side: WhiteboardSide = 'bottom';\n private button: WhiteboardModeButton;\n private dragHandle: videojs.Component;\n private enabled: boolean = true;\n\n constructor(player: VideoJsPlayer) {\n super(player);\n\n this.player.ready(() => {\n this.initialize();\n });\n }\n\n private initialize(): void {\n if (this.player.options_.mobile)\n return;\n\n if (LocalStorageHelper.hasLocalStorage()) {\n const side = LocalStorageHelper.get(SIDE) as WhiteboardSide;\n side && (this.side = side);\n }\n\n this.initCollapserator();\n this.initDragTargets();\n this.initFullscreenListener();\n }\n\n private initCollapserator(): void {\n if (this.player.viewTranscriptPlugin?.().isTranscriptOn())\n return;\n\n const collapserator = this.player.getChild('collapserator');\n this.dragHandle = new DragHandle(this.player);\n this.button = new WhiteboardModeButton(this.player);\n\n collapserator.addChild(this.dragHandle);\n collapserator.addChild(this.button);\n this.player.trigger('cv-updatecog');\n\n const mousedown = () => {\n if (this.player.isFullscreen())\n collapserator.el().setAttribute('draggable', 'true');\n };\n\n const mouseup = () => {\n if (this.player.isFullscreen())\n collapserator.el().setAttribute('draggable', 'false');\n };\n\n const dragstart = (e: DragEvent) => {\n if (this.player.isFullscreen()) {\n this.player.addClass('cv-dragging');\n e.dataTransfer.setData('text/plain', 'handle');\n }\n };\n\n const dragend = () => {\n if (this.player.isFullscreen()) {\n this.player.removeClass('cv-dragging');\n collapserator.el().setAttribute('draggable', 'false');\n }\n };\n\n this.dragHandle.el().addEventListener('mousedown', mousedown);\n this.dragHandle.el().addEventListener('mouseup', mouseup);\n collapserator.el().addEventListener('dragstart', dragstart);\n collapserator.el().addEventListener('dragend', dragend);\n\n this.on('dispose', () => {\n this.dragHandle.el().removeEventListener('mousedown', mousedown);\n this.dragHandle.el().removeEventListener('mouseup', mouseup);\n collapserator.el().removeEventListener('dragstart', dragstart);\n collapserator.el().removeEventListener('dragend', dragend);\n });\n }\n\n private initDragTargets(): void {\n this.player.addChild(new DragTargets(this.player));\n }\n\n private initFullscreenListener(): void {\n this.update = this.update.bind(this);\n this.player.on('fullscreenchange', this.update);\n this.player.on('cv-transcript-toggle', this.update);\n this.one('dispose', () => {\n this.player.off('fullscreenchange', this.update);\n });\n }\n\n public setWhiteboardMode(side: WhiteboardSide): void {\n this.side = side;\n this.button.update();\n\n if (LocalStorageHelper.hasLocalStorage())\n LocalStorageHelper.set(SIDE, side);\n\n this.player.trigger('cv-whiteboard-change');\n this.update();\n }\n\n public setEnabled(val: boolean): void {\n this.enabled = val;\n this.update();\n }\n\n public isEnabled(): boolean {\n return this.enabled;\n }\n\n private getSide(): WhiteboardSide {\n if (!this.isEnabled())\n return 'bottom';\n\n return this.side;\n }\n\n private update(): void {\n this.player.removeClass('cv-whiteboard-top');\n this.player.removeClass('cv-whiteboard-left');\n this.player.removeClass('cv-whiteboard-right');\n videojs.dom.removeClass(window.document.documentElement, 'cv-whiteboard-html-font-size');\n\n this.player.trigger('resizemenus');\n this.player.trigger('cv-updatecog');\n\n if (!this.isEnabled()) {\n this.dragHandle?.hide();\n return;\n }\n this.dragHandle?.show();\n\n const side = this.getSide();\n if (!this.player.isFullscreen() || side === 'bottom')\n return;\n\n this.player.addClass(`cv-whiteboard-${side}`);\n videojs.dom.addClass(window.document.documentElement, 'cv-whiteboard-html-font-size');\n }\n}\n\nvideojs.registerPlugin('whiteboardModePlugin', WhiteboardModePlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n whiteboardModePlugin(): WhiteboardModePlugin;\n }\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\nconst Plugin = videojs.getPlugin('plugin');\n\ninterface MenuItem {\n id: string | number;\n name: string;\n selected: boolean;\n}\n\ninterface DeferMenusInfo {\n subtitles: MenuItem[];\n qualities: MenuItem[];\n playbackSpeeds: MenuItem[];\n}\n\n/**\n * This plugin is used by the android app to render native controls for the player menu instead\n * of the player rendering the menus itself. This happens by triggering a \n * `cv-defer-menus` event with all the relevant information to render the menus.\n * The android app then uses the player's API to control the player when the user interacts\n * with the menu. - Sha\n */\nclass DeferMenusPlugin extends Plugin {\n constructor(player: VideoJsPlayer) {\n super(player);\n }\n\n public deferMenu(): void {\n const info: DeferMenusInfo = {\n subtitles: this.buildSubtitles(),\n qualities: this.buildQualities(),\n playbackSpeeds: this.buildPlaybackSpeeds()\n };\n this.player.trigger('cv-defer-menus', info);\n }\n\n private buildSubtitles(): MenuItem[] {\n const tracks: MenuItem[] = [];\n let trackSelected = false;\n\n const playerTracks = this.player.textTracks();\n for (let i = 0; i < playerTracks.length; i++) {\n const track = playerTracks[i];\n const selected = track.mode === 'showing';\n\n tracks.unshift({\n id: track.label,\n name: track.label,\n selected\n });\n \n if (selected)\n trackSelected = true;\n }\n\n tracks.push({\n id: null,\n name: 'Off',\n selected: !trackSelected\n });\n\n return tracks;\n }\n\n private buildQualities(): MenuItem[] {\n const qualities: MenuItem[] = [];\n\n const qualityLevels = this.player.qualityLevels();\n\n for (let i = 0; i < qualityLevels.length; i++) {\n const quality = qualityLevels[i];\n qualities.push({\n id: quality.id,\n name: quality.id + 'p',\n selected: quality.enabled\n });\n }\n\n return qualities;\n }\n\n private buildPlaybackSpeeds(): MenuItem[] {\n const currentPlaybackRate = this.player.playbackRate();\n return this.player.options_.playbackRates.map(r => ({\n id: r,\n name: r + 'x' + (r === 1 ? ' (Normal)' : ''),\n selected: currentPlaybackRate === r\n }));\n }\n}\n\nvideojs.registerPlugin('deferMenusPlugin', DeferMenusPlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n deferMenusPlugin(): DeferMenusPlugin;\n }\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport './mute-button.scss';\n\nconst Button = videojs.getComponent('Button');\nconst MUTE_CLASS = 'cv-muted';\n\nexport class MuteButton extends Button {\n public controlText_: string;\n\n constructor(player: VideoJsPlayer) {\n super(player);\n this.update();\n\n this.update = this.update.bind(this);\n player.on('volumechange', this.update);\n player.on('dispose', () => player.off('volumechange', this.update));\n }\n\n public handleClick() {\n this.player_.muted(!this.player_.muted());\n this.update();\n }\n\n public update(): void {\n this.player_.muted()\n ? this.addClass(MUTE_CLASS)\n : this.removeClass(MUTE_CLASS);\n }\n\n public buildCSSClass(): string {\n return 'cv-mute-button cv-muted';\n }\n}\n\nvideojs.registerComponent('muteButton', MuteButton);\n\nMuteButton.prototype.controlText_ = 'Mute';","import videojs, { VideoJsPlayer } from 'video.js';\n\nconst Component = videojs.getComponent('Component');\n\nimport './player-overlay.scss';\n\ninterface PlayerOverlayOptions extends videojs.ComponentOptions {\n onClickHandler: () => void;\n}\n\nexport class PlayerOverlay extends Component {\n private _onClickHandler: () => void;\n\n constructor(player: VideoJsPlayer, options: PlayerOverlayOptions) {\n super(player, options);\n\n this._onClickHandler = options.onClickHandler;\n\n this.bindEventListeners();\n }\n\n public createEl(): Element {\n return videojs.dom.createEl('div', {\n className: 'cv-player-overlay'\n });\n }\n\n public handleClick(event: videojs.EventTarget.Event) {\n if (typeof this._onClickHandler === 'function') {\n event.stopImmediatePropagation();\n this._onClickHandler();\n }\n }\n\n public dispose(): void {\n this.off('click', this.handleClick);\n super.dispose();\n }\n\n private bindEventListeners(): void {\n this.on('click', this.handleClick);\n }\n}\n\nvideojs.registerComponent('playerOverlay', PlayerOverlay);","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { MuteButton } from 'projects/player/components/mute-button/mute-button';\nimport { PlayerOverlay } from 'projects/player/components/player-overlay/player-overlay';\n\nimport './player-mode-plugin.scss';\n\nexport enum PlayerMode {\n Default = 'play',\n Hover = 'hover'\n}\n\nconst Plugin = videojs.getPlugin('plugin');\n\nconst PREVIEW_MODE_CLASS = 'cv-preview-mode';\n\nclass PlayerModePlugin extends Plugin {\n private buttonAdded: boolean = false;\n private mode: PlayerMode = null;\n\n constructor(player: VideoJsPlayer) {\n super(player);\n }\n\n public getMode(): PlayerMode {\n return this.mode;\n }\n\n public setPlayerMode(mode: PlayerMode, onClickHandler?: () => void) {\n const previousMode = this.mode;\n this.mode = mode;\n\n if (mode === PlayerMode.Hover) {\n if (!this.buttonAdded)\n this.addButtons(onClickHandler);\n\n this.player.addClass(PREVIEW_MODE_CLASS);\n this.enableSubtites();\n this.mute();\n this.removeActivityTimeout();\n this.player.trigger('resize');\n return;\n }\n\n if (previousMode !== PlayerMode.Hover)\n return;\n \n this.player.removeClass(PREVIEW_MODE_CLASS);\n this.disableSubtitles();\n this.unmute();\n this.restoreActivityTimeout();\n this.player.trigger('resize');\n }\n\n private addButtons(onClickHandler?: () => void) {\n const muteButton = new MuteButton(this.player);\n const playerOverlay = new PlayerOverlay(this.player, { onClickHandler });\n \n this.player.addChild(muteButton);\n this.player.addChild(playerOverlay);\n\n this.buttonAdded = true;\n }\n\n private enableSubtites(): void {\n // Must ensure that our subtitles have been fetched.\n this.player.dataLoaded(() => this.player.persistSubtitleSettingsPlugin().previewModeSubtitles());\n }\n\n /**\n * We don't actually disable subtitles, we go back to whatever the user's saved preferences were.\n * So that they get subtitles on hover, but then go back to their preferences when they click to play.\n */\n private disableSubtitles(): void {\n // Must ensure that our subtitles have been fetched.\n this.player.dataLoaded(() => this.player.persistSubtitleSettingsPlugin().applyUserPreferences());\n }\n\n private mute(): void {\n this.player.ready(() => {\n this.player.persistVolumePlugin().disable();\n this.player.muted(true);\n });\n }\n\n private unmute(): void {\n this.player.ready(() => {\n this.player.persistVolumePlugin().applyUserPreferences();\n this.player.persistVolumePlugin().enable();\n });\n }\n\n private removeActivityTimeout(): void {\n (this.player as any).cache_.inactivityTimeout = this.player.options_.inactivityTimeout;\n this.player.options_.inactivityTimeout = 0;\n }\n\n private restoreActivityTimeout(): void {\n this.player.options_.inactivityTimeout = (this.player as any).cache_.inactivityTimeout;\n }\n}\n\nvideojs.registerPlugin('playerModePlugin', PlayerModePlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n playerModePlugin(): PlayerModePlugin;\n }\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\nconst Component = videojs.getComponent('Component');\nconst ClickableComponent = videojs.getComponent('ClickableComponent');\n\nimport './favourite-button.scss';\n\nconst HEART_SVG = `\n <svg version=\"1.1\" viewBox=\"0 0 24 24\">\n <path id=\"Heart-Filled\" d=\"m18.833 5.9735c-0.78916-0.95022-1.8839-1.4735-3.0826-1.4735-1.6859 0-2.7532 1.0685-3.3517 1.9648-0.15528 0.2326-0.28738 0.46582-0.39828 0.68529-0.11091-0.21946-0.24297-0.45269-0.39828-0.68529-0.5985-0.89636-1.6658-1.9648-3.3517-1.9648-1.1987 0-2.2935 0.52333-3.0827 1.4735-0.75275 0.90644-1.1673 2.1204-1.1673 3.4183 0 1.4128 0.51978 2.7268 1.6358 4.1353 0.99741 1.2588 2.4323 2.5564 4.0939 4.0589 0.61916 0.5599 1.2594 1.1389 1.9411 1.7718l0.02047 0.01903c0.08837 0.08211 0.19856 0.12313 0.30875 0.12313s0.22038-0.04105 0.30875-0.12313l0.02047-0.01903c0.68166-0.63289 1.3219-1.2119 1.9412-1.7719 1.6615-1.5024 3.0964-2.8 4.0938-4.0588 1.116-1.4085 1.6358-2.7225 1.6358-4.1353 0-1.2979-0.41459-2.5119-1.1674-3.4183z\"/>\n </svg>\n`;\n\nconst HEART_OUTLINE_SVG = `\n <svg version=\"1.1\" viewBox=\"0 0 24 24\">\n <path id=\"Shape\" d=\"m18.959 5.9741c-0.76992-0.92705-1.9357-1.5351-3.1052-1.5351-1.6448 0-2.8808 0.74937-3.4647 1.6238-0.15149 0.22693-0.28074 0.55125-0.38894 0.76537-0.10821-0.21411-0.23718-0.53844-0.38871-0.76537-0.58391-0.87451-1.8205-1.6238-3.4653-1.6238-1.1695 0-2.2376 0.60808-3.0075 1.5351-0.7344 0.88434-1.1388 1.9712-1.1388 3.2374 0 1.3784 0.50711 3.0509 1.5959 4.4251 0.97309 1.2281 2.373 2.4941 3.9941 3.9599 0.60406 0.54625 1.2285 1.1104 1.8936 1.7278l0.01997 0.01934c0.08622 0.08011 0.38931 0.21727 0.49681 0.21727 0.1075 0 0.40992-0.13796 0.49614-0.21804l0.0201-0.0178c0.66504-0.61746 1.2897-1.1824 1.8939-1.7287 1.621-1.4658 3.0209-2.7317 3.994-3.9598 1.0888-1.3742 1.5955-3.0467 1.5955-4.4251 0-1.2663-0.30646-2.3531-1.0409-3.2374zm-5.337 10.688c-0.51948 0.47226-1.0567 0.95549-1.6218 1.4768-0.56507-0.52124-1.101-1.0059-1.6219-1.4769-3.1725-2.8689-5.2684-4.7641-5.2684-7.2556 0-1.0298 0.32333-1.9863 0.91044-2.6933 0.59385-0.71497 1.4183-1.1088 2.3213-1.1088 1.254 0 2.0645 0.81976 2.5237 1.5074 0.41187 0.61679 0.62678 1.2385 0.70006 1.4772 0.06131 0.19978 0.23683 0.33499 0.43482 0.33499s0.37351-0.1352 0.43482-0.33499c0.07329-0.23867 0.28821-0.86044 0.70006-1.4773 0.45914-0.68766 1.2698-1.5074 2.5237-1.5074 0.90309 0 1.7274 0.39377 2.3213 1.1088 0.58714 0.70695 0.91047 1.6634 0.91047 2.6933 0 2.4914-2.1035 4.3783-5.2685 7.2557z\" stroke-width=\".97562\"/>\n </svg>\n`;\n\nclass FavouriteIcon extends Component {\n public createEl(): HTMLSpanElement {\n return Component.prototype.createEl.call(this, 'span', {\n className: 'cv-favourite-button-svg',\n innerHTML: `<span class='cv-favourite-heart'>${HEART_SVG}</span><span class='cv-favourite-outline'>${HEART_OUTLINE_SVG}</span>`\n });\n }\n}\n\ninterface FavouriteButtonOptions extends videojs.ComponentOptions {\n isFavourited: boolean;\n onClick: (isFavourited: boolean) => void;\n}\n\nexport class FavouriteButton extends ClickableComponent {\n public options_: FavouriteButtonOptions;\n public controlText_: string;\n private icon: FavouriteIcon;\n\n private isFavourited: boolean;\n private isHovering: boolean;\n\n constructor(player: VideoJsPlayer, options: FavouriteButtonOptions) {\n super(player, options);\n\n this.isFavourited = options.isFavourited;\n this.renderIcon();\n this.update();\n }\n\n private renderIcon(): void {\n if (this.icon)\n this.removeChild(this.icon);\n\n this.icon = new FavouriteIcon(this.player_);\n this.addChild(this.icon);\n }\n\n public update(): void {\n if (this.isFavourited)\n this.addClass('cv-favourited');\n else\n this.removeClass('cv-favourited');\n }\n\n public createEl(tagName?: string, properties?: any, attributes?: any): HTMLButtonElement {\n tagName = 'button';\n\n properties = {\n innerHTML: '',\n className: 'cv-favourite-button',\n ...properties\n };\n\n // Add attributes for button element\n attributes = {\n // Necessary since the default button type is \"submit\"\n type: 'button',\n ...attributes\n };\n\n const el = Component.prototype.createEl.call(this, tagName, properties, attributes);\n\n this.createControlTextEl(el);\n\n return el;\n }\n\n public handleClick() {\n this.isFavourited = !this.isFavourited;\n\n this.update();\n\n if (this.options_.onClick) {\n this.options_.onClick(this.isFavourited);\n }\n }\n}\n\nFavouriteButton.prototype.controlText_ = 'Favourite';","import videojs from 'video.js';\n\nimport { FavouriteButton } from 'projects/player/plugins/favourite-plugin/components/favourite-button';\n\nconst Plugin = videojs.getPlugin('plugin');\n\nclass FavouritePlugin extends Plugin {\n private initialized: boolean;\n\n public setFavourite(isFavourited: boolean, onClick: (isFavourited: boolean) => void): void {\n if (this.initialized)\n return;\n\n const button = new FavouriteButton(this.player, { isFavourited, onClick });\n this.player.addChild(button);\n\n this.initialized = true;\n }\n}\n\nvideojs.registerPlugin('favouritePlugin', FavouritePlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n favouritePlugin(): FavouritePlugin;\n }\n}","import videojs from 'video.js';\n\nconst Menu = videojs.getComponent('Menu');\n\nconst toTitleCase = function(string: string) {\n if (typeof string !== 'string') {\n return string;\n }\n\n return string.replace(/./, (w: string) => w.toUpperCase());\n};\n\nconst Component = videojs.getComponent('Component');\nconst BaseMenuButton = videojs.getComponent('MenuButton');\n\nclass MenuButton extends BaseMenuButton {\n public hideThreshold_: number;\n public items: videojs.MenuItem[];\n\n /**\n * Direct copy of video.js MenuButton.createMenu() except we're using our own mneu\n * The only reason we're doing this is so we can override handleBlur in Menu\n */\n public createMenu(): videojs.Menu {\n const menu = new Menu(this.player_, { menuButton: this });\n\n this.hideThreshold_ = 0;\n\n if (this.options_.title) {\n const titleEl = videojs.dom.createEl('li', {\n className: 'vjs-menu-title',\n innerHTML: toTitleCase(this.options_.title),\n tabIndex: -1\n });\n\n this.hideThreshold_ += 1;\n\n const titleComponent = new Component(this.player_, { el: titleEl } as any);\n\n menu.addItem(titleComponent as any);\n }\n\n this.items = this.createItems();\n\n if (this.items) {\n for (let i = 0; i < this.items.length; i++) {\n menu.addItem(this.items[i]);\n }\n }\n\n return menu;\n }\n}\n\n/**\n * Functions have to be defined directly onto the prototype because they are used internally by\n * the video.js player. pressButton and unpressButton here ensure that the player controls\n * won't fade while a menu is open.\n */\nconst pressButton = BaseMenuButton.prototype.pressButton;\nBaseMenuButton.prototype.pressButton = function(): void {\n pressButton.call(this);\n\n this.inactivityTimeout = this.player_.cache_.inactivityTimeout;\n this.player_.cache_.inactivityTimeout = 0;\n this.player_.options_.inactivityTimeout = 0;\n};\n\nconst unpressButton = BaseMenuButton.prototype.unpressButton;\nBaseMenuButton.prototype.unpressButton = function(): void {\n unpressButton.call(this);\n\n this.player_.cache_.inactivityTimeout = this.inactivityTimeout;\n this.player_.options_.inactivityTimeout = this.inactivityTimeout;\n this.player_.reportUserActivity();\n};\n\nvideojs.registerComponent('MenuButton', MenuButton);","import videojs from 'video.js';\n\nimport './time-wrapper.scss';\n\nconst Component = videojs.getComponent('Component');\n\nclass TimeWrapper extends Component {\n // eslint-disable-next-line\n public options_: videojs.ComponentOptions;\n\n public buildCSSClass(): string {\n return `cv-time-wrapper ${super.buildCSSClass()}`;\n }\n\n public createEl(tagName?: string, properties?: any, attributes?: any): Element {\n return super.createEl(tagName, {\n ...properties,\n className: this.buildCSSClass()\n }, attributes);\n }\n}\n\nTimeWrapper.prototype.options_ = {\n children: [\n 'currentTimeDisplay',\n 'remainingTimeDisplay'\n ]\n};\n\nvideojs.registerComponent('TimeWrapper', TimeWrapper);","import videojs from 'video.js';\n\nconst BaseSeekBar = videojs.getComponent('SeekBar') as unknown as typeof videojs.SeekBar;\n\n/**\n * Note, this is not the player's default seekbar.\n * You're looking for chapter-seek-bar.ts\n * \n * This is just used to disable play-pause-feedback\n * when the user interacts with any seek bar\n */\nclass SeekBar extends BaseSeekBar {\n private timeoutId: number;\n\n public handleMouseDown(event: videojs.EventTarget.Event): void {\n const preventScrubbingPlugin = this.player_.preventScrubbingPlugin();\n\n if (preventScrubbingPlugin.isEnabled) {\n const isLockedTime = this.getMouseTime(event) > preventScrubbingPlugin.furthestVisitedTime;\n\n if (isLockedTime) {\n return;\n }\n }\n\n (BaseSeekBar.prototype as any).handleMouseDown.call(this, event);\n\n this.player_.addClass('cv-disable-play-pause-feedback');\n }\n\n public handleMouseMove(event: videojs.EventTarget.Event): void {\n (BaseSeekBar.prototype as any).handleMouseMove.call(this, event);\n // We call update here so that the UI feels responsive as the mouse or touch input moves\n (this as any).update();\n }\n\n /**\n * This is basically forcing us to use `this.player_.currentTime()\n * instead of this.player_.getCache().currentTime. Which makes for a smoother\n * user experience.\n * \n * NOTE: If we ever want to do live streaming this will need to change\n * I recommend looking at getPercent() in SeekBar in videojs\n */\n public getPercent(): number {\n const time = this.player_.currentTime();\n const percent = time / this.player_.duration();\n return percent >= 1 ? 1 : percent;\n }\n\n public handleMouseUp(event: videojs.EventTarget.Event): void {\n (BaseSeekBar.prototype as any).handleMouseUp.call(this, event);\n\n if (this.timeoutId)\n window.clearTimeout(this.timeoutId);\n\n this.timeoutId = window.setTimeout(() => {\n this.player_.removeClass('cv-disable-play-pause-feedback');\n }, 500);\n }\n\n private clamp(num: number, min: number, max: number) {\n return Math.min(Math.max(num, min), max);\n }\n\n private getMouseTime(event: videojs.EventTarget.Event): number {\n const seekBarPoint = this.clamp(BaseSeekBar.prototype.calculateDistance.call(this, event).x, 0, 1);\n return seekBarPoint * this.player_.duration();\n }\n}\n\nvideojs.registerComponent('SeekBar', SeekBar);","import videojs from 'video.js';\n\nconst Component = videojs.getComponent('Component');\n\nexport class ChapterBarLoadProgress extends Component {\n // eslint-disable-next-line\n private el_: HTMLElement;\n\n public buildCSSClass(): string {\n return `cv-chapter-bar-load-progress ${super.buildCSSClass()}`;\n }\n\n public createEl(tagName?: string, properties?: any, attributes?: any): Element {\n return super.createEl(tagName, {\n ...properties,\n className: this.buildCSSClass()\n }, attributes);\n }\n\n public update(width: number): void {\n this.el_.style.width = (width * 100) + '%';\n }\n}","import videojs from 'video.js';\n\nconst Component = videojs.getComponent('Component');\n\nexport class ChapterBarPlayProgress extends Component {\n // eslint-disable-next-line\n private el_: HTMLElement;\n\n public buildCSSClass(): string {\n return `cv-chapter-bar-play-progress ${super.buildCSSClass()}`;\n }\n\n public createEl(tagName?: string, properties?: any, attributes?: any): Element {\n return super.createEl(tagName, {\n ...properties,\n className: this.buildCSSClass()\n }, attributes);\n }\n\n public update(width: number): void {\n if (width > 0 && width < 1)\n this.addClass('cv-current');\n else\n this.removeClass('cv-current');\n\n this.el_.style.width = (width * 100) + '%';\n }\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { ChapterBarLoadProgress } from './chapter-bar-load-progress';\nimport { ChapterBarPlayProgress } from './chapter-bar-play-progress';\n\nconst Component = videojs.getComponent('Component');\n\ninterface ChapterItemOptions extends videojs.ComponentOptions {\n startTime: number;\n endTime: number;\n}\n\nexport class ChapterBarItem extends Component {\n // eslint-disable-next-line\n private duration_: number;\n // eslint-disable-next-line\n private el_: HTMLElement;\n // eslint-disable-next-line\n public options_: ChapterItemOptions;\n\n private playProgress: ChapterBarPlayProgress;\n private loadProgress: ChapterBarLoadProgress;\n\n constructor(player: VideoJsPlayer, options: ChapterItemOptions) {\n super(player, options);\n\n this.playProgress = new ChapterBarPlayProgress(this.player_);\n this.addChild(this.playProgress);\n\n this.loadProgress = new ChapterBarLoadProgress(this.player_);\n this.addChild(this.loadProgress);\n\n this.update();\n this.updateBuffered(0);\n }\n\n public buildCSSClass(): string {\n return `cv-chapter-bar-item ${super.buildCSSClass()}`;\n }\n\n public createEl(tagName?: string, properties?: any, attributes?: any): Element {\n return super.createEl(tagName, {\n ...properties,\n className: this.buildCSSClass()\n }, attributes);\n }\n\n /**\n * Get the value of current time but allows for smooth scrubbing,\n * when player can't keep up.\n *\n * @return {number}\n * The current time value to display\n *\n * @private\n */\n private getCurrentTime(): number {\n return (this.player_.scrubbing()) ?\n this.player_.getCache().currentTime :\n this.player_.currentTime();\n }\n\n /**\n * Update is called by ChapterBarItems on each item each time\n * ChapterSeekBar updates, which is done once per animation frame\n * by SeekBar which ChapterSeekBar extends\n */\n public update(): void {\n const duration = this.player_.duration() || 3600; // Sane Default to ensure we have values while loading\n const chapterDuration = this.options_.endTime - this.options_.startTime;\n\n /**\n * Set chapter width. We only need to do this when the duration changes\n */\n if (duration !== this.duration_) {\n const width = chapterDuration / duration;\n this.el_.style.width = (width * 100) + '%';\n\n const start = this.options_.startTime / duration;\n this.el_.style.left = (start * 100) + '%';\n\n this.duration_ = duration;\n }\n\n /**\n * Set play progress width\n */\n const progress = this.getCurrentTime();\n if (progress < this.options_.startTime)\n this.playProgress.update(0);\n else if (progress > this.options_.endTime)\n this.playProgress.update(1);\n else\n this.playProgress.update((progress - this.options_.startTime) / chapterDuration);\n }\n\n public updateBuffered(bufferEnd: number): void {\n const chapterDuration = this.options_.endTime - this.options_.startTime;\n\n if (bufferEnd < this.options_.startTime)\n this.loadProgress.update(0);\n else if (bufferEnd > this.options_.endTime)\n this.loadProgress.update(1);\n else\n this.loadProgress.update((bufferEnd - this.options_.startTime) / chapterDuration);\n }\n}\n\n","import videojs from 'video.js';\n\nimport { getBufferedEnd } from 'projects/player/utils/getBufferedEnd';\n\nimport { ChapterBarItem } from './chapter-bar-item';\n\nimport './chapter-bar-items.scss';\n\nconst Component = videojs.getComponent('Component');\n\nexport class ChapterBarItems extends Component {\n public buildCSSClass(): string {\n return `cv-chapter-bar-items ${super.buildCSSClass()}`;\n }\n\n public createEl(tagName?: string, properties?: any, attributes?: any): Element {\n return super.createEl(tagName, {\n ...properties,\n className: this.buildCSSClass()\n }, attributes);\n }\n\n public update(): void {\n this.children_.forEach((c: ChapterBarItem) => {\n c.update();\n });\n }\n\n public updateBuffered(): void {\n this.children_.forEach((c: ChapterBarItem) => {\n c.updateBuffered(getBufferedEnd(this.player_));\n });\n }\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { ChapterBarItem } from 'projects/player/components/chapter-bar-items/chapter-bar-item';\nimport { ChapterBarItems } from 'projects/player/components/chapter-bar-items/chapter-bar-items';\nimport { TrackHelper } from 'projects/player/utils/track-helper';\n\nconst SeekBar = videojs.getComponent('SeekBar') as unknown as typeof videojs.SeekBar;\n\ninterface SeekBarOptions extends videojs.SliderOptions {\n ignoreChapters?: boolean;\n}\n\nclass ChapterSeekBar extends SeekBar {\n public options_: SeekBarOptions;\n\n // eslint-disable-next-line\n private track_: TextTrack;\n private chapterBarItems: ChapterBarItems;\n\n constructor(player: VideoJsPlayer, options: SeekBarOptions) {\n super(player, options);\n\n this.onDurationChange = this.onDurationChange.bind(this);\n this.createChapterItems = this.createChapterItems.bind(this);\n this.updateBuffered = this.updateBuffered.bind(this);\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n TrackHelper.useChapters(this.player_, this.createChapterItems);\n\n this.player_.on('durationchange', this.onDurationChange);\n this.player_.on('progress', this.updateBuffered);\n\n this.createChapterItems();\n this.update();\n }\n\n public dispose(): void {\n this.player_.off('durationchange', this.onDurationChange);\n this.player_.off('progress', this.updateBuffered);\n super.dispose();\n }\n\n public createEl(): HTMLDivElement {\n return videojs.dom.createEl('div', {\n className: 'vjs-progress-holder cv-chapter-seek-bar'\n }, {\n 'aria-label': this.localize('Progress Bar'),\n 'role': 'progressbar'\n }) as HTMLDivElement;\n }\n\n private onDurationChange(): void {\n this.createChapterItems();\n this.update();\n }\n\n public update(): number {\n const percent = super.update();\n\n if (this.chapterBarItems)\n this.chapterBarItems.update();\n\n return percent;\n }\n\n public updateBuffered(): void {\n this.chapterBarItems.updateBuffered();\n }\n\n private bindUpdateListener(track: TextTrack): void {\n const onCueChange = () => {\n this.createChapterItems();\n this.updateBuffered();\n };\n track.addEventListener('cv:cuechange', onCueChange);\n this.player_.one('dispose', () => track.removeEventListener('cv:cuechange', onCueChange));\n }\n\n private createChapterItems(track?: TextTrack): void {\n if (track) {\n if (!this.track_)\n this.bindUpdateListener(track);\n\n this.track_ = track;\n }\n\n const chapterBarItems = new ChapterBarItems(this.player_);\n\n if (this.track_?.cues?.length && !this.options_.ignoreChapters) {\n for (let i = 0; i < this.track_.cues.length; i++) {\n const cue = this.track_.cues[i];\n\n const startTime = cue.startTime;\n let endTime = cue.endTime;\n\n /**\n * If the last cue isn't the end of the video\n * we make it so that it is.\n */\n const duration = this.player_.duration();\n if (duration) {\n if (i === this.track_.cues.length - 1) {\n if (cue.endTime < this.player_.duration())\n endTime = this.player_.duration();\n }\n\n if (endTime > duration) {\n endTime = duration;\n }\n }\n\n const ci = new ChapterBarItem(this.player_, {\n startTime,\n endTime\n });\n\n chapterBarItems.addChild(ci);\n\n if (duration && endTime === duration)\n break;\n }\n } else {\n chapterBarItems.addChild(new ChapterBarItem(this.player_, {\n startTime: 0, endTime: this.player_.duration() || 3600 // Sane Default to ensure we have values while loading\n }));\n }\n\n if (this.chapterBarItems)\n this.removeChild(this.chapterBarItems);\n\n this.chapterBarItems = chapterBarItems;\n this.addChild(this.chapterBarItems);\n }\n}\n\n/**\n * In order for seekbar to work, we have to have a child component with\n * a bar name. For now we're just setting display: none;\n * on the playProgressBar with our css\n */\nChapterSeekBar.prototype.options_ = {\n children: ['playProgressBar'],\n barName: 'playProgressBar'\n};\n\n// MouseTimeDisplay tooltips should not be added to a player on mobile devices\nif (!videojs.browser.IS_IOS && !videojs.browser.IS_ANDROID) {\n ChapterSeekBar.prototype.options_.children.splice(1, 0, 'mouseTimeDisplay');\n}\n\nvideojs.registerComponent('ChapterSeekBar', ChapterSeekBar);","import videojs from 'video.js';\n\nimport './progress-control.scss';\n\nconst BaseProgressControl = videojs.getComponent('ProgressControl') as unknown as typeof videojs.ProgressControl;\n\nconst BASE_SEEK_BAR_NAME = 'seekBar';\n\nexport class ProgressControl extends BaseProgressControl {\n private seekBarName_: string = BASE_SEEK_BAR_NAME;\n\n public setSeekBarName(name: string): void {\n this.seekBarName_ = name;\n }\n\n public getChild(name: string): videojs.Component | undefined {\n if (name?.toLowerCase() === BASE_SEEK_BAR_NAME.toLowerCase())\n name = this.seekBarName_;\n\n return super.getChild(name);\n }\n}\n\n/**\n * Remove 'seekBar' as a child.\n * Instead each player is responsible for adding\n * its own seekBar.\n */\nProgressControl.prototype.options_ = {\n children: []\n};\n\nvideojs.registerComponent('ProgressControl', ProgressControl);","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { formatTime } from 'projects/player/utils/formatTime';\nimport { TrackHelper } from 'projects/player/utils/track-helper';\n\nimport './time-tooltip.scss';\n\nconst BaseTimeToolTip = videojs.getComponent('TimeTooltip');\n\nexport class TimeTooltip extends BaseTimeToolTip {\n // eslint-disable-next-line\n private track_: TextTrack;\n // eslint-disable-next-line\n private time_: Element;\n // eslint-disable-next-line\n private chapter_: Element;\n private hasCustomChapterText: boolean = false;\n\n constructor(player: VideoJsPlayer, options?: videojs.ComponentOptions) {\n super(player, options);\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n TrackHelper.useChapters(this.player_, (track: TextTrack) => {\n this.track_ = track;\n });\n }\n\n public createEl(): HTMLDivElement {\n const el = super.createEl();\n\n this.chapter_ = videojs.dom.createEl('div');\n el.appendChild(this.chapter_);\n\n this.time_ = videojs.dom.createEl('div');\n el.appendChild(this.time_);\n\n return el;\n }\n\n public updateTime(time: number): void {\n const duration = this.player_.duration();\n videojs.dom.textContent(this.time_, formatTime(time, duration));\n\n if (!this.track_ || this.hasCustomChapterText)\n return;\n \n for (let i = 0; i < this.track_.cues.length; i++) {\n const cue = this.track_.cues[i];\n\n /* The last chapter can not have an endTime */\n const endTime = cue.endTime || duration;\n \n if (cue.startTime <= time && endTime >= time) {\n videojs.dom.textContent(this.chapter_, (cue as any).text);\n return;\n }\n }\n videojs.dom.textContent(this.chapter_, '');\n }\n \n public clearChapterContent() {\n videojs.dom.textContent(this.chapter_, '');\n }\n\n public updateText(text: string): void {\n videojs.dom.textContent(this.time_, text);\n }\n\n public setCustomChapterText(text?: string): void {\n this.hasCustomChapterText = !!text;\n videojs.dom.textContent(this.chapter_, text ?? '');\n }\n}\n\nvideojs.registerComponent('TimeTooltip', TimeTooltip);\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport './thumbnail-display.scss';\n\ninterface Setting {\n src: string;\n w: number;\n h: number;\n x: number;\n y: number;\n}\n\nconst Component = videojs.getComponent('Component');\n\ninterface ThumbnailDisplayOptions extends videojs.ComponentOptions {\n scaleFactor?: number;\n}\n\nexport class ThumbnailDisplay extends Component {\n public options_: ThumbnailDisplayOptions;\n \n private img_: HTMLImageElement;\n // eslint-disable-next-line\n private el_: HTMLDivElement;\n // eslint-disable-next-line\n private track_: TextTrack;\n\n constructor(player: VideoJsPlayer, options?: ThumbnailDisplayOptions) {\n super(player, options);\n }\n\n public setTrack(track: TextTrack): void {\n this.track_ = track;\n }\n\n public createEl(): Element {\n const el = super.createEl('div', {\n className: 'cv-thumbnail-display'\n });\n\n this.img_ = videojs.dom.createEl('img');\n el.appendChild(this.img_);\n\n return el;\n }\n\n private enable(): void {\n this.addClass('cv-thumbnail-display-enabled');\n }\n\n private disable(): void {\n this.removeClass('cv-thumbnail-display-enabled');\n }\n\n private parseImageLink(imageLocation: string): Setting {\n const hashIndex = imageLocation.indexOf('#');\n\n if (hashIndex === -1) {\n return {\n src: imageLocation,\n w: 0, h: 0, x: 0, y: 0\n };\n }\n\n const lsrc = imageLocation.substr(0, hashIndex);\n const hashString = imageLocation.substr(hashIndex + 1);\n\n if (hashString.substr(0, 5) !== 'xywh=') {\n return {\n src: imageLocation,\n w: 0, h: 0, x: 0, y: 0\n };\n }\n\n const scale = this.getScale();\n\n const data = hashString.substr(5).split(',');\n return {\n src: lsrc,\n w: parseInt(data[2]) * scale,\n h: parseInt(data[3]) * scale,\n x: parseInt(data[0]) * scale,\n y: parseInt(data[1]) * scale\n };\n }\n\n private getScale(): number {\n let scale = this.options_.scaleFactor;\n const side = this.player_.whiteboardModePlugin().side;\n\n if (this.player_.isFullscreen() && side !== 'bottom') {\n scale = scale * 2;\n }\n\n return scale;\n }\n\n public update(time: number): void {\n if (!this.track_?.cues?.length)\n return;\n\n /**\n * Estimated time in video based on mouse position\n */\n const mouseTime = time;\n\n let imageSettings: Setting;\n\n /**\n * Find the corresponding image for the estimated time\n */\n let i = 0;\n while (i < this.track_.cues.length) {\n const cue = this.track_.cues[i];\n\n if (cue.startTime <= mouseTime && cue.endTime >= mouseTime) {\n imageSettings = this.parseImageLink((cue as any).text);\n break;\n }\n\n i++;\n }\n\n /**\n * Hide if we don't have an image\n */\n if (!imageSettings?.src) {\n this.disable();\n return;\n }\n\n this.enable();\n\n const { src, w, h, x, y } = imageSettings;\n\n const scale = this.getScale();\n\n this.img_.src = src;\n this.img_.style.left = -(x) + 'px';\n this.img_.style.top = -(y) + 'px';\n\n this.img_.style.transformOrigin = '0 0';\n this.img_.style.transform = `scale(${scale})`;\n \n\n this.el_.style.width = w + 'px';\n this.el_.style.height = h + 'px';\n }\n}\n\nThumbnailDisplay.prototype.options_ = {\n scaleFactor: 1\n};\n\nvideojs.registerComponent('ThumbnailDisplay', ThumbnailDisplay);\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { ProgressControl } from 'projects/player/components/progress-control/progress-control';\nimport { ThumbnailDisplay } from 'projects/player/components/thumbnail-display/thumbnail-display';\nimport { TimeTooltip } from 'projects/player/components/time-tooltip/time-tooltip';\nimport { PreventScrubbingTooltip } from 'projects/player/plugins/prevent-scrubbing-plugin/components/prevent-scrubbing-tooltip';\nimport { COMPONENT_PREVENT_SCRUBBING_TOOLTIP, MOUSE_TIME_DURATION } from 'projects/player/plugins/prevent-scrubbing-plugin/utils/prevent-scrubbing-helper';\nimport { debounce } from 'projects/player/utils/fn';\nimport { TrackHelper } from 'projects/player/utils/track-helper';\n\nimport './mouse-time-display.scss';\n\nimport 'projects/player/components/time-tooltip/time-tooltip';\nimport 'projects/player/components/thumbnail-display/thumbnail-display';\n\nconst BaseMouseTimeDisplay = videojs.getComponent('MouseTimeDisplay');\n\nconst MOUSE_TIME_FORCE_SHOW_CLASS = 'cv-mouse-time-display-force-show';\n\nexport class MouseTimeDisplay extends BaseMouseTimeDisplay {\n // eslint-disable-next-line\n private el_: HTMLDivElement;\n\n constructor(player: VideoJsPlayer, options: videojs.ComponentOptions) {\n super(player, options);\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n TrackHelper.useMetadataTrack(this.player_, 'thumbnails', (track: TextTrack) => {\n (this.getChild('ThumbnailDisplay') as ThumbnailDisplay).setTrack(track);\n });\n\n this.update = this.update.bind(this);\n this.player_.on('durationchange', this.update);\n this.player_.one('dispose', () => {\n this.player_.off('durationchange', this.update);\n });\n }\n\n public update(seekBarRect: ClientRect, seekBarPoint: number): void {\n this.requestAnimationFrame(() => {\n /**\n * Estimated time in video based on mouse position\n */\n const tooltip = (this.getChild('TimeTooltip') as TimeTooltip);\n const thumbnailDisplay = (this.getChild('ThumbnailDisplay') as ThumbnailDisplay);\n \n const mouseTime = seekBarPoint * this.player_.duration();\n const preventScrubbingPlugin = this.player_.preventScrubbingPlugin();\n const farLeftPreventScrubbingTooltip = (this.player_.controlBar.getChild('progressControl') as ProgressControl)\n .getChild(COMPONENT_PREVENT_SCRUBBING_TOOLTIP) as PreventScrubbingTooltip;\n \n let isLockerEnabled = false;\n \n if (preventScrubbingPlugin.isEnabled) {\n isLockerEnabled = mouseTime > preventScrubbingPlugin.furthestVisitedTime;\n }\n\n if (isLockerEnabled) {\n this.hide();\n farLeftPreventScrubbingTooltip.show();\n debounce(farLeftPreventScrubbingTooltip.hide, MOUSE_TIME_DURATION, false, farLeftPreventScrubbingTooltip)();\n } else {\n this.show();\n\n if (farLeftPreventScrubbingTooltip) {\n farLeftPreventScrubbingTooltip.hide(true);\n }\n\n thumbnailDisplay.update(mouseTime);\n tooltip.updateTime(mouseTime);\n }\n\n const rect = this.el_.getBoundingClientRect();\n\n this.el_.style.marginLeft = -(rect.width / 2) + 'px';\n\n const left = seekBarRect.width * seekBarPoint;\n\n if (left < (rect.width / 2)) {\n this.el_.style.left = (rect.width / 2) + 'px';\n } else if (left > (seekBarRect.width - (rect.width / 2))) {\n this.el_.style.left = (seekBarRect.width - (rect.width / 2)) + 'px';\n } else {\n this.el_.style.left = (seekBarRect.width * seekBarPoint) + 'px';\n }\n });\n }\n\n public forceShow(): void {\n this.addClass(MOUSE_TIME_FORCE_SHOW_CLASS);\n }\n \n public removeForceShow(): void {\n this.removeClass(MOUSE_TIME_FORCE_SHOW_CLASS);\n }\n}\n\nMouseTimeDisplay.prototype.options_ = {\n children: [\n 'ThumbnailDisplay',\n 'TimeTooltip'\n ]\n};\n\nvideojs.registerComponent('MouseTimeDisplay', MouseTimeDisplay);\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { ThumbnailDisplay } from 'projects/player/components/thumbnail-display/thumbnail-display';\nimport { formatTime } from 'projects/player/utils/formatTime';\nimport { TrackHelper } from 'projects/player/utils/track-helper';\n\nimport './chapter-menu-item.scss';\n\nconst ChaptersTrackMenuItem = videojs.getComponent('ChaptersTrackMenuItem');\n\nexport class ChapterMenuItem extends ChaptersTrackMenuItem {\n // eslint-disable-next-line\n public options_: videojs.ChaptersTrackMenuItemOptions;\n private nonIconControl: boolean = false;\n private thumbnailDisplay: ThumbnailDisplay;\n\n constructor(player: VideoJsPlayer, options?: videojs.ChaptersTrackMenuItemOptions) {\n super(player, options);\n\n this.thumbnailDisplay = new ThumbnailDisplay(this.player_, {\n scaleFactor: 0.5\n });\n this.el().insertBefore(this.thumbnailDisplay.el(), this.el().firstChild);\n\n // eslint-disable-next-line react-hooks/rules-of-hooks\n TrackHelper.useMetadataTrack(this.player_, 'thumbnails', (track: TextTrack) => {\n this.addClass('cv-has-thumbnails');\n this.thumbnailDisplay.setTrack(track);\n this.thumbnailDisplay.update(this.options_.cue.startTime);\n });\n }\n\n public update(): void {\n /**\n * This is to fix a bug with the video.js ChaptersTrackMenuItem\n * not unbinding update when it's disposed of\n */\n if (!this.player_)\n return;\n\n (ChaptersTrackMenuItem.prototype as any).update.call(this);\n }\n\n public buildCSSClass(): string {\n return 'vjs-menu-item cv-chapter-menu-item';\n }\n\n public createEl(type: string, props?: any, attrs?: any): HTMLLIElement {\n // The control is textual, not just an icon\n this.nonIconControl = true;\n\n return super.createEl('li', Object.assign({\n className: this.buildCSSClass(),\n innerHTML: this.getInnerHTML(),\n tabIndex: -1\n }, props), attrs) as HTMLLIElement;\n }\n\n private getInnerHTML(): string {\n const duration = this.player_.duration();\n return (\n '<span class=\"vjs-menu-item-text cv-chapter-menu-item-text\">'\n + `<p>${this.localize(this.options_.label)}</p>`\n + `<p>(${formatTime(this.options_.cue.startTime, duration)})</p>`\n + '</span>'\n );\n }\n}\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { CollapsibleComponent } from 'projects/player/interfaces/CollapsibleComponent';\n\nimport { ChapterMenuItem } from './chapter-menu-item';\n\nimport './chapters-button.scss';\n\nconst BaseChaptersButton = videojs.getComponent('ChaptersButton') as unknown as typeof videojs.ChaptersButton;\n\nclass ChaptersButton extends BaseChaptersButton implements CollapsibleComponent {\n // eslint-disable-next-line\n private track_: videojs.TextTrack;\n\n constructor(player: VideoJsPlayer, options?: videojs.TrackButtonOptions, ready?: videojs.Component.ReadyCallback) {\n super(player, options, ready);\n\n this.update = this.update.bind(this);\n this.player_.on('cv-whiteboard-change', this.update);\n this.player_.on('fullscreenchange', this.update);\n\n this.player_.on('dispose', () => {\n this.player_.off('cv-whiteboard-change', this.update);\n this.player_.off('fullscreenchange', this.update);\n });\n }\n\n public buildCSSClass(): string {\n return `cv-chapters-button ${super.buildCSSClass()}`;\n }\n\n public buildWrapperCSSClass() {\n return `cv-menu-big ${super.buildWrapperCSSClass()}`;\n }\n\n public createItems(): videojs.TextTrackMenuItem[] {\n const items: videojs.TextTrackMenuItem[] = [];\n\n if (!this.track_) {\n return items;\n }\n\n const cues = this.track_.cues;\n\n if (!cues) {\n return items;\n }\n\n for (let i = 0, l = cues.length; i < l; i++) {\n const cue = cues[i];\n const mi = new ChapterMenuItem(this.player_, { track: this.track_, cue });\n\n items.push(mi as unknown as videojs.TextTrackMenuItem);\n }\n\n return items;\n }\n\n public setTrack(track: videojs.TextTrack): void {\n super.setTrack(track);\n\n if (this.track_ && this.track_.kind === 'chapters') {\n track.one('loadeddata', this.update);\n const onCueChange = () => {\n this.update();\n this.player_.trigger('resizemenus');\n };\n track.on('cv:cuechange', onCueChange);\n this.player_.one('dispose', () => track.off('cv:cueupdate', onCueChange));\n }\n }\n\n public update(event?: videojs.EventTarget.Event): void {\n super.update(event);\n }\n\n /**\n * CollapsibileComponent interface implementation\n * from here onward\n */\n public alwaysCollapsed: boolean = false;\n public isCollapsed: boolean = false;\n public isCollabsible: boolean = true;\n\n public getCollabsibleName(): string {\n return 'Chapters';\n }\n\n public getCollabsibleValue(): string {\n const cue = this.track_.activeCues[0];\n\n return cue?.text || '';\n }\n\n public showInCollabsibleMenu(): boolean {\n if (!this.track_) {\n return false;\n }\n\n const cues = this.track_.cues;\n\n if (!cues || !cues.length) {\n return false;\n }\n\n return true;\n }\n\n public showCollapsibleMenu(): void {\n this.handleClick(null);\n }\n}\n\nvideojs.registerComponent('ChaptersButton', ChaptersButton);\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nconst BaseOffTextTrackMenuItem = videojs.getComponent('OffTextTrackMenuItem');\n\nclass OffTextTrackMenuItem extends BaseOffTextTrackMenuItem {\n constructor(player: VideoJsPlayer, options: any) {\n options.track = {\n player,\n kind: options.kind,\n kinds: options.kinds,\n default: false,\n // set to 'hidden' instead of 'disabled' for our transcription\n mode: 'hidden'\n };\n\n if (!options.kinds) {\n options.kinds = [options.kind];\n }\n\n if (options.label) {\n options.track.label = options.label;\n } else {\n options.track.label = options.kinds.join(' and ') + ' off';\n }\n\n options.selectable = true;\n options.multiSelectable = false;\n\n super(player, options);\n }\n\n public handleClick(event: any): void {\n (BaseOffTextTrackMenuItem.prototype as any).handleClick.call(this, event);\n const tracks = this.player_.textTracks();\n // we set the subtitles to hidden instead of disabled so the cueChange event would be triggered\n for (let i = 0; i < tracks.length; i++) {\n const track = tracks[i];\n if (track.kind === 'subtitles') {\n track.mode = 'hidden';\n }\n }\n\n this.player_.trigger('cv:languageselected');\n }\n\n public createEl(tag: string, props: any, attrs: any): Element {\n return super.createEl('li', {\n className: 'vjs-menu-item',\n tabIndex: -1,\n ...props,\n\n /**\n * This function exists just to override the \"off\" text\n */\n innerHTML: `<span class=\"vjs-menu-item-text\">Off</span>`\n }, attrs);\n }\n}\n\nvideojs.registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem);","import videojs from 'video.js';\n\nimport './off-text-track-menu-item';\n\nconst BaseTextTrackButton = videojs.getComponent('TextTrackButton');\nconst TextTrackMenuItem = videojs.getComponent('TextTrackMenuItem');\nconst OffTextTrackMenuItem = videojs.getComponent('OffTextTrackMenuItem');\n\nclass TextTrackButton extends BaseTextTrackButton {\n /**\n * This entire function is a direct vopy of createItems()\n * in `text-track-button.js` from video.js. We have to\n * override this to allow us to use our own OffTextTrackMenuItem\n */\n public createItems(items: any[] = [], MenuItemType: any = TextTrackMenuItem): any[] {\n // Label is an override for the [track] off label\n // USed to localise captions/subtitles\n let label;\n\n if ((this as any).label_) {\n label = `${(this as any).label_} off`;\n }\n // Add an OFF menu item to turn all tracks off\n items.push(new OffTextTrackMenuItem(this.player_, {\n kinds: (this as any).kinds_,\n kind: (this as any).kind_,\n label\n } as any));\n\n (this as any).hideThreshold_ += 1;\n\n const tracks = this.player_.textTracks();\n\n if (!Array.isArray((this as any).kinds_)) {\n (this as any).kinds_ = [(this as any).kind_];\n }\n\n for (let i = 0; i < tracks.length; i++) {\n const track = tracks[i];\n\n // only add tracks that are of an appropriate kind and have a label\n if ((this as any).kinds_.indexOf(track.kind) > -1) {\n const item = new MenuItemType(this.player_, {\n track,\n kinds: (this as any).kinds_,\n kind: (this as any).kind_,\n // MenuItem is selectable\n selectable: true,\n // MenuItem is NOT multiSelectable (i.e. only one can be marked \"selected\" at a time)\n multiSelectable: false\n });\n\n item.addClass(`vjs-${track.kind}-menu-item`);\n items.push(item);\n }\n }\n\n // re-calculate menu position when track items all added\n this.player().trigger('resizemenus');\n\n return items;\n }\n}\n\nvideojs.registerComponent('TextTrackButton', TextTrackButton);","import videojs from 'video.js';\n\nconst SubCapsMenuItem = videojs.getComponent('SubsCapsMenuItem');\n\nexport class CustomSubCapsMenuItem extends SubCapsMenuItem {\n public handleClick(event: any): void {\n (SubCapsMenuItem.prototype as any).handleClick.call(this, event);\n const tracks = this.player_.textTracks();\n // we set the subtitles to hidden instead of disabled so the cueChange event would be triggered\n for (let i = 0; i < tracks.length; i++) {\n const track = tracks[i];\n if (track.kind === 'subtitles' && track.mode === 'disabled') {\n track.mode = 'hidden';\n }\n }\n\n this.player_.trigger('cv:languageselected');\n }\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { CollapsibleComponent } from 'projects/player/interfaces/CollapsibleComponent';\nimport { TrackHelper } from 'projects/player/utils/track-helper';\n\nconst TextTrackMenuItem = videojs.getComponent('TextTrackMenuItem');\n\nexport class SubtitleSearchMenuItem extends TextTrackMenuItem {\n constructor(player: VideoJsPlayer) {\n const options: any = {};\n\n options.track = <any>{\n player,\n kind: 'subtitle',\n label: 'Search Captions',\n selectable: false,\n default: false,\n mode: 'disabled'\n };\n options.selectable = false;\n options.name = 'SubtitleSearchMenuItem';\n\n super(player, options);\n this.addClass('vjs-texttrack-settings');\n this.addClass('cv-subtitle-search-menu-item');\n this.controlText(', opens subtitle search');\n\n /**\n * Will hide or show the button if we have subtitles selected or not\n */\n this.toggleEnabled = this.toggleEnabled.bind(this);\n const tracks = this.player_.textTracks();\n tracks.addEventListener('selectedlanguagechange', this.toggleEnabled);\n this.player_.one('dispose', () => {\n tracks.removeEventListener('selectedlanguagechange', this.toggleEnabled);\n });\n\n /**\n * Fire this immediately to hide if there are no subtitles selected\n * on load\n */\n this.toggleEnabled();\n }\n\n private toggleEnabled(): void {\n if (!this.player_)\n return;\n\n const track = TrackHelper.getCurrentTextTrack(this.player_);\n\n if (!track) {\n this.addClass('vjs-disabled');\n return;\n }\n\n if (!track.cues?.length) {\n this.bindTrackEvents(track);\n this.addClass('vjs-disabled');\n } else {\n this.removeClass('vjs-disabled');\n }\n }\n\n private bindTrackEvents(track: TextTrack): void {\n /**\n * Because theoretically bindTrackEvents could be called multiple times\n * if a track has no cues. We unbind any listners on this event before adding.\n */\n track.removeEventListener('loadeddata', this.toggleEnabled);\n\n track.addEventListener('loadeddata', this.toggleEnabled);\n this.player_.one('dispose', () => {\n track.removeEventListener('loadeddata', this.toggleEnabled);\n });\n }\n\n public handleClick(): void {\n const track = TrackHelper.getCurrentTextTrack(this.player_);\n\n if (!track?.cues?.length)\n return;\n\n /**\n * The MenuItem handle click and then the corresponding blur\n * event have to fire, otherwise the below line will not run\n * so we execute our click handle in the next frame\n */\n this.requestAnimationFrame(() => {\n const subtitleSizeButton = this.player_\n .getChild('collapserator')\n .getChild('subtitleSearchButton') as CollapsibleComponent;\n\n subtitleSizeButton.showCollapsibleMenu();\n });\n }\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { CollapsibleComponent } from 'projects/player/interfaces/CollapsibleComponent';\n\nconst TextTrackMenuItem = videojs.getComponent('TextTrackMenuItem');\n\nexport class SubtitleSizeMenuItem extends TextTrackMenuItem {\n constructor(player: VideoJsPlayer) {\n const options: any = {};\n\n options.track = <any>{\n player,\n kind: 'subtitle',\n label: 'Caption Text Size',\n selectable: false,\n default: false,\n mode: 'disabled'\n };\n options.selectable = false;\n options.name = 'SubtitleSizeMenuItem';\n\n super(player, options);\n this.addClass('vjs-texttrack-settings');\n this.addClass('cv-divider-after-menu-item');\n this.addClass('cv-subtitle-size-menu-item');\n this.controlText(', opens subtitle size settings');\n }\n\n public handleClick(): void {\n /**\n * The MenuItem handle click and then the corresponding blur\n * event have to fire, otherwise the below line will not run\n * so we execute our click handle in the next frame\n */\n this.requestAnimationFrame(() => {\n const subtitleSizeButton = this.player_\n .getChild('collapserator')\n .getChild('subtitleSizeButton') as CollapsibleComponent;\n\n subtitleSizeButton.showCollapsibleMenu();\n });\n }\n}","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { MIN_WIDTH_WITH_TRANSCRIPT } from 'projects/player/plugins/transcript-plugin/transcript-plugin';\n\nimport './toggle-transcript-menu-item.scss';\n\nconst TextTrackMenuItem = videojs.getComponent('TextTrackMenuItem');\n\nexport class ToggleTranscriptMenuItem extends TextTrackMenuItem {\n private toggleEl: Element;\n private transcriptOn: boolean;\n private item: Element;\n\n /**\n * Because we want to bind our listener in createEl\n * and createEl runs in super. We store if we've bounud\n * our handler, so we only call bind once and \n * the call to removeEventListener will still work\n */\n private handlerBound: boolean;\n\n constructor(player: VideoJsPlayer) {\n const options: any = {};\n\n options.track = <any>{\n player,\n kind: 'subtitle',\n label: 'Video Transcript',\n selectable: false,\n default: false,\n mode: 'disabled'\n };\n options.selectable = false;\n options.name = 'TranscriptMenuItem';\n\n super(player, options);\n\n this.transcriptOn = this.player_.viewTranscriptPlugin && this.player_.viewTranscriptPlugin().isTranscriptOn();\n\n this.bindEventListeners();\n }\n\n private bindEventListeners(): void {\n const onToggle = this.toggleListener.bind(this);\n const onResize = this.onResize.bind(this);\n this.player_.on('cv-transcript-toggle', onToggle);\n this.player_.on('playerresize', onResize);\n\n this.on('dispose', () => {\n this.player_.off('cv-transcript-toggle', onToggle);\n this.player_.off('playerresize', onResize);\n });\n }\n\n private onResize(): void {\n const shouldHide = window.innerWidth < MIN_WIDTH_WITH_TRANSCRIPT;\n if (this.item) {\n (this.item as HTMLElement).style.display = shouldHide ? 'none' : 'block';\n }\n }\n\n private handleToggleListener(): void {\n this.transcriptOn ? this.toggleOff() : this.toggleOn();\n }\n\n private toggleListener(e: any, val: boolean): void {\n if (val) {\n this.transcriptOn = true;\n videojs.dom.addClass(this.toggleEl, 'on');\n } else {\n this.transcriptOn = false;\n videojs.dom.removeClass?.(this.toggleEl, 'on');\n }\n }\n\n private toggleOn(): void {\n this.transcriptOn = true;\n videojs.dom.addClass(this.toggleEl, 'on');\n\n if (this.player_.viewTranscriptPlugin)\n this.player_.viewTranscriptPlugin()?.toggleTranscript?.(true);\n\n // disabled whiteboard mode when transcript is on\n this.player_.whiteboardModePlugin && this.player_.whiteboardModePlugin().setEnabled(false);\n }\n\n private toggleOff(): void {\n this.transcriptOn = false;\n videojs.dom.removeClass?.(this.toggleEl, 'on');\n if (this.player_.viewTranscriptPlugin)\n this.player_.viewTranscriptPlugin()?.toggleTranscript?.(false);\n }\n\n public createEl(tagName?: string, properties?: any, attributes?: any): Element {\n /**\n * Bind our event listener only once\n * see the comment where handlerBound is defined\n */\n if (!this.handlerBound) {\n this.handleToggleListener = this.handleToggleListener.bind(this);\n this.handlerBound = true;\n }\n\n if (this.toggleEl)\n this.toggleEl.removeEventListener('click', this.handleToggleListener);\n\n this.toggleEl = videojs.dom.createEl('div', {\n className: `custom-toggle custom-toggle-info toggle-option float-end`,\n innerHTML: '<span class=\"handle\"></span></div>'\n });\n this.toggleEl.addEventListener('click', this.handleToggleListener);\n\n const innerHTML = `\n <span class=\"vjs-menu-item-text\">Video Transcript</span>\n <span class=\"cv-toggle-container\"></span>\n <span class=\"vjs-control-text\" aria-live=\"polite\">, opens transcript</span>\n `;\n\n this.item = videojs.dom.createEl('li', {\n className: 'vjs-menu-item cv-transcript-toggle',\n innerHTML\n }, attributes);\n\n /**\n * Indexing into the child this way is only safe to do because\n * we know that the el only has two children\n */\n this.item.children[1].appendChild(this.toggleEl);\n\n return this.item;\n }\n}\n\nvideojs.registerComponent('ToggleTranscriptMenuItem', ToggleTranscriptMenuItem);\n","import videojs from 'video.js';\n\nimport { CollapsibleComponent } from 'projects/player/interfaces/CollapsibleComponent';\nimport { MIN_WIDTH_WITH_TRANSCRIPT } from 'projects/player/plugins/transcript-plugin/transcript-plugin';\n\nimport { CustomSubCapsMenuItem } from './SubCapsMenuItem';\nimport { SubtitleSearchMenuItem } from './subtitle-search-menu-item';\nimport { SubtitleSizeMenuItem } from './subtitle-size-menu-item';\nimport { ToggleTranscriptMenuItem } from './toggle-transcript-menu-item';\n\nimport './subs-caps-button.scss';\n\nconst TextTrackButton = videojs.getComponent('TextTrackButton');\n\nconst BaseSubsCapsButton = videojs.getComponent('SubsCapsButton') as unknown as typeof videojs.TextTrackButton;\n\nclass SubsCapsButton extends BaseSubsCapsButton implements CollapsibleComponent {\n // tslint:disable-next-line\n private kinds_: string[];\n\n public buildWrapperCSSClass() {\n return `cv-menu-small cv-has-left-icons ${super.buildWrapperCSSClass()}`;\n }\n\n public createItems(): videojs.TextTrackMenuItem[] {\n const items = [];\n if (!this.player_.options_.mobile) {\n const tracks = this.player().textTracks();\n const hasSubtitleTrack = Array.from(tracks || []).some(track => track.kind === 'subtitles');\n const shouldShowTranscript =\n this.player_.options_.allowTheatreMode\n && !!hasSubtitleTrack\n && this.player_.viewTranscriptPlugin\n && window.innerWidth >= MIN_WIDTH_WITH_TRANSCRIPT;\n\n if (shouldShowTranscript) {\n items.push(new ToggleTranscriptMenuItem(this.player_) as any);\n }\n\n items.push(new SubtitleSearchMenuItem(this.player_) as any);\n items.push(new SubtitleSizeMenuItem(this.player_) as any);\n\n /**\n * We need to bump this by 2 because we've added\n * an extra menu item\n */\n (this as any).hideThreshold_ = (this as any).hideThreshold_ + 2;\n }\n\n // re-calculate menu position when track items all added\n this.player().trigger('resizemenus');\n\n return (TextTrackButton.prototype as any).createItems.call(this, items, CustomSubCapsMenuItem);\n }\n\n /**\n * CollapsibileComponent interface implementation\n * from here onward\n */\n public alwaysCollapsed: boolean = false;\n public isCollapsed: boolean = false;\n public isCollabsible: boolean = true;\n public className: string = 'cv-subs-caps-menu-button';\n\n public getCollabsibleName(): string {\n return 'Subtitles';\n }\n\n public getCollabsibleValue(): string {\n const tracks = this.player_.textTracks();\n\n for (let i = 0; i < tracks.length; i++) {\n const track = tracks[i];\n\n // only add tracks that are of an appropriate kind and have a label\n if (this.kinds_.indexOf(track.kind) > -1) {\n if (track.mode === 'showing')\n return track.label;\n }\n }\n\n return 'Off';\n }\n\n public showInCollabsibleMenu(): boolean {\n const tracks = this.player_.textTracks();\n\n for (let i = 0; i < tracks.length; i++) {\n const track = tracks[i];\n\n // only add tracks that are of an appropriate kind and have a label\n if (this.kinds_.indexOf(track.kind) > -1)\n return true;\n }\n\n return false;\n }\n\n public showCollapsibleMenu(): void {\n BaseSubsCapsButton.prototype.handleClick.apply(this);\n }\n}\n\nvideojs.registerComponent('SubsCapsButton', SubsCapsButton);\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { LocalCacheIconSvg } from 'projects/player/plugins/localcache-plugin/compontents/local-cache-indicator';\n\nconst localCacheElement = `<span class=\\'vjs-local-cache-indicator-icon\\' title=\\'Streaming from ClickView Local Cache\\'>${LocalCacheIconSvg}</span>`;\n\nconst MenuItem = videojs.getComponent('MenuItem');\n\nexport interface QualityMenuOptions extends videojs.MenuItemOptions {\n qualityId: string;\n label: string;\n}\n\nexport class QualityMenuItem extends MenuItem {\n private qualityId: string;\n\n constructor(player: VideoJsPlayer, options: QualityMenuOptions) {\n super(player, options);\n\n this.qualityId = options.qualityId;\n\n const qualityLevels = player.qualityLevels();\n\n const changeHandler = this.handleQualityChange.bind(this);\n\n qualityLevels.on('change', changeHandler);\n\n player.one('dispose', () => {\n qualityLevels.off('change', changeHandler);\n });\n\n /**\n * Must be inside of ready otherwise this\n * component could initialise the localCache plugin\n */\n this.handleLocalCacheChange = this.handleLocalCacheChange.bind(this);\n \n this.player_.ready(() => {\n // TODO: We need to figure out why quality-button gets rendered\n // twice before the played is ever ready, once we do we can remove this check\n if (!this.player_)\n return;\n\n this.player_.on('localcachechanged', this.handleLocalCacheChange);\n this.player_.one('dispose', () => {\n this.player_?.off('localcachechanged', this.handleLocalCacheChange);\n });\n\n this.handleLocalCacheChange();\n });\n }\n\n private async handleLocalCacheChange(): Promise<void> {\n const localCachePlugin = this.player_.localCache();\n const activeLocalCache = await localCachePlugin.getActiveLocalCache();\n\n if (!activeLocalCache?.playbackProfile) {\n this.show();\n this.enable();\n this.setLabel(this.options_.label);\n return;\n }\n\n if (activeLocalCache.playbackProfile !== this.qualityId) {\n this.disable();\n } else {\n this.setLabel(this.options_.label + localCacheElement);\n }\n }\n\n private setLabel(text: string): void {\n const itemText = this.$('.vjs-menu-item-text');\n if (itemText)\n itemText.innerHTML = text;\n }\n\n public buildCSSClass(): string {\n return 'vjs-menu-item cv-quality-menu-item';\n }\n\n public handleClick(): void {\n const qualityLevels = this.player_.qualityLevels();\n\n for (let i = 0; i < qualityLevels.length; i++) {\n const qualityLevel = qualityLevels[i];\n\n qualityLevel.enabled = qualityLevel.id === this.qualityId;\n }\n }\n\n private handleQualityChange(): void {\n // sometimes player is null? seems to happen during initialization for some reason\n if (!this.player_)\n return;\n\n const qualityLevels = this.player_.qualityLevels();\n const currentQuality = qualityLevels[qualityLevels.selectedIndex];\n const shouldBeSelected = currentQuality && currentQuality.id === this.qualityId;\n\n if (shouldBeSelected !== (this as any).isSelected_)\n this.selected(shouldBeSelected);\n }\n}\n","import videojs, { VideoJsPlayer } from 'video.js';\nimport { QualityLevel } from 'videojs-contrib-quality-levels';\n\nimport { CollapsibleComponent } from 'projects/player/interfaces/CollapsibleComponent';\n\nimport { CollapsibleHeadingMenuItem } from '../cog-button/collapsible-heading-menu-item';\n\nimport { QualityMenuItem } from './quality-menu-item';\n\nimport './quality-button.scss';\n\ninterface QualityLabelsMap {\n [name: string]: string;\n}\n\nconst qualityLabels: QualityLabelsMap = {\n 144: '144p (Preview)',\n 240: '240p',\n 360: '360p',\n 480: '480p',\n 720: '720p',\n 1080: '1080p'\n};\n\nconst MenuButton = videojs.getComponent('MenuButton') as unknown as typeof videojs.MenuButton;\n\nclass QualityMenuButton extends MenuButton implements CollapsibleComponent {\n constructor(player: VideoJsPlayer, options?: videojs.MenuButtonOptions) {\n super(player, options);\n\n const qualityLevels = this.player_.qualityLevels();\n\n const updateHandler = this.update.bind(this);\n\n qualityLevels.on('addqualitylevel', updateHandler);\n qualityLevels.on('removequalitylevel', updateHandler);\n\n player.one('dispose', () => {\n qualityLevels.removeEventListener('addqualitylevel', updateHandler);\n qualityLevels.removeEventListener('removequalitylevel', updateHandler);\n });\n }\n\n public buildCSSClass(): string {\n return `cv-quality-button ${super.buildCSSClass()}`;\n }\n\n public buildWrapperCSSClass(): string {\n return `cv-menu-small vjs-quality-button cv-has-left-icons ${super.buildWrapperCSSClass()}`;\n }\n\n public createItems(): QualityMenuItem[] {\n const items: QualityMenuItem[] = [];\n const qualityLevels = this.player_.qualityLevels();\n\n items.push(new CollapsibleHeadingMenuItem(this.player_, {\n label: 'Quality'\n }) as any);\n\n for (let i = 0; i < qualityLevels.length; i++) {\n const qualityLevel = qualityLevels[i] as QualityLevel;\n\n if (!qualityLevel)\n continue;\n\n const label = qualityLabels[qualityLevel.id];\n\n // if no label is found, skip it\n if (!label)\n continue;\n\n items.push(new QualityMenuItem(this.player_, {\n qualityId: qualityLevel.id,\n label: label,\n selectable: true,\n multiSelectable: false\n }));\n }\n\n return items;\n }\n\n /**\n * CollapsibileComponent interface implementation\n * from here onward\n */\n public alwaysCollapsed: boolean = true;\n public isCollapsed: boolean = false;\n public isCollabsible: boolean = true;\n public className: string = 'cv-quality-menu-button';\n\n public getCollabsibleName(): string {\n return 'Quality';\n }\n\n public getCollabsibleValue(): string {\n const qualityLevels = this.player_.qualityLevels();\n const currentQuality = qualityLevels[qualityLevels.selectedIndex];\n\n if (!currentQuality)\n return '';\n\n return qualityLabels[currentQuality.id];\n }\n\n public showInCollabsibleMenu(): boolean {\n return !!this.player_.qualityLevels().length;\n }\n\n public showCollapsibleMenu(): void {\n MenuButton.prototype.handleClick.apply(this);\n }\n}\n\nvideojs.registerComponent('QualityButton', QualityMenuButton);\n","\nimport videojs, { VideoJsPlayer } from 'video.js';\n\nimport { CollapsibleComponent } from 'projects/player/interfaces/CollapsibleComponent';\n\nimport { CollapsibleHeadingMenuItem } from '../cog-button/collapsible-heading-menu-item';\n\nimport './playback-rate-button.scss';\n\ninterface PlaybackRateMenuItemOptions extends videojs.MenuItemOptions {\n rate: string;\n}\n\ninterface PlaybackRateMenuItem extends videojs.MenuItem {\n new(player: VideoJsPlayer, options: PlaybackRateMenuItemOptions): videojs.MenuItem;\n}\n\ninterface BasePlaybackRateMenuButton extends videojs.MenuButton {\n new(player: VideoJsPlayer, options: videojs.MenuButtonOptions): videojs.MenuButton;\n updateLabel: (event: any) => void;\n}\n\nconst Menu = videojs.getComponent('Menu');\nconst MenuButton = videojs.getComponent('MenuButton');\nconst PlaybackRateMenuItem = videojs.getComponent('PlaybackRateMenuItem') as unknown as PlaybackRateMenuItem;\nconst BasePlaybackRateMenuButton = videojs.getComponent('PlaybackRateMenuButton') as unknown as BasePlaybackRateMenuButton;\n\nclass PlaybackRateMenuButton extends BasePlaybackRateMenuButton implements CollapsibleComponent {\n // eslint-disable-next-line\n private labelEl_: Element;\n\n /**\n * The base class injects labelEl_ here. We don't want that\n * as we want it inside the `<button>` as that is where the\n * click handler is bound.\n */\n public createEl(...args: any[]): Element {\n return MenuButton.prototype.createEl.apply(this, ...args);\n }\n\n public buildWrapperCSSClass() {\n return `cv-menu-small cv-has-left-icons ${super.buildWrapperCSSClass()}`;\n }\n\n /**\n * This implementation of createMenu differs slightly from the one in the base class.\n */\n public createMenu(): videojs.Menu {\n /**\n * The base class doesn't pass menuButton as an option to Menu.\n * This is required for the menu to close when an item is clicked.\n */\n const menu = new Menu(this.player(), { menuButton: this });\n\n menu.addItem(new CollapsibleHeadingMenuItem(this.player_, {\n label: 'Playback Speed'\n }));\n\n const rates = (this as any).playbackRates();\n\n if (rates) {\n for (let i = 0; i < rates.length; i++) {\n /**\n * For some reason the base class uses menu.addChild, however\n * menu.addItem is required for the event listeners to be be bound\n * to the child components. Without this, the menu wouldn't close\n * when selecting an item;\n */\n let rate = rates[i] + 'x';\n \n if (rates[i] === 1)\n rate += ' (Normal)';\n\n menu.addItem(new PlaybackRateMenuItem(this.player(), { rate }));\n }\n }\n\n return menu;\n }\n\n /**\n * The base class toggles the playback rate on click.\n * We want the menu to open.\n */\n public handleClick(...args: any[]): void {\n return MenuButton.prototype.handleClick.apply(this, ...args);\n }\n\n public updateLabel(...args: any[]): void {\n this.setupLabelEl();\n\n return BasePlaybackRateMenuButton.prototype.updateLabel.apply(this, ...args);\n }\n\n /**\n * labelEl_ displays the current playback rate, e.g. 1x.\n * This is used instead of an icon for this button.\n * As mentioned above, we want the labelEl_ to be inside\n * the `<button>` so that clicking on it opens the menu.\n */\n private setupLabelEl(): void {\n if (this.labelEl_)\n return;\n\n const button = this.$('button');\n\n if (!button)\n return;\n\n this.labelEl_ = videojs.dom.createEl('div', {\n className: 'vjs-playback-rate-value',\n innerHTML: '1x'\n });\n\n button.appendChild(this.labelEl_);\n }\n\n /**\n * CollapsibileComponent interface implementation\n * from here onward\n */\n public alwaysCollapsed: boolean = true;\n public isCollapsed: boolean = false;\n public isCollabsible: boolean = true;\n public className: string = 'cv-playback-rate-menu-button';\n\n public getCollabsibleName(): string {\n return 'Playback Speed';\n }\n\n public getCollabsibleValue(): string {\n return this.player().playbackRate() + 'x';\n }\n\n public showInCollabsibleMenu(): boolean {\n return !!(this as any).playbackRates();\n }\n\n public showCollapsibleMenu(): void {\n this.handleClick(null);\n }\n}\n\nvideojs.registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton);\n","import videojs from 'video.js';\n\nconst BaseTextTrackSettings = videojs.getComponent('TextTrackSettings');\n\nexport type SubtitleSizes = 'small' | 'medium' | 'large';\n\nconst BASE_TRACK_SETTINGS = {\n backgroundColor: '#000',\n backgroundOpacity: '1',\n color: '#FFF',\n edgeStyle: undefined as string,\n fontFamily: 'proportionalSansSerif',\n fontPercent: 1,\n textOpacity: '1',\n windowColor: '#000',\n windowOpacity: '0'\n};\n\nconst TRACK_SETTINGS = {\n small: BASE_TRACK_SETTINGS,\n medium: {\n ...BASE_TRACK_SETTINGS,\n fontPercent: 1.5\n },\n large: {\n ...BASE_TRACK_SETTINGS,\n fontPercent: 2\n }\n};\n\nexport class TextTrackSettings extends BaseTextTrackSettings {\n private size_: 'small' | 'medium' | 'large';\n\n public setSizeSetting(size: SubtitleSizes): void {\n this.size_ = size;\n const ttDisplay = this.player_.getChild('textTrackDisplay') as any;\n ttDisplay.updateDisplay();\n const subtitleSizeButton = this.player_\n .getChild('collapserator')\n .getChild('subtitleSizeButton') as any;\n\n this.player_.trigger('changesubtitlesize', this.size_);\n \n /**\n * If we update out button immediately, our mouseleave event\n * never fires because the child menu item is removed from the dom.\n * We need this event to fire before we remove the element so that the\n * inactivityTimeout maintained by `player.ts` in `listenForUserActivity_()`\n * continues to work.\n */\n window.requestAnimationFrame(() => {\n subtitleSizeButton.update();\n this.player_.trigger('resizemenus');\n });\n }\n\n public getSizeSetting(): SubtitleSizes {\n return this.size_ || 'small';\n }\n\n public getValues(): any {\n if (!TRACK_SETTINGS[this.size_])\n return BASE_TRACK_SETTINGS;\n\n return TRACK_SETTINGS[this.size_];\n }\n}\n\nvideojs.registerComponent('TextTrackSettings', TextTrackSettings);","import videojs, { VideoJsPlayer, VideoJsPlayerOptions } from 'video.js';\n\nimport { DevicesConfig } from 'projects/player/interfaces/DevicesConfig';\nimport { PlayerMode } from 'projects/player/plugins/player-mode-plugin/player-mode-plugin';\n\nimport './player.scss';\n\n/**\n * Taken from browser.js in video.js\n */\nconst USER_AGENT = window.navigator && window.navigator.userAgent || '';\nexport const IS_IPOD = (/iPod/i).test(USER_AGENT);\nexport const IS_ANDROID = (/Android/i).test(USER_AGENT);\n\nconst VIDEO_CONTAINER_CLASS_NAME = 'cv-video-wrapper';\n\nconst Player = videojs.getComponent('Player');\n\nclass PlayerWrapper extends Player {\n private callback_: (success: () => void) => void;\n private _dataLoaded: boolean = false;\n private videoContainer: Element;\n\n constructor(player: VideoJsPlayer, options: VideoJsPlayerOptions) {\n super(player, options);\n\n if (options.mobile)\n this.addClass('cv-mobile-player');\n\n const setDataLoaded = () => this._dataLoaded = true;\n this.on('cv-playback-data-loaded', setDataLoaded);\n this.on('dispose', () => this.off('cv-playback-data-loaded', setDataLoaded));\n }\n\n public dataLoaded(callback: () => void): void {\n if (this._dataLoaded) {\n callback();\n return;\n }\n\n this.one('cv-playback-data-loaded', callback);\n this.one('dispose', () => {\n this.off('cv-playback-data-loaded', callback);\n });\n }\n\n /**\n * TODO: Update lock, unlock and currentTime\n * to use a pattern similar to the clipPlugin where\n * these functions are re-assigned on the instance when the interactives\n * plugin is initialized\n */\n public lock(callback: (success: () => void) => void): void {\n this.callback_ = callback;\n }\n\n public unlock(): void {\n delete this.callback_;\n }\n\n public currentTime(seconds: number, ignore?: boolean): void;\n public currentTime(): number ;\n public currentTime(seconds?: any, ignore?: boolean): any {\n if (typeof seconds !== 'number' || !this.callback_ || ignore)\n return super.currentTime(seconds);\n\n this.callback_(() => {\n this.unlock();\n this.currentTime(seconds);\n });\n }\n\n public play(): any {\n if (!this.callback_) return super.play();\n\n this.callback_(() => {\n this.unlock();\n this.play();\n });\n }\n\n public createEl() {\n const el = super.createEl();\n\n if (!this.videoContainer) {\n this.videoContainer = videojs.dom.createEl('div', {\n className: VIDEO_CONTAINER_CLASS_NAME\n });\n\n el.appendChild(this.videoContainer);\n }\n\n Array.from(el.childNodes)\n .forEach(node => node !== this.videoContainer && this.videoContainer.appendChild(node));\n\n return el;\n }\n\n public addChild(child: any, options: any = {}, index: number = this.children_.length) {\n const component = super.addChild(child, options, index);\n\n const element = component.el();\n if (element) {\n this.videoContainer.appendChild(element);\n }\n\n return component;\n }\n\n public updateStyleEl_(): void {\n (Player.prototype as any).updateStyleEl_.call(this);\n\n if (!this.options_.fluid)\n return;\n\n const parent = (this as any).el_.parentNode;\n\n if (!parent || !this.options_.setMaxHeight)\n return;\n\n /**\n * Copied updateStyleEl_ from in player.js in videojs\n */\n let aspectRatio = this.aspectRatio();\n if (aspectRatio === undefined || aspectRatio === 'auto') {\n if (this.videoWidth() > 0) {\n aspectRatio = this.videoWidth() + ':' + this.videoHeight();\n } else {\n aspectRatio = '16:9';\n }\n }\n\n\n if (this.player_.playerModePlugin().getMode() === PlayerMode.Hover) {\n parent.style.removeProperty('maxWidth');\n parent.style.removeProperty('margin');\n return;\n }\n \n // Get the ratio as a decimal we can use to calculate dimensions\n const ratioParts = aspectRatio.split(':');\n const ratioMultiplier = +ratioParts[1] / +ratioParts[0];\n \n\n parent.style.maxWidth = (85 * 1 / ratioMultiplier) + 'vh';\n parent.style.margin = '0 auto';\n }\n\n public listenForUserActivity_(): void {\n (Player.prototype as any).listenForUserActivity_.call(this);\n\n /**\n * Player in video.js already does this exact logic for ControlBar, however for WhiteboardMode\n * we need out collapserator to exist outside of the ControlBar so we need to re-implement this logic \n * specifically for collapserator. \n * \n * All this does it keep the controls from fading if the mouse is inside any of our controls of menus\n */\n const collapserator = this.getChild('collapserator');\n collapserator.on('mouseenter', () => {\n (this.player() as any).cache_.inactivityTimeout = this.player().options_.inactivityTimeout;\n this.player().options_.inactivityTimeout = 0;\n });\n\n collapserator.on('mouseleave', () => {\n this.player().options_.inactivityTimeout = (this.player() as any).cache_.inactivityTimeout;\n });\n }\n\n /**\n * Uncomment to debug fullscreen interactives on iOS,\n * we are just ignoring all the other logic in the base implementation of this function\n * and going straight into windowed fullscreen mode. - Sha\n * \n * Note: Exiting fullscreen doesn't work when doing this, feel free to try fix that if you want\n */\n // public requestFullscreenHelper_() {\n // this.enterFullWindow();\n // }\n}\n\nPlayerWrapper.prototype.options_ = {\n ...Player.prototype.options_,\n setMaxHeight: true\n};\n\nvideojs.registerComponent('player', PlayerWrapper);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n lock(callback: (success: () => void) => void): void;\n unlock(): void;\n dataLoaded(callback: () => void): void;\n\n activePlugins_: {\n activityStatusPlugin: boolean;\n favouritePlugin: boolean;\n };\n }\n export interface VideoJsPlayerOptions {\n setMaxHeight?: boolean;\n mobile?: boolean;\n allowTheatreMode?: boolean;\n onRequestTheatreMode?: (isTheatreMode: boolean) => void;\n deferMenus?: boolean;\n fill?: boolean;\n devicesConfig?: DevicesConfig;\n devices?: {\n instanceId: string;\n }\n }\n}\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport './play-pause-feedback.scss';\n\nconst Component = videojs.getComponent('Component');\n\nclass PlayPauseFeedback extends Component {\n constructor(player: VideoJsPlayer, options?: videojs.ComponentOptions) {\n super(player, options);\n\n this.player_.addClass('cv-disable-play-pause-feedback');\n\n this.onFirstPlay = this.onFirstPlay.bind(this);\n this.player_.one('play', this.onFirstPlay);\n }\n\n public dispose(): void {\n this.player_.off('play', this.onFirstPlay);\n }\n\n private onFirstPlay(): void {\n window.setTimeout(() => {\n if (!(this.player_ as any).isDisposed())\n this.player_.removeClass('cv-disable-play-pause-feedback');\n }, 500);\n }\n\n public createEl(): Element {\n return videojs.dom.createEl('div', {\n className: 'cv-play-pause-feedback'\n });\n }\n}\n\nvideojs.registerComponent('PlayPauseFeedback', PlayPauseFeedback);","import videojs from 'video.js';\n\nimport './play-toggle.scss';\n\nconst BasePlayToggle = videojs.getComponent('PlayToggle');\n\nclass PlayToggle extends BasePlayToggle {\n private timeoutId: number;\n\n public handleClick(event: videojs.EventTarget.Event): void {\n (BasePlayToggle.prototype as any).handleClick.call(this, event);\n\n this.player_.addClass('cv-disable-play-pause-feedback');\n if (this.timeoutId)\n window.clearTimeout(this.timeoutId);\n\n this.timeoutId = window.setTimeout(() => {\n this.player_.removeClass('cv-disable-play-pause-feedback');\n }, 500);\n }\n}\n\nvideojs.registerComponent('PlayToggle', PlayToggle);","import videojs from 'video.js';\n\nimport './text-track-display.scss';\n\nconst BaseTextTrackDisplay = videojs.getComponent('TextTrackDisplay');\n\n/**\n * Making our subtitle font size based on the width of the player container, instead of the height.\n * This code is emulating what is happening in https://github.com/mozilla/vtt.js/blob/master/lib/vtt.js#L1052 which video.js uses in the backend\n * We're using 2.5% of the player width, instead of 5% of the player height, as was being used before\n */\nconst FONT_SIZE_PERCENT = 0.025;\n\nexport class TextTrackDisplay extends BaseTextTrackDisplay {\n /**\n * The code inside this function is duplicating what updateDisplayState() is doing in the\n * base text track display, however we're only updating the font size to be based on the container width\n */\n public updateDisplayState(track: videojs.TextTrack): void {\n (BaseTextTrackDisplay.prototype as any).updateDisplayState.call(this, track);\n\n const overrides = (this.player_ as any).textTrackSettings.getValues();\n const cues = track.activeCues;\n\n let i = cues.length;\n\n while (i--) {\n const cue = cues[i];\n\n if (!cue) {\n continue;\n }\n\n const cueDiv = (cue as any).displayState;\n\n if (overrides.fontPercent && overrides.fontPercent !== 1) {\n const container = this.el().getBoundingClientRect();\n const fontSize = (container.width * FONT_SIZE_PERCENT * 100) / 100;\n cueDiv.style.fontSize = (fontSize * overrides.fontPercent) + 'px';\n }\n }\n }\n}\n\nvideojs.registerComponent('TextTrackDisplay', TextTrackDisplay);","import videojs from 'video.js';\n\nconst Component = videojs.getComponent('Component');\n\nexport class ControlBarGradient extends Component {\n public createEl(): Element {\n return videojs.dom.createEl('div', {\n className: 'cv-control-bar-gradient-container',\n innerHTML: '<div class=\"cv-control-bar-gradient\"></div>'\n });\n }\n}\n\nvideojs.registerComponent('ControlBarGradient', ControlBarGradient);","/**\n * IMPORTANT!\n * Please refer to projects\\player\\src\\components\\poster-image\\poster-image-details.md\n * before changing this file\n */\nimport videojs, { VideoJsPlayer } from 'video.js';\n\nconst Component = videojs.getComponent('Component');\n\ninterface SplashTitleOptions extends videojs.ComponentOptions {\n title: string;\n seriesName?: string;\n seasonNumber?: number;\n episodeNumber?: number;\n}\n\nexport class SplashTitle extends Component {\n public options_: SplashTitleOptions;\n\n constructor(player: VideoJsPlayer, options: SplashTitleOptions) {\n super(player, options);\n\n this.options_ = options;\n }\n\n public createEl(): Element {\n let innerHTML = this.options_.title;\n\n if (!this.options_.seriesName)\n return super.createEl('h1', { innerHTML });\n \n const seasonEpisode = this.buildSeasonEpisodeString();\n\n if (!seasonEpisode) {\n innerHTML = `<div class='cv-splash-series'>${this.options_.seriesName.toUpperCase()}</div>` + innerHTML;\n\n return super.createEl('h1', { innerHTML });\n }\n\n innerHTML =\n `<div class='cv-splash-series'>${this.options_.seriesName.toUpperCase()} ${seasonEpisode}</div>` + innerHTML;\n\n return super.createEl('h1', { innerHTML });\n }\n\n private buildSeasonEpisodeString(): string {\n if (!this.options_.seasonNumber || !this.options_.episodeNumber)\n return '';\n\n const seasonNumber = this.padNumber(this.options_.seasonNumber, 2);\n const episodeNumber = this.padNumber(this.options_.episodeNumber, 2);\n\n return `S${seasonNumber} • E${episodeNumber}`;\n }\n\n private padNumber(num: number, padLength: number): string {\n let numberString = num.toString();\n\n if (numberString.length >= padLength)\n return numberString;\n\n padLength = padLength - numberString.length;\n\n while (padLength > 0) {\n numberString = '0' + numberString;\n padLength--;\n }\n return numberString;\n }\n}","/**\n * IMPORTANT!\n * Please refer to projects\\player\\src\\components\\poster-image\\poster-image-details.md\n * before changing this file\n */\nimport videojs, { VideoJsPlayer } from 'video.js';\n\nimport { mapRatingValueToColourClass } from 'projects/player/utils/PlayerRatingHelper';\n\nconst Component = videojs.getComponent('Component');\n\ninterface SplashWarningOptions extends videojs.ComponentOptions {\n ratingCode?: string;\n ratingValue?: number;\n}\n\nexport class SplashWarning extends Component {\n public options_: SplashWarningOptions;\n\n constructor(player: VideoJsPlayer, options: SplashWarningOptions) {\n super(player, options);\n\n this.options_ = options;\n }\n\n public buildCSSClass(): string {\n return `cv-splash-rating ${mapRatingValueToColourClass(this.options_.ratingValue)}`;\n }\n\n public createEl(tagName?: string, properties?: any, attributes?: any): Element {\n if (!this.options_.ratingCode)\n return null;\n\n return super.createEl(tagName, {\n ...properties,\n className: this.buildCSSClass(),\n innerHTML: this.options_.ratingCode\n }, attributes);\n }\n}","/**\n * IMPORTANT!\n * Please refer to projects\\player\\src\\components\\poster-image\\poster-image-details.md\n * before changing this file\n */\nimport videojs, { VideoJsPlayer } from 'video.js';\n\nimport { SplashTitle } from './splash-title/splash-title';\nimport { SplashWarning } from './splash-warning/splash-warning';\n\nconst Component = videojs.getComponent('Component');\n\ninterface SplashMetadataOptions extends videojs.ComponentOptions {\n embed: boolean;\n title: string;\n ratingCode?: string;\n ratingValue?: number;\n seriesName?: string;\n seasonNumber?: number;\n episodeNumber?: number;\n}\n\nexport class SplashMetadata extends Component {\n public options_: SplashMetadataOptions;\n\n constructor(player: VideoJsPlayer, options: SplashMetadataOptions) {\n super(player, options);\n\n if (!options.embed)\n return this;\n\n this.addChild(new SplashTitle(player, options));\n this.addChild(new SplashWarning(player, options));\n }\n\n public createEl(): HTMLDivElement {\n return videojs.dom.createEl('div', {\n className: 'cv-splash-metadata'\n }) as HTMLDivElement;\n }\n}","/**\n * IMPORTANT!\n * Please refer to projects\\player\\src\\components\\poster-image\\poster-image-details.md\n * before changing this file\n */\nimport videojs, { VideoJsPlayer } from 'video.js';\n\nimport { ClickViewLogo } from 'projects/player/components/logo/clickview-logo';\n\nimport { SplashMetadata } from './metadata/splash-metadata';\n\nconst BasePosterImage = videojs.getComponent('posterImage');\n\ninterface PosterImageOptions extends videojs.ComponentOptions {\n embed: boolean;\n posterUrl: string;\n title: string;\n warning?: string;\n ratingCode?: string;\n seriesName?: string;\n seasonNumber?: number;\n episodeNumber?: number;\n}\n\nexport class PosterImage extends BasePosterImage {\n public options_: PosterImageOptions;\n\n constructor(player: VideoJsPlayer, options: PosterImageOptions) {\n super(player, options);\n\n this.addChild(new SplashMetadata(player, options));\n }\n\n public createEl(): Element {\n let innerHTML = `<div class='cv-splash-mask'></div>`;\n\n if (this.options_.embed)\n innerHTML += `<div class='cv-splash-logo'>${ClickViewLogo}</div>`;\n\n return videojs.dom.createEl('div', {\n className: 'vjs-poster cv-embed-splash cv-embed-splash-black',\n\n // Don't want poster to be tabbable.\n tabIndex: -1,\n innerHTML\n });\n }\n\n public setSrc(url: string) {\n let backgroundImage = '';\n\n // Any falsy value should stay as an empty string, otherwise\n // this will throw an extra error\n if (url) {\n backgroundImage = `url(\"${url}\")`;\n }\n\n (this as any).el_.style.backgroundImage = backgroundImage;\n }\n}\n\nvideojs.registerComponent('posterImage', PosterImage);","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport './error-display.scss';\n\nconst BaseErrorDisplay = videojs.getComponent('ErrorDisplay');\n\nexport class ErrorDisplay extends BaseErrorDisplay {\n constructor(player: VideoJsPlayer, options: videojs.ComponentOptions) {\n super(player, options);\n\n this.el().prepend(this.getErrorImage());\n }\n\n private getErrorImage(): Element {\n return videojs.dom.createEl('div', {\n className: 'cv-error-image',\n innerHTML: `\n <svg viewBox=\"0 0 301 185\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M267.393 36.6514V167.906C267.393 168.182 267.169 168.406 266.893 168.406H32C31.7239 168.406 31.5 168.182 31.5 167.906V36.6514C31.5 36.3752 31.7239 36.1514 32 36.1514H80.5C80.7761 36.1514 81 36.3752 81 36.6514V57.7196C81 58.7622 82.0375 59.4868 83.0164 59.1279L95.7377 54.4634C95.9961 54.3687 96.2825 54.5006 96.3785 54.7585L102.094 70.1194C102.677 71.6866 105 71.2685 105 69.5964V48.4925C105 47.7632 104.475 47.1396 103.757 47.0146L94.2479 45.3609C93.9436 45.308 93.7596 44.9946 93.8616 44.7031L96.7376 36.4862C96.8077 36.2856 96.997 36.1514 97.2095 36.1514H266.893C267.169 36.1514 267.393 36.3752 267.393 36.6514Z\" stroke=\"white\"/>\n <path d=\"M163.296 101.777L149.437 90.1217C148.275 89.1441 146.5 89.9705 146.5 91.4894V113.664C146.5 115.141 148.191 115.98 149.367 115.087L163.226 104.569C164.139 103.876 164.173 102.515 163.296 101.777Z\" stroke=\"white\" stroke-linecap=\"round\"/>\n <path d=\"M295.53 23.0783L277.524 26.2801L283.252 32.7192L274.855 38.9079L292.861 35.7061L287.133 29.2671L295.53 23.0783Z\" stroke=\"white\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M268.06 2.91764L254.192 14.8403L262.401 17.4661L258.324 27.0679L272.192 15.1453L263.983 12.5194L268.06 2.91764Z\" stroke=\"white\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n `\n });\n }\n}\n\nvideojs.registerComponent('ErrorDisplay', ErrorDisplay);","import videojs from 'video.js';\n\nconst BaseFullscreenToggle = videojs.getComponent('FullscreenToggle');\n\nconst CONTROL_TEXT = 'Fullscreen (f)';\n\nexport class FullscreenToggle extends BaseFullscreenToggle {\n public controlText_: string;\n\n handleFullscreenChange() {\n (BaseFullscreenToggle.prototype as any).handleFullscreenChange.call(this);\n this.controlText(CONTROL_TEXT);\n }\n}\n\nvideojs.registerComponent('FullscreenToggle', FullscreenToggle);\n\nFullscreenToggle.prototype.controlText_ = CONTROL_TEXT;","/* eslint simple-import-sort/imports: 0 */\n\n/**\n * NOTICE: DO NOT CHANGE THE ORDER OF OUR IMPORTS.\n * IF YOU LINTED THIS FILE DISCARD YOUR CHANGES - SHA\n */\n\nimport '../theme/index.scss';\n\nimport { COLLAPSERATOR_CHILDREN } from 'projects/player/components/collapserator/collapserator';\nimport { ProgressControl } from 'projects/player/components/progress-control/progress-control';\nimport { SubtitleSizes } from 'projects/player/components/text-track-settings/text-track-settings';\nimport { Config } from 'projects/player/interfaces/models/Config';\nimport { Chapter, PlaybackObject } from 'projects/player/interfaces/models/PlaybackObject';\nimport { ExternalLinkOptions } from 'projects/player/plugins/open-externally-plugin/interfaces/ExternalLinkOptions';\nimport { PlayerMode } from 'projects/player/plugins/player-mode-plugin/player-mode-plugin';\nimport { ProgressEventPair } from 'projects/player/plugins/progress-reporter-plugin/interfaces/ProgressEvent';\nimport { Source } from 'projects/player/plugins/progressive-files-plugin/interfaces/Source';\nimport { AnalyticsPlayerType, AnalyticsService } from 'projects/player/services/analytics-service';\nimport { AjaxHelper } from 'projects/player/utils/ajax-helper';\nimport { handleHotKeys } from 'projects/player/utils/hotkeys';\nimport { TrackHelper } from 'projects/player/utils/track-helper';\nimport { Splash } from 'projects/player/interfaces/models/Splash';\nimport { DevicesConfig } from 'projects/player/interfaces/DevicesConfig';\nimport { ApiError } from 'projects/player/interfaces/models/ApiError';\nimport { PlayerApiErrorType } from 'projects/player/interfaces/models/PlayerApiErrorType';\nimport videojs, { VideoJsPlayer, VideoJsPlayerOptions } from 'video.js';\n\nimport { RegionName } from 'libs/analytics/enums/RegionName';\nimport { HashObject } from 'libs/analytics/interfaces';\n\nimport packageInfo from '../../package.json';\n\n/**\n * *.scss imports must be relative\n */\nimport '../components/control-bar/control-bar.scss';\nimport '../components/volume-control/volume-control.scss';\nimport '../components/menu/menu.scss';\nimport '../components/big-play-button/big-play-button.scss';\nimport '../components/text-track-display/text-track-display.scss';\n\nimport 'videojs-contrib-quality-levels';\nimport 'projects/player/plugins/configure-menu-dimensions-plugin/configure-menu-dimensions-plugin';\nimport 'projects/player/plugins/persist-volume-plugin/persist-volume-plugin';\nimport 'projects/player/plugins/persist-playback-rate-plugin/persist-playback-rate-plugin';\nimport 'projects/player/plugins/fullscreen-on-rotate-plugin/fullscreen-on-rotate-plugin';\nimport 'projects/player/plugins/open-externally-plugin/open-externally-plugin';\nimport 'projects/player/plugins/touch-controls-plugin/touch-controls-plugin';\nimport 'projects/player/plugins/progressive-files-plugin/progressive-files-plugin';\nimport 'projects/player/plugins/localcache-plugin/localcache-plugin';\nimport 'projects/player/plugins/handle-network-errors-plugin/handle-network-errors-plugin';\nimport 'projects/player/plugins/persist-subtitle-settings-plugin/persist-subtitle-settings-plugin';\nimport 'projects/player/plugins/persist-quality-settings-plugin/persist-quality-settings-plugin';\nimport 'projects/player/plugins/progress-reporter-plugin/progress-reporter-plugin';\nimport 'projects/player/plugins/whiteboard-mode-plugin/whiteboard-mode-plugin';\nimport 'projects/player/plugins/defer-menus-plugin/defer-menus-plugin';\nimport 'projects/player/plugins/prevent-scrubbing-plugin/prevent-scrubbing-plugin';\nimport 'projects/player/plugins/player-mode-plugin/player-mode-plugin';\nimport 'projects/player/plugins/favourite-plugin/favourite-plugin';\nimport 'projects/player/plugins/theatre-mode-plugin/theatre-mode-plugin';\n\nimport 'projects/player/components/menu/menu';\nimport 'projects/player/components/menu-button/menu-button';\nimport 'projects/player/components/time-wrapper/time-wrapper';\nimport 'projects/player/components/collapserator/collapserator';\n/** Seekbar must be imported before chapter-seek-bar */\nimport 'projects/player/components/seek-bar/seek-bar';\nimport 'projects/player/components/chapter-seek-bar/chapter-seek-bar';\nimport 'projects/player/components/progress-control/progress-control';\nimport 'projects/player/components/mouse-time-display/mouse-time-display';\nimport 'projects/player/components/chapters-button/chapters-button';\nimport 'projects/player/components/text-track-button/text-track-button';\nimport 'projects/player/components/subs-caps-button/subs-caps-button';\nimport 'projects/player/components/quality-selector/quality-button';\nimport 'projects/player/components/playback-rate-button/playback-rate-button';\nimport 'projects/player/components/text-track-settings/text-track-settings';\nimport 'projects/player/components/player/player';\nimport 'projects/player/components/play-pause-feedback/play-pause-feedback';\nimport 'projects/player/components/play-toggle/play-toggle';\nimport 'projects/player/components/text-track-display/text-track-display';\nimport 'projects/player/components/control-bar/control-bar-gradient';\nimport 'projects/player/components/mute-button/mute-button';\nimport 'projects/player/components/player-overlay/player-overlay';\nimport 'projects/player/components/poster-image/poster-image';\nimport 'projects/player/components/error-display/error-display';\nimport 'projects/player/components/fullscreen-toggle/fullscreen-toggle';\nimport { ImageHelper } from 'libs/shared/utils/ImageHelper';\nimport { ImageSize } from 'libs/shared/enums/Images';\n\n\nconst Player = videojs.getComponent('Player');\n\nconst normalizeId = (id: string) => id.indexOf('#') === 0 ? id.slice(1) : id;\n\nconst LOG_STREAM_TIME_THRESHOLD = 3; // seconds\n\nlet config: Config;\n\nexport interface BasePlayerOptions {\n autoplay?: boolean;\n viewKey: string;\n startTime?: number;\n endTime?: number;\n controls?: boolean;\n overflowControls?: boolean;\n playbackRates?: number[];\n embed?: boolean;\n playerApi?: URL;\n enableLocalCache?: boolean;\n onRequestPictureInPicture?: (isPiP: boolean) => void;\n onRequestTheatreMode?: (isTheatreMode: boolean) => void;\n imageCdnUrl?: string; // Used when showing resources\n aspectRatio?: string;\n inactivityTimeout?: number;\n muted?: boolean;\n allowFullscreen?: boolean;\n eventLogging?: boolean;\n splash?: Splash;\n devicesConfig?: DevicesConfig;\n allowTheatreMode?: boolean;\n theatreMode?: boolean;\n\n /**\n * Instance region of the person sharing the share link.\n * Will be used if the user is not signed in\n */\n sharerInstanceRegion?: string;\n\n /**\n * An optional external element for binding hotkey\n * event listeners to.\n */\n hotkeyElQuerySelector?: string;\n\n /**\n * An optional type for prevent scrubbing plugin\n */\n furthestVisitedTime?: number;\n\n // TODO: Add error type\n onError?: (error: any) => void;\n getExternalLink?: (options: ExternalLinkOptions) => string;\n onClickCreateClip?: () => void;\n setup?: (options: BasePlayerOptions, player: VideoJsPlayer) => void;\n fetch?: (viewKey: string) => Promise<PlaybackObject>;\n\n // Mobile player stuff\n mobile?: boolean;\n deferMenus?: boolean;\n offlinePlaybackObject?: PlaybackObject;\n}\n\nexport abstract class BasePlayer {\n // eslint-disable-next-line\n static options_: BasePlayerOptions = {\n viewKey: null,\n controls: true,\n playbackRates: [ 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2 ],\n playerApi: new URL('http://localhost:52000'),\n enableLocalCache: true,\n eventLogging: true,\n allowFullscreen: true\n };\n\n protected el: HTMLVideoElement;\n protected player: VideoJsPlayer;\n protected options: BasePlayerOptions;\n protected analyticsService: AnalyticsService;\n \n private streamLogged: boolean = false;\n\n constructor(id: string | Element, options: BasePlayerOptions) {\n this.options = (videojs as any).obj.merge({}, BasePlayer.options_, options);\n\n // ensure we have a playerAPi\n if (this.options.playerApi === null)\n throw new Error('PlayerApi required');\n\n this.initialize();\n\n this.createEl(id);\n this.buildVideoJs();\n\n /**\n * We setup our splash as early as possible, when it's provided.\n */\n if (this.options.splash) {\n this.setupSplash(this.options.splash);\n }\n \n this.bindEventListeners();\n this.setupSeekBar();\n this.fetchConfig();\n\n this.logStream = this.logStream.bind(this);\n\n this.player.ready(() => {\n this._configurePlugins();\n\n if (this.options.setup)\n this.options.setup(this.options, this.player);\n\n this.fetch().catch(err => this.handleFetchError(err));\n });\n }\n\n protected initialize(): void { }\n\n private _configurePlugins(): void {\n this.player.configureMenuDimensionsPlugin({\n mobile: this.options.mobile,\n overflowControls: this.options.overflowControls,\n seekBarName: this.getSeekBarName()\n });\n this.player.progressReporterPlugin({\n onFlush: (this.onFlushProgress = this.onFlushProgress.bind(this))\n });\n this.player.persistVolumePlugin();\n\n if (!this.options.mobile && this.options.allowFullscreen)\n this.player.fullscreenOnRotatePlugin();\n\n this.player.touchControls();\n\n if (this.options.getExternalLink) {\n this.player.openExternallyPlugin({\n getExternalLink: this.options.getExternalLink\n });\n }\n \n this.configurePlugins();\n }\n protected configurePlugins(): void { }\n\n protected onFlushProgress(events: ProgressEventPair[]): void {\n this.analyticsService?.logVideoProgress(events);\n }\n\n protected buildVideoJs(): VideoJsPlayer {\n return (this.player = videojs(this.el, this.getPlayerOptions()));\n }\n\n private getInactivityTimeout(): number {\n if (typeof this.options.inactivityTimeout === 'number')\n return this.options.inactivityTimeout;\n\n let inactivityTimeout = 500;\n\n if (this.options.mobile || videojs.browser.IS_IOS || videojs.browser.IS_ANDROID)\n inactivityTimeout = 3000;\n\n return inactivityTimeout;\n }\n\n private getFluid(): boolean {\n if (this.options.theatreMode)\n return false;\n\n if (this.options.embed || this.options.mobile)\n return false;\n\n return true;\n }\n\n private getFill(): boolean {\n if (this.options.theatreMode)\n return true;\n\n if (this.options.embed || this.options.mobile)\n return true;\n\n return false;\n }\n\n protected getPlayerOptions(): VideoJsPlayerOptions {\n let baseChildren = Player.prototype.options_.children;\n\n /**\n * We removed the play button and poster image\n * because we add these in either when autoplay\n * fails or if autoplay is disabled and we have our\n * playbackObject\n */\n baseChildren = baseChildren.filter(c => {\n if (c === 'bigPlayButton' || c === 'posterImage')\n return false;\n return true;\n });\n\n return {\n controls: this.options.controls,\n fluid: this.getFluid(),\n fill: this.getFill(),\n inactivityTimeout: this.getInactivityTimeout(),\n controlBar: {\n children: [\n 'timeWrapper',\n 'progressControl'\n ]\n },\n children: [\n ...baseChildren,\n {\n name: 'collapserator',\n children: COLLAPSERATOR_CHILDREN.filter(child => {\n if (child === 'fullscreenToggle' && !this.options.allowFullscreen)\n return false;\n\n return true;\n })\n },\n 'playPauseFeedback',\n 'controlBarGradient'\n ],\n userActions: {\n hotkeys: event => handleHotKeys(event, this.player, this.options)\n },\n playbackRates: this.options.playbackRates,\n techOrder: ['html5'],\n html5: {\n nativeTextTracks: false // If true, interactives, chapters and POIs don't work in Safari\n },\n playsinline: true, // Prevents auto-fullscreen on iPhone Safari\n aspectRatio: this.options.aspectRatio,\n mobile: this.options.mobile,\n allowTheatreMode: this.options.allowTheatreMode,\n deferMenus: this.options.deferMenus,\n muted: this.options.muted,\n devicesConfig: this.options.devicesConfig\n };\n }\n\n protected async getPlaybackObject(): Promise<PlaybackObject> {\n if (this.options.offlinePlaybackObject)\n return this.options.offlinePlaybackObject;\n\n let fetchFn = this.options.fetch;\n\n // if we have no fetch function on the options, create our own\n if (this.options.fetch === undefined) {\n fetchFn = (viewKey: string) => {\n const fetchUrl = `${this.options.playerApi.origin}/api/playback?viewKey=${viewKey}`;\n return AjaxHelper.get<PlaybackObject>(fetchUrl);\n };\n }\n\n // ensure we have a viewkey\n if (!this.options.viewKey) {\n throw new Error('Please specify a viewKey or a fetch function');\n }\n\n // fetch the playback object using the fetch function\n const playbackObject = await fetchFn(this.options.viewKey);\n\n if (!playbackObject)\n throw new Error('Error fetching playback object');\n\n return playbackObject;\n }\n\n private setChaptersInternal(chapters: Chapter[], triggerUpdate: boolean): void {\n let track = TrackHelper.getTrack(this.player, 'chapters', null) as any;\n\n if (!track)\n track = this.player.addTextTrack('chapters') as any;\n\n const cues = [...track.cues.cues_];\n cues.forEach(cue => track.removeCue(cue));\n chapters.forEach(chapter => {\n track.addCue({\n startTime: chapter.timestamp,\n endTime: chapter.endTimestamp,\n text: chapter.name\n });\n });\n\n if (triggerUpdate)\n track.trigger({ type: 'cv:cuechange', target: track });\n\n track.trigger({ type: 'loadeddata', target: track });\n }\n public setChapters(chapters: Chapter[]): void {\n this.setChaptersInternal(chapters, true);\n }\n\n public setPlayerMode(location: PlayerMode, onButtonClickCallback: () => void): void {\n this.player.playerModePlugin().setPlayerMode(location, onButtonClickCallback);\n }\n\n public setFavourite(isFavourited: boolean, onClickFavourite: (isFavourited: boolean) => void): void {\n const plugin = this.player.favouritePlugin();\n plugin.setFavourite(isFavourited, onClickFavourite);\n }\n\n protected async fetch(): Promise<void> {\n const playbackObject = await this.getPlaybackObject();\n\n if (this.isDisposed())\n return;\n\n const isClip = playbackObject.mediaType === 'MasterClip';\n const isInteractiveClip = playbackObject.additionalData?.clipData;\n\n // add chapters if we have any except for clips/interactive clips\n if (playbackObject.chapters?.list?.length > 0 && !isClip && !isInteractiveClip)\n this.setChaptersInternal(playbackObject.chapters.list, false);\n\n // setup local cache\n this.player.localCache({\n localCacheAddresses: playbackObject.localCacheAddresses ?? [],\n enabled: this.options.enableLocalCache ?? true\n });\n\n // add sources\n this.player.progressiveFiles({\n sources: playbackObject.files.progressive.map(file => <Source>{\n id: file.profile,\n mimeType: file.mimeType,\n url: file.url\n })\n });\n\n // handle our network errors\n this.player.handleNetworkErrors({\n playerApi: this.options.playerApi,\n fileToken: playbackObject.files.fileToken\n });\n\n // add subtitles\n if (playbackObject.subtitles.list.length > 0) {\n playbackObject.subtitles.list.forEach(subtitle => {\n // we only support vtt subtitles\n if (subtitle.mimeType !== 'text/vtt')\n return;\n\n const trackElement = this.player.addRemoteTextTrack({\n kind: 'subtitles',\n src: subtitle.url,\n language: subtitle.language,\n label: subtitle.label\n }, true);\n\n TrackHelper.sanitizeTrack(trackElement.track, this.player);\n TrackHelper.activeTextTrack(trackElement.track);\n });\n }\n\n if (playbackObject.posterUrl)\n this.player.poster(ImageHelper.createUrl(playbackObject.posterUrl, { size: ImageSize.Large }));\n\n this.setupSplash({\n title: playbackObject.title,\n posterUrl: playbackObject.posterUrl,\n episodeNumber: playbackObject.episodeNumber,\n ratingCode: playbackObject.ratingCode,\n seasonNumber: playbackObject.seasonNumber,\n seriesName: playbackObject.seriesName\n });\n\n this.additionalSetup(playbackObject);\n\n this.handleAutoplay(playbackObject);\n\n if (this.options.startTime) {\n /**\n * It seems that seeking to a time before the player starts does not work on all browsers, and the current workaround\n * implemented in videojs is not consistent across browsers. Hence we're waiting for the player to be ready before\n * setting the current time.\n * \n * We set the current time initially for all the player UI, and then set the time again when the tech is ready. 🤮\n * \n * References:\n * https://github.com/videojs/video.js/pull/6507\n * https://github.com/videojs/video.js/blob/32630d964b3fc502143a935c219d092eb683fce0/src/js/player.js#L1737\n */\n this.player.currentTime(this.options.startTime);\n this.player.one('canplay', () => {\n this.player.currentTime(this.options.startTime);\n });\n }\n\n this.player.trigger('cv-playback-data-loaded', playbackObject);\n }\n\n protected handleFetchError(error: Error): void {\n let message = error.message;\n\n if (error instanceof ApiError && error.response?.type === PlayerApiErrorType.PhysicallyChapteredVideo)\n message = 'Video cannot be played because it is either corrupt or damaged.';\n\n this.player.error(message);\n\n if (this.options.onError)\n this.options.onError(error);\n }\n\n private async fetchConfig(): Promise<void> {\n if (config || this.options.fetch || this.options.offlinePlaybackObject)\n return;\n\n const fetchUrl = `${this.options.playerApi.origin}/api/config`;\n\n config = await AjaxHelper.get<Config>(fetchUrl);\n\n if (this.isDisposed())\n return;\n\n this.trigger('config:loaded');\n }\n\n protected additionalSetup(playbackObject: PlaybackObject): void {\n this.player.whiteboardModePlugin();\n this.player.deferMenusPlugin();\n // this.player.chromecast({\n // title: playbackObject.title\n // });\n\n const isUsingLocalCache = this.options.enableLocalCache && !!playbackObject.localCacheAddresses?.length;\n\n if (config)\n this.setupAnalyticsService(playbackObject, isUsingLocalCache);\n else\n this.one('config:loaded', () => this.setupAnalyticsService(playbackObject, isUsingLocalCache));\n\n // Setup plugins that may collect analytics data\n if (this.analyticsService || !this.isAnalyticsEnabled())\n this.setupAnalyticsDependentPlugins(playbackObject);\n else\n this.one('analytics:loaded', () => this.setupAnalyticsDependentPlugins(playbackObject));\n }\n\n private setupAnalyticsService(playbackObject: PlaybackObject, isUsingLocalCache: boolean): void {\n if (!this.options.eventLogging)\n return;\n\n this.analyticsService = new AnalyticsService({\n collectionApiUrls: config.collectionApi.urls,\n collectionApiClientId: config.collectionApi.clientId,\n productVersion: packageInfo.version,\n videoId: playbackObject.videoId,\n mediaId: playbackObject.mediaId,\n userId: playbackObject.viewerId,\n shareId: playbackObject.shareId,\n customerId: playbackObject.viewerCustomerId,\n mediaType: playbackObject.mediaType,\n playerType: this.getAnalyticsPlayerType(),\n isEmbedded: this.options.embed,\n isUsingLocalCache: isUsingLocalCache,\n additionalAnalyticsData: this.getAdditionalAnalyticsData(playbackObject),\n /**\n * The instance region for public views is pulled off the share object for the time being,\n * so it is being passed into the player as a property, in future we will need a more sophisticated IP look up system\n * - Sha\n */\n regionName: playbackObject.instanceRegion\n || (this.options.sharerInstanceRegion as RegionName)\n || RegionName.CvApSoutheast1\n });\n\n this.on('timeupdate', this.logStream);\n \n this.trigger('analytics:loaded');\n }\n\n protected setupAnalyticsDependentPlugins(playbackObject: PlaybackObject): void {\n this.player.persistSubtitleSettingsPlugin({\n showSubtitles: playbackObject.settings?.showSubtitles,\n subtitleSize: playbackObject.settings?.playbackSubtitleSizeDefault as SubtitleSizes,\n analyticsService: this.analyticsService\n });\n \n // Settings will be null when playing publicly\n this.player.persistQualitySettingsPlugin({\n playbackProfile: playbackObject.settings?.playbackProfile,\n playbackProfileLocalCache: playbackObject.settings?.playbackProfileLocalCache,\n analyticsService: this.analyticsService\n });\n\n this.player.persistPlaybackRatePlugin({\n analyticsService: this.analyticsService\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected getAdditionalAnalyticsData(playbackObject: PlaybackObject): HashObject {\n return {};\n }\n\n protected isAnalyticsEnabled(): boolean {\n if (this.options.fetch) return false;\n if (this.options.offlinePlaybackObject) return false;\n\n return this.options.eventLogging;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected handleAutoplay(playbackObject: PlaybackObject): void {\n if (!this.options.autoplay)\n return;\n\n this.player.ready(() => {\n this.player.play().catch(() => {\n if (this.isDisposed())\n return;\n\n this.showSplash();\n });\n });\n }\n\n protected logStream(): void {\n if (!this.analyticsService)\n return;\n\n if (this.player.currentTime() < LOG_STREAM_TIME_THRESHOLD || this.streamLogged)\n return;\n\n this.analyticsService.logStream();\n\n this.streamLogged = true;\n this.off('timeupdate', this.logStream);\n }\n\n protected getAnalyticsPlayerType(): AnalyticsPlayerType {\n return 'player';\n }\n\n protected createEl(id: string | Element): HTMLVideoElement {\n let tag: Element;\n if (typeof id === 'string') {\n id = normalizeId(id);\n tag = videojs.dom.$('#' + id);\n } else {\n tag = id;\n }\n\n let className = 'video-js';\n\n if (this.getPlayerClassName())\n className += ` ${this.getPlayerClassName()}`;\n\n this.el = videojs.dom.createEl('video', {}, {\n class: className\n }) as HTMLVideoElement;\n\n tag.appendChild(this.el);\n\n return this.el;\n }\n\n protected getPlayerClassName(): string {\n return '';\n }\n\n public on(type: string | string[], listener: (...args: any[]) => void): void {\n this.player.on(type, listener);\n }\n\n public one(type: string | string[], listener: (...args: any[]) => void): void {\n this.player.one(type, listener);\n }\n\n public off(type: string | string[], listener: (...args: any[]) => void): void {\n this.player.off(type, listener);\n }\n\n public trigger(event: any, hash?: any): boolean {\n return this.player.trigger(event, hash);\n }\n\n public dispose(): void {\n this.player.dispose();\n }\n\n public ready(callback: () => void): void {\n this.player.ready(callback);\n }\n\n public isDisposed(): boolean {\n return (this.player as any).isDisposed();\n }\n\n public play(): void {\n this.player.play();\n }\n\n public pause(): void {\n this.player.pause();\n }\n\n public isPaused(): boolean {\n return this.player.paused();\n }\n\n public currentTime(time?: number): number | void {\n return this.player.currentTime(time);\n }\n\n public muted(muted?: boolean): boolean | void {\n return this.player.muted(muted);\n }\n\n public duration(): number {\n return this.player.duration();\n }\n\n public isFullscreen(): boolean {\n return this.player.isFullscreen();\n }\n\n public requestFullscreen(): void {\n this.player.requestFullscreen();\n }\n\n public exitFullscreen(): void {\n this.player.exitFullscreen();\n }\n\n public playbackRate(): number;\n public playbackRate(rate: number): void;\n public playbackRate(rate?: number): number | void {\n return this.player.playbackRate(rate);\n }\n\n public quality(): string;\n public quality(id: string): void;\n public quality(id?: string): string | void {\n const qualityLevels = this.player.qualityLevels();\n\n for (let i = 0; i < qualityLevels.length; i++) {\n const qualityLevel = qualityLevels[i];\n\n if (id) {\n qualityLevel.enabled = qualityLevel.id === id.toString();\n continue;\n }\n\n if (qualityLevel.enabled)\n return qualityLevel.id;\n }\n }\n\n public subtitles(): string;\n public subtitles(label: string): void;\n public subtitles(label?: string): void | string {\n const tracks = this.player.textTracks();\n\n for (let i = 0; i < tracks.length; i++) {\n const track = tracks[i];\n\n if (label !== undefined) {\n if (track.label === label) {\n track.mode = 'showing';\n } else {\n track.mode = 'hidden';\n }\n continue;\n }\n\n if (track.mode === 'showing')\n return track.label;\n }\n }\n\n private bindEventListeners(): void {\n const preventDefaultListener = (event: MouseEvent) => event.preventDefault();\n\n this.showSplash = this.showSplash.bind(this);\n this.hideSplash = this.hideSplash.bind(this);\n this.player.on('ended', this.showSplash);\n this.player.on('play', this.hideSplash);\n\n this.player.tech(true).on('contextmenu', preventDefaultListener);\n\n this.player.one('dispose', () => {\n this.off('ended', this.showSplash);\n this.off('play', this.hideSplash);\n this.player.tech(true).off('contextmenu', preventDefaultListener);\n });\n\n if (!this.options.hotkeyElQuerySelector)\n return;\n\n const hotkeyEl = videojs.dom.$(this.options.hotkeyElQuerySelector);\n\n if (!hotkeyEl)\n return;\n\n this.player.on(hotkeyEl, 'keydown', (this.player as any).handleKeyDown);\n\n this.player.one('dispose', () => {\n this.player.off(hotkeyEl, 'keydown', (this.player as any).handleKeyDown);\n });\n }\n\n private setupSeekBar(): void {\n const name = this.getSeekBarName();\n const progressControl = this.player.controlBar.getChild('progressControl') as ProgressControl;\n progressControl.addChild(name, this.getSeekBarOptions());\n progressControl.setSeekBarName(name);\n }\n\n private _splashAdded: boolean;\n private setupSplash(splash: Splash): void {\n if (this._splashAdded)\n return;\n\n this._splashAdded = true;\n\n this.player.addChild('posterImage', {\n embed: this.options.embed,\n ...splash\n });\n this.player.addChild('bigPlayButton');\n\n if (!this.options.autoplay)\n this.showSplash();\n else\n this.hideSplash();\n }\n\n protected showSplash(): void {\n this.player.hasStarted(false);\n this.player.getChild('posterImage').show();\n this.player.getChild('bigPlayButton').show();\n }\n\n private hideSplash(): void {\n this.player.getChild('posterImage').hide();\n this.player.getChild('bigPlayButton').hide();\n }\n\n protected getSeekBarOptions(): any {\n return {};\n }\n\n protected getSeekBarName(): string {\n return 'ChapterSeekBar';\n }\n}\n","import videojs from 'video.js';\n\nimport { COMPONENT_PREVENT_SCRUBBING_TOOLTIP, NO_SKIPPING_AHEAD_TEXT } from 'projects/player/plugins/prevent-scrubbing-plugin/utils/prevent-scrubbing-helper';\n\nimport './prevent-scrubbing-tooltip.scss';\n\nconst Component = videojs.getComponent('Component');\n\nconst TOOLTIP_SHOW_CLASS = 'cv-prevent-scrubbing-tooltip-show';\nconst TOOLTIP_REMOVE_TRANSITION_CLASS = 'cv-prevent-scrubbing-tooltip-remove-transition';\n\nexport class PreventScrubbingTooltip extends Component {\n private isShowing: boolean = false;\n\n public buildCSSClass(): string {\n return `cv-prevent-scrubbing-tooltip ${super.buildCSSClass()}`;\n }\n\n public createEl(tagName?: string, properties?: any, attributes?: any): Element {\n return super.createEl(tagName, {\n ...properties,\n className: this.buildCSSClass(),\n innerText: NO_SKIPPING_AHEAD_TEXT\n }, attributes);\n }\n\n public show() {\n if (this.isShowing) {\n return;\n }\n \n this.player_.userActive(true);\n this.addClass(TOOLTIP_SHOW_CLASS);\n this.isShowing = true;\n }\n \n public hide(immediately: boolean = false) {\n if (!this.isShowing) {\n return;\n }\n\n if (immediately) {\n this.addClass(TOOLTIP_REMOVE_TRANSITION_CLASS);\n window.requestAnimationFrame(() => {\n this.removeClass(TOOLTIP_REMOVE_TRANSITION_CLASS);\n });\n }\n\n this.player_.userActive(false);\n this.removeClass(TOOLTIP_SHOW_CLASS);\n this.isShowing = false;\n }\n}\n\nvideojs.registerComponent(COMPONENT_PREVENT_SCRUBBING_TOOLTIP, PreventScrubbingTooltip);","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { MouseTimeDisplay } from 'projects/player/components/mouse-time-display/mouse-time-display';\nimport { ProgressControl } from 'projects/player/components/progress-control/progress-control';\nimport { PreventScrubbingTooltip } from 'projects/player/plugins/prevent-scrubbing-plugin/components/prevent-scrubbing-tooltip';\nimport { COMPONENT_PREVENT_SCRUBBING_TOOLTIP, MOUSE_TIME_DURATION } from 'projects/player/plugins/prevent-scrubbing-plugin/utils/prevent-scrubbing-helper';\nimport { debounce } from 'projects/player/utils/fn';\n\nimport './components/prevent-scrubbing-tooltip';\n\nconst Plugin = videojs.getPlugin('plugin');\n\ninterface PreventScrubbingPluginOptions {\n isEnabled: boolean;\n furthestVisitedTime?: number;\n}\n\nexport class PreventScrubbingPlugin extends Plugin {\n private playerCurrentTimeFn: (seconds?: number, ...args: any[]) => number;\n public isEnabled: boolean = false;\n public isPreviewing: boolean = false;\n public furthestVisitedTime: number;\n\n constructor(player: VideoJsPlayer, options?: PreventScrubbingPluginOptions) {\n super(player);\n\n const {\n furthestVisitedTime = 0,\n isEnabled = false\n } = options ?? {};\n\n // save old player functions\n this.playerCurrentTimeFn = this.player.currentTime.bind(player);\n\n // overwrite the base player function with our new fancy ones\n this.player.currentTime = this.currentTime.bind(this);\n\n this.onTimeUpdate = this.onTimeUpdate.bind(this);\n\n this.furthestVisitedTime = furthestVisitedTime;\n this.isEnabled = isEnabled;\n\n if (isEnabled) {\n this.enable();\n }\n }\n\n public dispose(): void {\n // put the original functions back\n this.player.currentTime = this.playerCurrentTimeFn;\n \n if (!this.isEnabled) {\n return;\n }\n\n this.disable();\n super.dispose();\n }\n\n public togglePreview(isSetToPreview: boolean) {\n if (isSetToPreview) {\n this.configurePreview();\n\n if (this.isEnabled) {\n return;\n }\n \n this.enable();\n this.isPreviewing = true;\n } else {\n this.disable();\n this.isPreviewing = false;\n }\n }\n\n private configurePreview() {\n this.player.currentTime(0);\n this.furthestVisitedTime = 0;\n }\n\n private enable(): void {\n this.player.on('timeupdate', this.onTimeUpdate);\n this.getProgressControl().addChild(COMPONENT_PREVENT_SCRUBBING_TOOLTIP);\n this.isEnabled = true;\n }\n \n private disable(): void {\n this.player.off('timeupdate', this.onTimeUpdate);\n this.getProgressControl().removeChild(this.getPreventScrubbingTooltip());\n this.isEnabled = false;\n }\n\n private getProgressControl(): ProgressControl {\n return this.player.controlBar.getChild('progressControl') as ProgressControl;\n }\n\n private onTimeUpdate(): void {\n const currentTime = this.playerCurrentTimeFn();\n \n if (currentTime > this.furthestVisitedTime) {\n this.furthestVisitedTime = currentTime;\n }\n }\n\n public currentTime(seconds: number, ...args: any[]): void;\n public currentTime(): number ;\n public currentTime(seconds?: any, ...args: any[]): any {\n if (typeof seconds !== 'number') {\n return this.playerCurrentTimeFn(seconds, ...args);\n }\n\n if (!this.isEnabled) {\n this.playerCurrentTimeFn(seconds, ...args);\n return;\n }\n\n const preventScrubbingTooltip = this.getPreventScrubbingTooltip();\n const mouseTimeDisplay = this.getSeekBar()\n ?.getChild('MouseTimeDisplay') as MouseTimeDisplay;\n \n if (seconds > this.furthestVisitedTime) {\n preventScrubbingTooltip.show();\n debounce(preventScrubbingTooltip.hide, MOUSE_TIME_DURATION, false, preventScrubbingTooltip)();\n mouseTimeDisplay?.hide();\n this.playerCurrentTimeFn(this.furthestVisitedTime, args);\n\n return;\n }\n\n mouseTimeDisplay?.show();\n preventScrubbingTooltip.hide(true);\n this.playerCurrentTimeFn(seconds, args);\n }\n\n public getPreventScrubbingTooltip(): PreventScrubbingTooltip {\n return this.getProgressControl().getChild(COMPONENT_PREVENT_SCRUBBING_TOOLTIP) as PreventScrubbingTooltip;\n }\n \n private getSeekBar(): videojs.SeekBar {\n return this.player.controlBar\n .getChild('ProgressControl')\n ?.getChild('SeekBar') as videojs.SeekBar;\n }\n}\n\nvideojs.registerPlugin('preventScrubbingPlugin', PreventScrubbingPlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n preventScrubbingPlugin(): PreventScrubbingPlugin;\n preventScrubbingPlugin(options: PreventScrubbingPluginOptions): void;\n }\n}","export const NO_SKIPPING_AHEAD_TEXT = 'No skipping ahead!';\nexport const COMPONENT_PREVENT_SCRUBBING_TOOLTIP = 'PreventScrubbingTooltip';\nexport const MOUSE_TIME_DURATION = 1000;","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { CollapsibleComponent } from 'projects/player/interfaces/CollapsibleComponent';\n\nimport './theatre-mode-button.scss';\n\nconst MenuButton = videojs.getComponent('MenuButton') as unknown as typeof videojs.MenuButton;\nconst MIN_WIDTH = 992;\nexport const THEATRE_MODE_CONTROL_TEXT = 'Theatre mode (t)';\nexport const DEFAULT_MODE_CONTROL_TEXT = 'Default mode';\n\nexport const THEATRE_MODE_ACTIVE_CLASS = 'cv-theatre-mode-button';\n\nclass TheatreModeButton extends MenuButton implements CollapsibleComponent {\n constructor(player: VideoJsPlayer, options: videojs.ComponentOptions) {\n super(player, options);\n this.updateControlText();\n }\n\n public controlText_: string;\n\n /**\n * CollapsibleComponent interface implementation below\n */\n public alwaysCollapsed: boolean = false;\n\n public isCollapsed: boolean = false;\n\n public isCollabsible: boolean = true;\n\n public getCollabsibleName(): string {\n return '';\n }\n \n public getCollabsibleValue(): string {\n return '';\n }\n \n public showInCollabsibleMenu(): boolean {\n if (window.innerWidth < MIN_WIDTH) {\n return false;\n }\n return true;\n }\n \n public showCollapsibleMenu(): void {\n super.handleClick(null);\n }\n\n public buildCSSClass(): string {\n return `cv-default-mode-button ${super.buildCSSClass()}`;\n }\n\n public buildWrapperCSSClass() {\n return `cv-menu-big ${super.buildWrapperCSSClass()}`;\n }\n\n public handleClick(): void {\n this.player_.theatreModePlugin().toggleTheatreMode();\n this.updateControlText();\n }\n\n public updateControlText() {\n if (this.player().theatreModePlugin().getTheatreMode()) {\n this.controlText(DEFAULT_MODE_CONTROL_TEXT);\n } else {\n this.controlText(THEATRE_MODE_CONTROL_TEXT);\n }\n }\n}\n\nvideojs.registerComponent('theatreModeButton', TheatreModeButton);","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { DEFAULT_MODE_CONTROL_TEXT, THEATRE_MODE_ACTIVE_CLASS, THEATRE_MODE_CONTROL_TEXT } from 'projects/player/plugins/theatre-mode-plugin/components/theatre-mode-button';\n\nconst Plugin = videojs.getPlugin('plugin');\nconst MIN_WIDTH = 992;\n\ninterface TheatreModePluginOptions {\n onRequestTheatreMode: (isTheatreMode: boolean) => void;\n theatreMode: boolean;\n}\n\nexport class TheatreModePlugin extends Plugin {\n private options: TheatreModePluginOptions;\n private button: videojs.Component;\n\n constructor(player: VideoJsPlayer, options: TheatreModePluginOptions) {\n super(player, options);\n this.options = options;\n\n this.bindListeners();\n player.ready(() => this.onReady());\n }\n\n private bindListeners(): void {\n this.onResize = this.onResize.bind(this);\n this.onFullscreenChange = this.onFullscreenChange.bind(this);\n\n this.player.on('playerresize', this.onResize);\n this.player.on('fullscreenchange', this.onFullscreenChange);\n }\n\n private onReady(): void {\n if (!this.options)\n return;\n\n if (window.innerWidth < MIN_WIDTH)\n return;\n\n const collapserator = this.getCollapserator();\n if (!collapserator)\n return;\n\n this.button = this.createButton();\n\n const theatreMode = this.options.theatreMode;\n if (theatreMode) {\n this.button?.addClass(THEATRE_MODE_ACTIVE_CLASS);\n this.options.onRequestTheatreMode(theatreMode);\n }\n }\n\n public dispose(): void {\n this.player.off('playerresize', this.onResize);\n this.player.off('fullscreenchange', this.onFullscreenChange);\n \n super.dispose();\n }\n\n public toggleTheatreMode(status?: boolean): boolean {\n if (!this.options)\n return;\n\n const currentMode = this.options.theatreMode;\n const nextMode = status !== undefined ? status : !currentMode;\n\n this.options.onRequestTheatreMode(nextMode);\n this.options.theatreMode = nextMode;\n\n if (!this.button)\n return;\n\n if (!nextMode) {\n if (currentMode) {\n this.player.fluid(true);\n }\n this.button?.removeClass(THEATRE_MODE_ACTIVE_CLASS);\n (this.button as any).updateControlText(DEFAULT_MODE_CONTROL_TEXT);\n if (this.player.viewTranscriptPlugin)\n this.player.viewTranscriptPlugin().toggleTranscript(false);\n\n return nextMode;\n }\n\n if (!currentMode) {\n (this.player as any).fill(true);\n }\n this.button.addClass(THEATRE_MODE_ACTIVE_CLASS);\n (this.button as any).updateControlText(THEATRE_MODE_CONTROL_TEXT);\n \n return nextMode;\n }\n\n private onResize(): void {\n if (window.innerWidth < MIN_WIDTH) {\n this.button?.hide();\n } else {\n if (!this.player.isFullscreen()) {\n // if the plugin is not initialzed with the button now we need to create one\n if (!this.button) {\n this.button = this.createButton();\n }\n this.button?.show();\n }\n }\n }\n\n private createButton(): videojs.Component {\n const collapserator = this.getCollapserator();\n const button = collapserator?.getChild('theatreModeButton');\n\n if (!button) {\n collapserator.addChild('theatreModeButton', {\n }, collapserator.children_.length - 3);\n }\n return collapserator?.getChild('theatreModeButton');\n }\n\n private onFullscreenChange(): void {\n if (this.player.isFullscreen()) {\n this.button?.hide();\n } else {\n this.button?.show();\n }\n }\n\n private getCollapserator(): videojs.Component {\n return this.player.getChild('collapserator');\n }\n\n public getTheatreMode(): boolean {\n return this.options.theatreMode;\n }\n}\n\nvideojs.registerPlugin('theatreModePlugin', TheatreModePlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n theatreModePlugin(options?: TheatreModePluginOptions): TheatreModePlugin;\n }\n}","// extracted by mini-css-extract-plugin\nexport default {\"languageSelect\":\"rHbhp\",\"inputWithoutHighlight\":\"nJvbl\"};","import React from 'react';\nimport { Dropdown } from 'react-bootstrap';\n\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { TranscriptSearchBar } from 'libs/shared/components/play-page/transcription-header/transcript-search-bar/TranscriptSearchBar';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { DownloadHelper } from 'libs/shared/utils/DownloadHelper';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport styles from './transcript-header.scss';\n\ninterface LanguageOptions {\n label: string;\n value: string\n}\n\ninterface TranscriptProps {\n selectedLanguage: string\n languageOptions: LanguageOptions[],\n track: TextTrack;\n onChangeLanguage?: (language: string) => void;\n\n searchQuery: string;\n currentSearchResultIndex: number;\n onSearch: (query: string) => void;\n totalSearchResults: number;\n jumpToSearchResult: (searchResultIndex: number) => void;\n}\n\nexport function TranscriptHeader(props: TranscriptProps): React.ReactElement {\n const firstLanguage = props.languageOptions[0]?.label;\n const subtitleSrc = (props.track as any).src;\n const alerts = useAlerts();\n\n async function onDownload() {\n try {\n await DownloadHelper.downloadBlob(subtitleSrc, `Subtitles-${props.selectedLanguage}.vtt`);\n } catch {\n alerts.error('Error downloading transcript');\n }\n }\n\n return (\n <div className='d-flex px-1 mb-3'>\n <TranscriptSearchBar\n query={props.searchQuery}\n currentSearchResultIndex={props.currentSearchResultIndex}\n onSearch={props.onSearch}\n totalSearchResults={props.totalSearchResults}\n jumpToSearchResult={props.jumpToSearchResult}\n />\n \n <Tooltip\n spanHack\n title={props.languageOptions.length > 1 ? '' : `Only available in ${firstLanguage}`}\n >\n <Dropdown>\n <Dropdown.Toggle\n className={`text-dark ${styles.languageSelect}`}\n id='language-select'\n disabled={props.languageOptions?.length <= 1}\n variant='outline-dark'\n >\n <SvgContainer svgName={cvSvgLibrary.Globe} />\n </Dropdown.Toggle>\n <Dropdown.Menu\n className={styles.menu}\n aria-labelledby='language-select'\n >\n {props.languageOptions.map((item, idx) => {\n return (\n <Dropdown.Item\n key={idx}\n onClick={() => props.onChangeLanguage?.(item.value)}\n className='cursor-pointer'\n active={item.value === props.selectedLanguage}\n >\n {item.label}\n </Dropdown.Item>\n );\n })}\n </Dropdown.Menu >\n </Dropdown>\n </Tooltip>\n\n <IconButton\n svgName={cvSvgLibrary.Download}\n onClick={onDownload}\n className='position-relative d-flex align-items-center text-dark'\n >\n </IconButton>\n </div>\n );\n}","import React from 'react';\nimport Scrollbars from 'react-custom-scrollbars-2';\nimport { useVirtualizer } from '@tanstack/react-virtual';\nimport videojs, { VideoJsPlayer } from 'video.js';\n\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { useCurrentActiveCues } from 'libs/shared/components/play-page/transcription/hooks/useCurrentCues';\nimport { getDefaultTranscriptLanguage, SAVED_LANGUAGE_KEY } from 'libs/shared/components/play-page/transcription/hooks/useTranscriptionLanguage';\nimport { useTranscriptionScroll } from 'libs/shared/components/play-page/transcription/hooks/useTranscriptionScroll';\nimport { useTranscriptionSearch } from 'libs/shared/components/play-page/transcription/hooks/useTranscriptionSearch';\nimport { getTranscriptInitialState, HighlightedCue } from 'libs/shared/components/play-page/transcription/PlayPageTranscription';\nimport { VirtualisedTranscriptionList } from 'libs/shared/components/play-page/transcription/virtualised-transcription-list/VirtualisedTranscriptionList';\nimport { useHover } from 'libs/shared/hooks/UseHover';\nimport { Chapter } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { TranscriptHeader } from 'projects/player/plugins/transcript-plugin/components/transcript-header/TranscriptHeader';\nimport { TranscriptLanguageOptions } from 'projects/player/plugins/transcript-plugin/transcript-plugin';\nimport { getReactComponent } from 'projects/player/react/react-component';\nimport { LocalStorageHelper } from 'projects/player/utils/local-storage-helper';\n\nimport './transcript-component.scss';\n\ninterface TranscriptProps {\n toggleTranscript: (value?: boolean) => void\n showTranscript: boolean\n languageOptions: TranscriptLanguageOptions[],\n allTracks: TextTrack[]\n onSearch?: (query: string) => void;\n setStartTime?: (time: number) => void;\n chapters?: Chapter[];\n player: VideoJsPlayer;\n}\n\nfunction TranscriptComponent(props: TranscriptProps): React.ReactElement {\n const defaultLanguage = LocalStorageHelper.get(SAVED_LANGUAGE_KEY) || getDefaultTranscriptLanguage(props.allTracks);\n\n function getTrack() {\n return props.allTracks.find(track => track.language === defaultLanguage);\n }\n const [ track, setTrack ] = React.useState(() => getTrack());\n const [ selectedLanguage, setSelectedLanguage ] = React.useState(defaultLanguage);\n // search related\n const [ currentCueIndex, setCurrentCueIndex ] = React.useState<number>(-1);\n const [ shouldAutoScroll, setShouldAutoScroll ] = React.useState<boolean>(true);\n const [ highlightedCues, setHighlightedCues ] = React.useState<HighlightedCue[]>([]);\n\n const cuesToDisplay = React.useMemo(() => Array.from(track?.cues || []), [selectedLanguage]);\n\n const hasStarted = props.player.hasStarted();\n useCurrentActiveCues({\n currentTranscriptTrack: track,\n cuesToDisplay, setCurrentCueIndex,\n hasStarted\n });\n const scrollRef = React.useRef<Scrollbars>();\n const virtualizer = useVirtualizer({\n count: highlightedCues.length,\n getScrollElement: () => {\n return (scrollRef as any).current?.view;\n },\n estimateSize: () => 40,\n enabled: highlightedCues.length > 0\n });\n const items = virtualizer.getVirtualItems();\n\n const scrollToCue = useTranscriptionScroll(currentCueIndex, shouldAutoScroll, virtualizer);\n\n const {\n isSearching,\n searchQuery,\n totalSearchResults,\n jumpToSearchResult,\n onSearch,\n currentSearchResultIndex,\n resetSearchResults\n } = useTranscriptionSearch(\n cuesToDisplay,\n setInitialState,\n setHighlightedCues,\n scrollToCue\n );\n\n const [ containerRef, isContainerHovered ] = useHover<HTMLDivElement>();\n React.useEffect(() => {\n setShouldAutoScroll(!isContainerHovered && !isSearching && hasStarted);\n }, [ isContainerHovered, isSearching, hasStarted ]);\n\n function setInitialState(): void {\n setHighlightedCues(getTranscriptInitialState(cuesToDisplay));\n }\n\n React.useEffect(() => {\n setInitialState();\n }, [cuesToDisplay]);\n\n // callbacks\n function onCloseTranscript() {\n props.toggleTranscript(false);\n }\n\n function onChangeLanguage(lan: string) {\n setTrack(props.allTracks.find(track => track.language === lan));\n setSelectedLanguage(lan);\n LocalStorageHelper.set(SAVED_LANGUAGE_KEY, lan);\n resetSearchResults();\n }\n\n function onClickTranscriptionItem(cue: TextTrackCue): void {\n props.setStartTime?.(cue.startTime);\n }\n\n if (!track || !cuesToDisplay.length)\n return <></>;\n\n return (\n <div ref={containerRef} className={`cv-transcript py-3 px-2 ${props.showTranscript ? 'cv-open' : ''}`}>\n <div className='text-dark d-flex justify-content-between px-1'>\n <h3>Transcript</h3>\n <IconButton svgName={cvSvgLibrary.Close} onClick={onCloseTranscript}></IconButton>\n </div>\n <TranscriptHeader\n selectedLanguage={selectedLanguage}\n languageOptions={props.languageOptions}\n onChangeLanguage={onChangeLanguage}\n track={track}\n onSearch={onSearch}\n searchQuery={searchQuery}\n currentSearchResultIndex={currentSearchResultIndex}\n totalSearchResults={totalSearchResults}\n jumpToSearchResult={jumpToSearchResult}\n />\n <div className='cv-transcript-list-wrapper text-dark'>\n <Scrollbars\n ref={scrollRef}\n >\n <VirtualisedTranscriptionList\n timepoint={cuesToDisplay[currentCueIndex]}\n onClickTranscriptionItem={onClickTranscriptionItem}\n cuesToDisplay={highlightedCues}\n chapters={props.chapters}\n currentSearchResultIndex={currentSearchResultIndex}\n inPlayer\n virtualizer={virtualizer}\n items={items}\n />\n </Scrollbars>\n </div>\n </div>\n );\n}\n\nvideojs.registerComponent(\n 'Transcript',\n getReactComponent((player: VideoJsPlayer, options: TranscriptProps) =>\n <TranscriptComponent player={player} {...options} />)\n);\n","import videojs, { VideoJsPlayer } from 'video.js';\n\nimport { PREFERABEL_LANGUAGE } from 'libs/shared/components/play-page/transcription/hooks/useTranscriptionLanguage';\n\nimport { TrackHelper } from 'projects/player/utils/track-helper';\n\nimport './components/transcript-component';\n\nconst Plugin = videojs.getPlugin('plugin');\n\nexport const MIN_WIDTH_WITH_TRANSCRIPT = 992;\n\nexport interface TranscriptLanguageOptions {\n label: string;\n value: string\n}\n\nclass TranscriptPlugin extends Plugin {\n private languageOptions: TranscriptLanguageOptions[];\n private component: videojs.Component;\n private allTracks: TextTrack[] = [];\n private showTranscript: boolean;\n private chapterTrack: TextTrack;\n\n constructor(player: VideoJsPlayer) {\n super(player);\n\n this.player = player;\n this.bindListeners();\n player.ready(() => this.initialize());\n }\n\n private bindListeners(): void {\n this.onResize = this.onResize.bind(this);\n \n // eslint-disable-next-line react-hooks/rules-of-hooks\n TrackHelper.useMetadataTracks(this.player, 'transcript', () => this.player.trigger('resizemenus'));\n\n this.player.on('playerresize', this.onResize);\n }\n\n public dispose(): void {\n this.player.off('playerresize', this.onResize);\n\n super.dispose();\n }\n\n private initialize(): void {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n TrackHelper.useSubtitles(this.player, this.onTrackLoaded.bind(this));\n // eslint-disable-next-line react-hooks/rules-of-hooks\n TrackHelper.useChapters(this.player, this.onChaptersLoaded.bind(this));\n }\n\n private onChaptersLoaded(chapter: TextTrack): void {\n this.chapterTrack = chapter;\n }\n\n private onTrackLoaded(track: TextTrack): void {\n if (!this.allTracks.find(subtitle => subtitle.language === track.language)) {\n this.allTracks.push(track);\n }\n\n this.languageOptions = this.buildOptions(this.allTracks || Array.from(this.player.textTracks() || []));\n }\n\n private buildOptions(subtitles: TextTrack[]): TranscriptLanguageOptions[] {\n return subtitles.map(subtitle => ({ label: subtitle.label, value: subtitle.language }))\n .sort((a, b) => {\n const aIsEnglish = a.value.includes(PREFERABEL_LANGUAGE) ? 1 : 0;\n const bIsEnglish = b.value.includes(PREFERABEL_LANGUAGE) ? 1 : 0;\n return bIsEnglish - aIsEnglish;\n });\n }\n\n private buildComponentProps(\n showTranscript: boolean,\n toggleTranscript: (value?: boolean) => void,\n setStartTime?: (time: number) => void\n ): any {\n const chapters = Array.from(this.chapterTrack?.cues || [])\n .map((t: any) => ({ endTimeStamp: t.endTime, startTime: t.startTime, name: t.text }));\n\n return {\n showTranscript,\n languageOptions: this.languageOptions,\n toggleTranscript,\n allTracks: this.allTracks,\n setStartTime,\n chapters\n };\n }\n\n private addChildren(showTranscript: boolean): videojs.Component {\n if (this.component) {\n this.component.show();\n return this.component;\n }\n const toggleTranscript = this.toggleTranscript.bind(this);\n const setStartTime = this.setStartTime.bind(this);\n\n const props = this.buildComponentProps(showTranscript, toggleTranscript, setStartTime);\n this.component = this.player.addChild('Transcript', props);\n }\n\n public toggleTranscript(value: boolean): void {\n const nextMode = value !== undefined ? value : !this.showTranscript;\n this.showTranscript = nextMode;\n\n if (nextMode) {\n // turn on the theatre mode first\n this.player.theatreModePlugin()?.toggleTheatreMode(true);\n this.addChildren(true);\n\n this.player.addClass('cv-transcript-plugin');\n } else {\n this.component?.hide();\n this.player.removeClass('cv-transcript-plugin');\n }\n\n if (this.player.whiteboardModePlugin) {\n this.player.whiteboardModePlugin().setEnabled(!nextMode);\n }\n\n this.player.trigger('cv-transcript-toggle', nextMode);\n // trigger resize\n this.player.trigger('resizemenus');\n this.player.trigger('playerresize');\n }\n\n private setStartTime(time: number): void {\n this.player.currentTime(time);\n }\n\n public isTranscriptOn(): boolean {\n return !!this.showTranscript;\n }\n\n private onResize(): void {\n if (window.innerWidth < MIN_WIDTH_WITH_TRANSCRIPT) {\n this.player.addClass('hide-transcript');\n return;\n }\n\n // show if transcript is on\n if (this.showTranscript) {\n this.player.removeClass('hide-transcript');\n }\n }\n}\n\nvideojs.registerPlugin('viewTranscriptPlugin', TranscriptPlugin);\n\ndeclare module 'video.js' {\n export interface VideoJsPlayer {\n viewTranscriptPlugin(): TranscriptPlugin;\n }\n}","import React from 'react';\nimport { createRoot, Root } from 'react-dom/client';\nimport videojs, { VideoJsPlayer } from 'video.js';\n\nimport { HashObject } from 'libs/common/react/interfaces';\n\nconst Component = videojs.getComponent('Component');\n\nclass BaseReactComponent<T> extends Component {\n public options_: T;\n\n protected root: Root;\n\n constructor(player: VideoJsPlayer, options: T) {\n super(player, options);\n }\n\n public dispose(): void {\n /*\n * Calling unmount asynchronously to avoid the following warning:\n * https://stackoverflow.com/questions/73043828/how-to-unmount-something-created-with-createroot-properly\n */\n setImmediate(() => {\n this.root?.unmount();\n });\n\n super.dispose();\n }\n}\n\ntype BaseReactComponentCtor<T> = new (player: VideoJsPlayer, options?: T) => videojs.Component;\n\ninterface RootNodeOptions {\n tagName?: string;\n properties?: any;\n attributes?: any;\n}\n\nconst defaultOptions: RootNodeOptions = {\n tagName: 'div'\n};\n\nexport function getReactComponent<T extends HashObject>(\n componentCtor: (player: VideoJsPlayer, options?: T) => React.ReactElement,\n options: RootNodeOptions = defaultOptions\n): BaseReactComponentCtor<T> {\n if (!componentCtor)\n throw new Error('componentCtor is required');\n\n class ReactComponent extends BaseReactComponent<T> {\n public createEl(): Element {\n const container = videojs.dom.createEl(options.tagName, options.properties, options.attributes);\n const root = createRoot(container);\n\n root.render(componentCtor(this.player_, this.options_));\n\n this.root = root;\n\n return container;\n }\n }\n\n return ReactComponent;\n}","export function mapRatingValueToColourClass(ratingValue: number): string {\n if (!ratingValue) return '';\n\n const ratings = (rating: number): string => {\n switch (true) {\n case (rating < 32):\n return 'cv-rating-purple';\n case (rating < 48):\n return 'cv-rating-green';\n case (rating < 80):\n return 'cv-rating-blue';\n case (rating < 96):\n return 'cv-rating-red';\n case (rating < 128):\n return 'cv-rating-pink';\n case (rating >= 128):\n return 'cv-rating-yellow';\n default:\n return ''; // Handles unrated\n }\n };\n\n return ratings(ratingValue);\n}","import { ApiError } from 'projects/player/interfaces/models/ApiError';\n\nexport interface AjaxOptions {\n tokenName?: TokenNames;\n}\n\ntype TokenNames = 'gateway';\n\nclass StaticAjaxHelper {\n private tokens?: {[name in TokenNames]: string} = {\n gateway: null\n };\n\n public async get<T>(url: string, options?: AjaxOptions): Promise<T> {\n return await this.parseResponse<T>(await fetch(url, {\n method: 'GET',\n mode: 'cors',\n headers: this.getHeaders(options)\n }));\n }\n\n public async delete(url: string, options?: AjaxOptions): Promise<void> {\n await fetch(url, {\n method: 'DELETE',\n headers: this.getHeaders(options)\n });\n }\n\n public async post<T>(\n url: string,\n body: any,\n options?: AjaxOptions,\n parseResponse: boolean = true\n ): Promise<T> {\n const response = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(options),\n body,\n mode: 'cors'\n });\n\n if (parseResponse)\n return await this.parseResponse<T>(response);\n }\n\n public async put<T>(\n url: string,\n body: any,\n options?: AjaxOptions,\n parseResponse: boolean = true\n ): Promise<T> {\n const response = await fetch(url, {\n method: 'PUT',\n headers: this.getHeaders(options),\n body,\n mode: 'cors'\n });\n\n if (parseResponse)\n return await this.parseResponse<T>(response);\n }\n\n public setToken(name: TokenNames, token: string): void {\n this.tokens[name] = token;\n }\n\n private getHeaders(options: AjaxOptions = {}): HeadersInit {\n const headers: HeadersInit = {\n 'Content-Type': 'application/json'\n };\n\n if (this.tokens[options.tokenName])\n headers.authorization = `Bearer ${this.tokens[options.tokenName]}`;\n\n return headers;\n }\n\n private async parseResponse<T>(response: Response): Promise<T> {\n // on 404, return null\n if (response.status === 404) {\n return null;\n }\n\n // any other status code throw an error\n if (!response.ok) {\n let body: any;\n try {\n body = await response.json();\n } catch {\n throw new ApiError(response.url);\n } finally {\n throw new ApiError(response.url, body);\n }\n }\n\n const value = await response.json();\n return value as T;\n }\n}\n\nexport const AjaxHelper = new StaticAjaxHelper();\n","/**\n * Wraps the given function, `fn`, with a new function that only invokes `fn`\n * at most once per every `wait` milliseconds.\n *\n * @function\n * @param {Function} fn\n * The function to be throttled.\n *\n * @param {number} wait\n * The number of milliseconds by which to throttle.\n *\n * @return {Function}\n */\nexport const throttle = function(fn: any, wait: any): any {\n let last = window.performance.now();\n\n const throttled = function(...args: any[]): any {\n const now = window.performance.now();\n\n if (now - last >= wait) {\n fn(...args);\n last = now;\n }\n };\n\n return throttled;\n};\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked.\n *\n * Inspired by lodash and underscore implementations.\n *\n * @function\n * @param {Function} func\n * The function to wrap with debounce behavior.\n *\n * @param {number} wait\n * The number of milliseconds to wait after the last invocation.\n *\n * @param {boolean} [leading]\n * When true will also invoke the function immediately upon creation.\n *\n * @param {Object} [context=window]\n * The \"context\" in which the debounced function should debounce. For\n * example, if this function should be tied to a Video.js player,\n * the player can be passed here. Alternatively, defaults to the\n * global `window` object.\n *\n * @return {Function}\n * A debounced function that returns true if the wrapped function was executed immediately.\n */\nexport const debounce = function(\n func: any,\n wait: any,\n leading: any,\n context: any = window\n): (...args: any[]) => boolean {\n let timeout: any;\n\n const cancel = () => {\n context.clearTimeout(timeout);\n timeout = null;\n };\n\n /* eslint-disable consistent-this */\n const debounced = (...args: any[]) => {\n let executed = false;\n\n let later = function() {\n timeout = null;\n later = null;\n func.apply(this, args);\n };\n\n if (!timeout && leading) {\n func.apply(this, args);\n executed = true;\n }\n\n context.clearTimeout(timeout);\n timeout = context.setTimeout(later, wait);\n\n return executed;\n };\n /* eslint-enable consistent-this */\n\n debounced.cancel = cancel;\n\n return debounced;\n};\n\n/**\n * A function that returns undefined.\n *\n * Inspired by lodash implementations.\n */\nexport const noop = function(): undefined {\n return undefined;\n};\n","/**\n * Direct copy from format-time.js within video.js\n * Unfortunately video.js doesn't expose this\n */\nexport function formatTime(seconds: number, guide: number = seconds): string {\n seconds = seconds < 0 ? 0 : seconds;\n let s: any = Math.floor(seconds % 60);\n let m: any = Math.floor(seconds / 60 % 60);\n let h: any = Math.floor(seconds / 3600);\n const gm = Math.floor(guide / 60 % 60);\n const gh = Math.floor(guide / 3600);\n\n // handle invalid times\n if (isNaN(seconds) || seconds === Infinity) {\n // '-' is false for all relational operators (e.g. <, >=) so this setting\n // will add the minimum number of fields specified by the guide\n h = m = s = '-';\n }\n\n // Check if we need to show hours\n h = (h > 0 || gh > 0) ? h + ':' : '';\n\n // If hours are showing, we may need to add a leading zero.\n // Always show at least one digit of minutes.\n m = (((h || gm >= 10) && m < 10) ? '0' + m : m) + ':';\n\n // Check if leading zero is need for seconds\n s = (s < 10) ? '0' + s : s;\n\n return h + m + s;\n}","import { VideoJsPlayer } from 'video.js';\n\nexport function getBufferedEnd(player: VideoJsPlayer): number {\n const buffered = player.buffered();\n const currentTime = player.currentTime();\n\n let bufferedEnd = 0;\n\n for (let i = 0; i < buffered.length; i++) {\n const start = buffered.start(i);\n const end = buffered.end(i);\n\n if (start <= currentTime && end >= currentTime) {\n bufferedEnd = end;\n break;\n }\n }\n\n return bufferedEnd;\n}","import { VideoJsPlayer } from 'video.js';\n\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\ntype TrackKind = 'metadata' | 'chapters' | 'subtitles';\ntype TrackLabel = 'interactive' | 'thumbnails' | 'pointsofinterest' | 'transcript' | false;\n\nfunction findTracks(tracks: TextTrackList, kind: TrackKind, label: TrackLabel, language?: string): TextTrack[] {\n if (!tracks.length)\n return [];\n\n const foundTracks: TextTrack[] = [];\n for (let i = tracks.length - 1; i >= 0; i--) {\n // We will always choose the last track as our chaptersTrack\n const track = tracks[i];\n\n if (track.kind === kind) {\n if (label && track.label !== label)\n continue;\n\n if (language && track.language !== language)\n continue;\n\n foundTracks.push(track);\n }\n }\n\n return foundTracks;\n}\n\nfunction onAddTrack(\n track: TextTrack,\n kind: TrackKind,\n label: TrackLabel,\n callback: (track: TextTrack) => void,\n language?: string\n): void {\n if (track.kind !== kind)\n return;\n\n if (label && track.label !== label)\n return;\n\n if (language && track.language !== language)\n return;\n\n if ((track as any).loaded_) {\n callback(track);\n return;\n }\n\n (track as any).one('loadeddata', () => {\n callback(track);\n });\n}\n\nfunction sanitizeTrack(track: TextTrack): void {\n if (!track?.cues.length)\n return;\n\n for (let i = 0; i < track.cues.length; i++) {\n const cue = track.cues[i] as any;\n\n if (!cue?.text)\n continue;\n\n cue.text = TextHelper.sanitize(cue.text);\n }\n}\n\nfunction useTrack(\n player: VideoJsPlayer,\n kind: 'metadata' | 'chapters',\n label: 'interactive' | 'thumbnails' | 'pointsofinterest',\n callback: (track: TextTrack) => void,\n language?: string\n): void {\n const tracks = player.textTracks();\n const t = findTracks(tracks, kind, label, language)[0];\n if (t) {\n onAddTrack(t, kind, label, callback);\n return;\n }\n\n const onAddTrackWrap = (event: any) => {\n onAddTrack(event.track, kind, label, callback);\n tracks.removeEventListener('addtrack', onAddTrackWrap);\n };\n\n tracks.addEventListener('addtrack', onAddTrackWrap);\n\n player.one('dispose', () => {\n tracks.removeEventListener('addtrack', onAddTrackWrap);\n });\n}\n\nfunction useTracks(\n player: VideoJsPlayer,\n kind: 'metadata' | 'subtitles',\n label: 'transcript',\n callback: (track: TextTrack) => void,\n language?: string\n): void {\n const tracks = player.textTracks();\n const foundTracks = findTracks(tracks, kind, label, language);\n\n if (foundTracks.length)\n foundTracks.forEach(t => onAddTrack(t, kind, label, callback, language));\n\n const onAddTrackWrap = (event: any) => {\n onAddTrack(event.track, kind, label, callback, language);\n };\n\n tracks.addEventListener('addtrack', onAddTrackWrap);\n\n player.one('dispose', () => {\n tracks.removeEventListener('addtrack', onAddTrackWrap);\n });\n}\n\nexport const TrackHelper = {\n getTrack(player: VideoJsPlayer, kind: TrackKind, label: TrackLabel, language?: string): TextTrack {\n const tracks = player.textTracks();\n return findTracks(tracks, kind, label, language)[0];\n },\n\n useChapters(\n player: VideoJsPlayer,\n callback: (track: TextTrack) => void\n ): void {\n useTrack(player, 'chapters', null, callback);\n },\n\n useMetadataTrack(\n player: VideoJsPlayer,\n label: 'interactive' | 'thumbnails' | 'pointsofinterest',\n callback: (track: TextTrack) => void\n ): void {\n useTrack(player, 'metadata', label, callback, null);\n },\n\n useMetadataTracks(\n player: VideoJsPlayer,\n label: 'transcript',\n callback: (track: TextTrack) => void,\n language?: string\n ): void {\n useTracks(player, 'metadata', label, callback, language);\n },\n\n useSubtitles(\n player: VideoJsPlayer,\n callback: (track: TextTrack) => void,\n language?: string\n ): void {\n useTracks(player, 'subtitles', null, callback, language);\n },\n\n getCurrentTextTrack(player: VideoJsPlayer): TextTrack {\n return this.findTrackByPredicate(player, (track: TextTrack) => track.mode === 'showing');\n },\n\n findTrackByPredicate(player: VideoJsPlayer, predicate: (track: TextTrack) => boolean): TextTrack {\n if (!player)\n return null;\n\n const tracks = player.textTracks();\n\n for (let i = 0; i < tracks.length; i++) {\n const track = tracks[i];\n\n if (predicate(track))\n return track;\n }\n\n return null;\n },\n\n forEachTrack(player: VideoJsPlayer, callback: (track: TextTrack) => void): void {\n if (!player)\n return;\n\n const tracks = player.textTracks();\n\n for (let i = 0; i < tracks.length; i++) {\n const track = tracks[i];\n callback(track);\n }\n },\n\n sanitizeTrack(track: TextTrack, player: VideoJsPlayer): void {\n if (!track || !player)\n return;\n\n if ((track as any).loaded) {\n sanitizeTrack(track);\n return;\n }\n\n const onLoadedData = () => sanitizeTrack(track);\n track.addEventListener('loadeddata', onLoadedData);\n player.one('dispose', () => {\n track.removeEventListener('loadeddata', onLoadedData);\n });\n },\n\n activeTextTrack(track: TextTrack): void {\n // transcript plugin rely on all tracks to be hidden instead of disabled\n if (track.mode === 'disabled' && track.kind === 'subtitles')\n track.mode = 'hidden';\n }\n};"],"names":["CollapsibleHeadingMenuItem","player","options","className","innerHTML","this","localize","options_","label","tabIndex","event","onClickBack","requestAnimationFrame","player_","getChild","pressButton","BaseMenu","baseMenuCreateEl","prototype","createEl","el","call","simpleBar","contentEl","autoHide","_contentEl","getContentElement","_dispose","dispose","unMount","_addItem","addItem","component","recalculate","_lockShowing","lockShowing","recalculateScrollBar","_handleBlur","handleBlur","relatedTarget","document","activeElement","contains","MenuItem","SearchInputMenuItem","onChange","bindEventListeners","placeholder","trim","$","focus","stopImmediatePropagation","bind","addEventListener","e","menuButton","menu","target","search","value","NoMatchingResultsMenuItem","tag","props","attrs","newLabel","span","ApiError","url","response","title","Error","CogMenuItem","item","showCollapsibleMenu","tagName","properties","attributes","getCollabsibleName","val","getCollabsibleValue","valueHolder_","appendChild","CogButton","controlText","deferMenus","deferMenusPlugin","deferMenu","children_","forEach","c","updateCollapsibleValue","items","i","length","isCollabsible","showInCollabsibleMenu","isCollapsed","push","additionalItems","menuItem","ctor","splice","index","trigger","some","name","update","SIZES","SubtitleSizeMenuItem","textTrackSettings","setSizeSetting","SubtitleSizeButton","alwaysCollapsed","ready","size","getSizeSetting","map","s","charAt","toUpperCase","substring","selectable","multiSelectable","selected","handleClick","apply","SubtitleResultMenuItem","matches","parts","progress","m","start","substr","join","currentTime","cue","startTime","SubtitleSearchButton","textTracks","track","removeEventListener","one","cues","text","noResults","hide","bindTrackEvents","findMatches","toggleItemVisibility","toggleNoResults","regex","RegExp","cueText","internalMatches","result","exec","slice","show","Object","keys","firstChild","shortcuts","type","KeyboardShortcutMenuItem","getDisplayHtml","KeyboardShortcutsButton","mobile","COLLAPSED_CLASS","Collapserator","addChild","on","off","addClass","removeClass","isFullscreen","side","whiteboardModePlugin","playerRect","getBoundingClientRect","comparisonEdge","width","height","toggleHidden","buildCSSClass","COLLAPSERATOR_CHILDREN","AnalyticsService","initialize","cacheKey","videoId","LocalStorageHelper","collectionApiClient","log","actionContext","getActionContext","data","getAnalyticsData","eventVersion","events","ev","analyticsData","analyticsOptions","actionType","video","id","flags","isUsingLocalCache","additionalAnalyticsData","shareId","entityType","getEntityType","interactive","mediaId","clip","setupCollectionApiClient","CollectionApiClient","productName","productVersion","regionName","collectionApiUrls","collectionApiClientId","getUser","getCurrentUser","shouldLog","CollectionApiClientHelper","formatData","userId","customerId","entity","location","getLocationContext","productArea","undefined","descriptor","isEmbedded","workflowPhase","mediaType","playerType","handlePlayPauseKey","paused","play","pause","handleSeekKey","step","handleVolumeKey","volume","PlayerApiErrorType","KeycodeHandlers","fsApi_","fullscreenEnabled","exitFullscreen","requestFullscreen","vol","lastVolume","lastVolume_","volumeToSet","muted","isTheatreMode","theatreModePlugin","getTheatreMode","toggleTheatreMode","ConfigureMenuDimensionsPlugin","configureMenuDimensions","resetVolumePanelToInline","setVolumeInline","collapserator","volumePanel","indexOf","removeChild","inline","playerWidth1","currentWidth","querySelectorAll","style","paddingTop","marginBottom","playerWidth","aspectRatio","currentHeight","controlBarEl","querySelector","menuEls","controlBarHeight","offsetHeight","seekBarName","overflowControls","VOLUME","MUTE","PersistVolumePlugin","enabled","removeVolumeControl","saveVolumeState","applyUserPreferences","mute","toString","PLAYBACK_RATE","PersistPlaybackRatePlugin","dataLoaded","savePlaybackRate","playbackRate","playbackRates","v","rate","analyticsService","logUserAction","FullscreenOnRotatePlugin","fullscreenBecauseOfRotate","supportsFullScreen","onRotate","onFullscreenChange","window","angle","getAngle","screen","orientation","ClickViewLogo","OpenExternallyButton","el_","href","getExternalLink","Math","round","createControlTextEl","controlText_","OpenExternallyPlugin","onReady","spacer","TouchControls","amount","timeout","isPositive","clearTimeout","timeoutId","setTimeout","removeText","TouchControlsPlugin","doubleTouchCount","seekStartTime","directionModifier","bindFunctions","onTouchStart","onTouchEnd","reBindEventListeners","unBindEventListeners","touchControls","tech","touchStartTime","timeStamp","userActive","changedTouches","lastTouchTime","onDoubleTouch","resetProperties","rect","middle","left","pageX","setUi","TIMEOUT","remainingTime","duration","ProgressiveRepresentation","plugin","source","currentSource","setSource","ProgressiveFilesPlugin","sources","qualityLevels","populateSources","onQualityChange","_currentSource","currentQuality","selectedIndex","getSourceById","isPlaying","hasStarted","src","mimeType","sourceChangeUpdateQualityLevels","find","removeQualityLevel","sort","a","b","selectSourceId","sortSources","addQualityLevel","selectedIndex_","QualityHelper","qualities","profile","quality","getQualityLevelById","getNextBestQuality","q","knownProfiles","getKnownProfiles","p","LocalCache","address","playbackProfile","URL","httpsAddress","encodeURIComponent","controller","AbortController","abort","fetch","method","mode","signal","LocalCacheMiddleware","logger","next","localCache","getActiveLocalCache","activeLocalCache","debug","getUrl","LocalCacheIconSvg","LocalCacheIndicator","onLocalCacheChange","localCachePlugin","LocalCachePlugin","logger_","localCaches_","localCacheAddresses","lca","enable","enabled_","resetActiveLocalCache","activeLocalCache_","clearActiveLocalCache","getActiveLocalCacheInternal","filter","l","controlBar","activeCache","ping","removeLocalCache","resetSource","onlineCaches","Promise","all","lc","profileChanged","enableProfileOrNextBest","HandleNetworkErrorsPlugin","playerApi","fileToken","bindErrorHandlers","onError","errorCode","error","code","MediaError","MEDIA_ERR_NETWORK","MEDIA_ERR_SRC_NOT_SUPPORTED","callErrorHandler","handleNetworkError","handleVideoSignatureExpiry","refetchedSourcesTimestamp","Date","now","files","fetchUrl","origin","progressiveFiles","repopulateSources","progressive","file","errorHandler","onLoadedMetadata","USER_SHOW_SUBTITLES","SELECTED_LANGUAGE","USER_SUBTITLE_SIZE","PersistSubtitleSettingsPlugin","showSubtitles","userShowSubtitles","safeGet","guessWhichTrack","hideSubtitles","subtitleSize","key","tracks","language","onSelectedLanguageChange","onChangeSubtitleSize","bestGuess","langOnlyMatch","selectedLanguage","navigator","getLanguageParts","userLanguage","userCountry","country","lang","langParts","toLowerCase","split","PersistQualitySettingsPlugin","playbackProfileLocalCache","userQuality","getStorageKey","onQualityLevelsChange","isLocalCacheActive","localCacheIsActive","ProgressItem","end","time","ProgressReporterDisplay","events_","children","Events","ProgressReporterPlugin","eventBuffer","latestTime","lastPlayingTime","isSeeking","hasEnded","shouldLogPlayOnTimeUpdate","validateOptions","bindListeners","startInterval","addEasterEgg","onFlush","eventHash","onPlay","onPause","onTimeUpdate","onSeeking","onEnded","onPlaying","k","interval","setInterval","flushBuffer","clearInterval","keyUpTimeout","touchTimeout","phrase","onKeyUp","addDisplay","touching","playToggle","progressReporterDisplay","inactivityTimeout","logEvent","pauseTimeout","previousLatestTime","eventType","current","shift","shouldClearCarriedOverTime","shouldSaveCarriedOverTime","shouldUseCarriedOverTime","validateEvents","addEvents","totalTime","DragHandle","WhiteboardSides","WhiteboardSideNames","top","right","bottom","DragTarget","class","dragover","preventDefault","dataTransfer","dropEffect","drop","setWhiteboardMode","dragleave","DragTargets","addChildren","WhiteboardModeMenuItem","WhiteboardModeButton","isEnabled","SIDE","WhiteboardModePlugin","initCollapserator","initDragTargets","initFullscreenListener","viewTranscriptPlugin","isTranscriptOn","dragHandle","button","mousedown","setAttribute","mouseup","dragstart","setData","dragend","documentElement","getSide","DeferMenusPlugin","info","subtitles","buildSubtitles","buildQualities","playbackSpeeds","buildPlaybackSpeeds","trackSelected","playerTracks","unshift","currentPlaybackRate","r","MUTE_CLASS","MuteButton","PlayerMode","PlayerOverlay","_onClickHandler","onClickHandler","PREVIEW_MODE_CLASS","PlayerModePlugin","buttonAdded","previousMode","Hover","addButtons","enableSubtites","removeActivityTimeout","disableSubtitles","unmute","restoreActivityTimeout","muteButton","playerOverlay","persistSubtitleSettingsPlugin","previewModeSubtitles","persistVolumePlugin","disable","cache_","ClickableComponent","FavouriteIcon","FavouriteButton","isFavourited","renderIcon","icon","onClick","FavouritePlugin","initialized","Menu","BaseMenuButton","string","hideThreshold_","titleEl","replace","w","titleComponent","createItems","unpressButton","reportUserActivity","TimeWrapper","BaseSeekBar","SeekBar","preventScrubbingPlugin","getMouseTime","furthestVisitedTime","handleMouseDown","handleMouseMove","percent","handleMouseUp","num","min","max","clamp","calculateDistance","x","ChapterBarLoadProgress","ChapterBarPlayProgress","ChapterBarItem","playProgress","loadProgress","updateBuffered","scrubbing","getCache","chapterDuration","endTime","duration_","getCurrentTime","bufferEnd","ChapterBarItems","getBufferedEnd","ChapterSeekBar","onDurationChange","createChapterItems","chapterBarItems","onCueChange","track_","bindUpdateListener","ignoreChapters","ci","barName","BaseProgressControl","BASE_SEEK_BAR_NAME","ProgressControl","seekBarName_","TimeTooltip","hasCustomChapterText","chapter_","time_","formatTime","ThumbnailDisplay","img_","imageLocation","hashIndex","h","y","lsrc","hashString","scale","getScale","parseInt","scaleFactor","imageSettings","mouseTime","parseImageLink","transformOrigin","transform","BaseMouseTimeDisplay","MOUSE_TIME_FORCE_SHOW_CLASS","MouseTimeDisplay","setTrack","seekBarRect","seekBarPoint","tooltip","thumbnailDisplay","farLeftPreventScrubbingTooltip","isLockerEnabled","updateTime","marginLeft","ChaptersTrackMenuItem","ChapterMenuItem","nonIconControl","insertBefore","assign","getInnerHTML","ChaptersButton","mi","kind","activeCues","BaseOffTextTrackMenuItem","OffTextTrackMenuItem","kinds","default","BaseTextTrackButton","TextTrackMenuItem","TextTrackButton","MenuItemType","label_","kinds_","kind_","Array","isArray","SubCapsMenuItem","CustomSubCapsMenuItem","SubtitleSearchMenuItem","toggleEnabled","ToggleTranscriptMenuItem","transcriptOn","onToggle","toggleListener","onResize","shouldHide","innerWidth","display","toggleOff","toggleOn","toggleEl","toggleTranscript","setEnabled","handlerBound","handleToggleListener","BaseSubsCapsButton","SubsCapsButton","hasSubtitleTrack","from","allowTheatreMode","localCacheElement","QualityMenuItem","qualityId","changeHandler","handleQualityChange","handleLocalCacheChange","setLabel","itemText","qualityLevel","shouldBeSelected","isSelected_","qualityLabels","QualityMenuButton","updateHandler","PlaybackRateMenuItem","BasePlaybackRateMenuButton","PlaybackRateMenuButton","args","rates","setupLabelEl","updateLabel","labelEl_","BaseTextTrackSettings","BASE_TRACK_SETTINGS","backgroundColor","backgroundOpacity","color","edgeStyle","fontFamily","fontPercent","textOpacity","windowColor","windowOpacity","TRACK_SETTINGS","small","medium","large","TextTrackSettings","size_","updateDisplay","subtitleSizeButton","USER_AGENT","userAgent","Player","test","PlayerWrapper","_dataLoaded","setDataLoaded","callback","callback_","seconds","ignore","unlock","videoContainer","childNodes","node","child","element","updateStyleEl_","fluid","parent","parentNode","setMaxHeight","videoWidth","videoHeight","playerModePlugin","getMode","removeProperty","ratioParts","ratioMultiplier","maxWidth","margin","listenForUserActivity_","PlayPauseFeedback","onFirstPlay","isDisposed","BasePlayToggle","PlayToggle","BaseTextTrackDisplay","TextTrackDisplay","updateDisplayState","overrides","getValues","cueDiv","displayState","fontSize","ControlBarGradient","SplashTitle","seriesName","seasonEpisode","buildSeasonEpisodeString","seasonNumber","episodeNumber","padNumber","padLength","numberString","SplashWarning","ratingValue","ratingCode","SplashMetadata","embed","PosterImage","backgroundImage","ErrorDisplay","prepend","getErrorImage","BaseFullscreenToggle","CONTROL_TEXT","FullscreenToggle","handleFullscreenChange","config","BasePlayer","streamLogged","buildVideoJs","splash","setupSplash","setupSeekBar","fetchConfig","logStream","_configurePlugins","setup","err","handleFetchError","configureMenuDimensionsPlugin","getSeekBarName","progressReporterPlugin","onFlushProgress","allowFullscreen","fullscreenOnRotatePlugin","openExternallyPlugin","configurePlugins","logVideoProgress","getPlayerOptions","theatreMode","baseChildren","controls","getFluid","fill","getFill","getInactivityTimeout","userActions","hotkeys","ctrlKey","metaKey","altKey","shiftKey","eventOriginatedFromPlayer","didEventOriginateFromPlayer","preventPropagationAndDefaultBehaviour","includes","stopPropagation","handleHotKeys","techOrder","html5","nativeTextTracks","playsinline","devicesConfig","offlinePlaybackObject","fetchFn","viewKey","playbackObject","chapters","triggerUpdate","addTextTrack","cues_","removeCue","chapter","addCue","timestamp","endTimestamp","setChaptersInternal","onButtonClickCallback","setPlayerMode","onClickFavourite","favouritePlugin","setFavourite","getPlaybackObject","isClip","isInteractiveClip","additionalData","clipData","list","enableLocalCache","handleNetworkErrors","subtitle","trackElement","addRemoteTextTrack","posterUrl","poster","ImageHelper","additionalSetup","handleAutoplay","message","PhysicallyChapteredVideo","setupAnalyticsService","isAnalyticsEnabled","setupAnalyticsDependentPlugins","eventLogging","collectionApi","urls","clientId","viewerId","viewerCustomerId","getAnalyticsPlayerType","getAdditionalAnalyticsData","instanceRegion","sharerInstanceRegion","RegionName","settings","playbackSubtitleSizeDefault","persistQualitySettingsPlugin","persistPlaybackRatePlugin","autoplay","showSplash","normalizeId","getPlayerClassName","listener","hash","preventDefaultListener","hideSplash","hotkeyElQuerySelector","hotkeyEl","handleKeyDown","progressControl","getSeekBarOptions","setSeekBarName","_splashAdded","Component","TOOLTIP_SHOW_CLASS","TOOLTIP_REMOVE_TRANSITION_CLASS","PreventScrubbingTooltip","isShowing","innerText","immediately","PreventScrubbingPlugin","isPreviewing","playerCurrentTimeFn","isSetToPreview","configurePreview","getProgressControl","getPreventScrubbingTooltip","preventScrubbingTooltip","mouseTimeDisplay","getSeekBar","NO_SKIPPING_AHEAD_TEXT","COMPONENT_PREVENT_SCRUBBING_TOOLTIP","MOUSE_TIME_DURATION","MenuButton","THEATRE_MODE_CONTROL_TEXT","DEFAULT_MODE_CONTROL_TEXT","THEATRE_MODE_ACTIVE_CLASS","TheatreModeButton","updateControlText","TheatreModePlugin","getCollapserator","createButton","onRequestTheatreMode","status","currentMode","nextMode","TranscriptHeader","firstLanguage","languageOptions","subtitleSrc","alerts","TranscriptSearchBar","query","searchQuery","currentSearchResultIndex","onSearch","totalSearchResults","jumpToSearchResult","Tooltip","spanHack","Dropdown","disabled","variant","SvgContainer","svgName","idx","onChangeLanguage","active","IconButton","DownloadHelper","TranscriptComponent","defaultLanguage","allTracks","setSelectedLanguage","currentCueIndex","setCurrentCueIndex","shouldAutoScroll","setShouldAutoScroll","highlightedCues","setHighlightedCues","cuesToDisplay","currentTranscriptTrack","scrollRef","virtualizer","count","getScrollElement","view","estimateSize","getVirtualItems","scrollToCue","useTranscriptionScroll","useTranscriptionSearch","setInitialState","isSearching","resetSearchResults","containerRef","isContainerHovered","ref","showTranscript","lan","VirtualisedTranscriptionList","timepoint","onClickTranscriptionItem","setStartTime","inPlayer","Plugin","MIN_WIDTH_WITH_TRANSCRIPT","TranscriptPlugin","onTrackLoaded","onChaptersLoaded","chapterTrack","buildOptions","aIsEnglish","t","endTimeStamp","buildComponentProps","BaseReactComponent","setImmediate","root","unmount","defaultOptions","getReactComponent","componentCtor","ReactComponent","container","render","mapRatingValueToColourClass","rating","ratings","AjaxHelper","tokens","gateway","headers","getHeaders","parseResponse","body","token","tokenName","authorization","ok","json","throttle","fn","wait","last","performance","debounce","func","leading","context","debounced","executed","cancel","guide","floor","gm","gh","isNaN","Infinity","buffered","bufferedEnd","findTracks","foundTracks","onAddTrack","loaded_","useTrack","useTracks","onAddTrackWrap","TrackHelper","getTrack","useChapters","useMetadataTrack","useMetadataTracks","useSubtitles","getCurrentTextTrack","findTrackByPredicate","predicate","forEachTrack","sanitizeTrack","loaded","onLoadedData","activeTextTrack"],"sourceRoot":""}
|