diff options
-rw-r--r-- | dist/plyr.js | 23 | ||||
-rw-r--r-- | dist/plyr.js.map | 2 | ||||
-rw-r--r-- | dist/plyr.min.js | 2 | ||||
-rw-r--r-- | dist/plyr.min.js.map | 2 | ||||
-rw-r--r-- | src/js/controls.js | 7 |
5 files changed, 21 insertions, 15 deletions
diff --git a/dist/plyr.js b/dist/plyr.js index 6bbbad13..f2ed3969 100644 --- a/dist/plyr.js +++ b/dist/plyr.js @@ -1957,6 +1957,7 @@ typeof navigator === "object" && (function (global, factory) { // Menu required if (!is.element(this.elements.settings.panels.quality)) { + console.warn('Not an element'); return; } @@ -1971,6 +1972,7 @@ typeof navigator === "object" && (function (global, factory) { } // Toggle the pane and tab + console.warn(this.options.quality); var toggle = !is.empty(this.options.quality) && this.options.quality.length > 1; controls.toggleMenuButton.call(this, type, toggle); @@ -2387,7 +2389,10 @@ typeof navigator === "object" && (function (global, factory) { toggleHidden(target, false); // Focus the first item - target.querySelectorAll('[role^="menuitem"]')[0].focus(); + var firstItem = target.querySelector('[role^="menuitem"]'); + if (firstItem) { + firstItem.focus(); + } }, @@ -3990,11 +3995,9 @@ typeof navigator === "object" && (function (global, factory) { } // If there's a play button, set label - if (is.nodeList(this.elements.buttons.play)) { - Array.from(this.elements.buttons.play).forEach(function (button) { - button.setAttribute('aria-label', label); - }); - } + Array.from(this.elements.buttons.play || []).forEach(function (button) { + button.setAttribute('aria-label', label); + }); // Set iframe title // https://github.com/sampotts/plyr/issues/124 @@ -4074,11 +4077,9 @@ typeof navigator === "object" && (function (global, factory) { toggleClass(this.elements.container, this.config.classNames.stopped, this.stopped); // Set state - if (is.nodeList(this.elements.buttons.play)) { - Array.from(this.elements.buttons.play).forEach(function (target) { - target.pressed = _this3.playing; - }); - } + Array.from(this.elements.buttons.play || []).forEach(function (target) { + target.pressed = _this3.playing; + }); // Only update controls on non timeupdate events if (is.event(event) && event.type === 'timeupdate') { diff --git a/dist/plyr.js.map b/dist/plyr.js.map index bb3e8221..f207f1e9 100644 --- a/dist/plyr.js.map +++ b/dist/plyr.js.map @@ -1 +1 @@ -{"version":3,"sources":["src/js/utils/is.js","src/js/utils/events.js","src/js/utils/elements.js","src/js/utils/animation.js","src/js/utils/browser.js","src/js/support.js","src/js/html5.js","src/js/utils/objects.js","src/js/utils/strings.js","src/js/i18n.js","src/js/utils/arrays.js","src/js/storage.js","src/js/utils/fetch.js","src/js/utils/loadSprite.js","src/js/utils/time.js","src/js/controls.js","src/js/utils/urls.js","src/js/captions.js","src/js/config/defaults.js","src/js/config/types.js","src/js/console.js","src/js/fullscreen.js","src/js/utils/loadImage.js","src/js/ui.js","src/js/listeners.js","node_modules/loadjs/dist/loadjs.umd.js","src/js/utils/loadScript.js","src/js/plugins/vimeo.js","src/js/plugins/youtube.js","src/js/media.js","src/js/plugins/ads.js","src/js/source.js","src/js/plyr.js"],"names":["getConstructor","input","constructor","instanceOf","Boolean","is","object","Object","number","Number","isNaN","string","String","boolean","function","Function","array","nullOrUndefined","Array","isArray","weakMap","WeakMap","nodeList","NodeList","element","Element","textNode","Text","event","Event","cue","window","TextTrackCue","VTTCue","track","TextTrack","kind","url","test","empty","length","keys","supportsPassiveListeners","supported","options","defineProperty","get","addEventListener","removeEventListener","e","toggleListener","callback","toggle","passive","capture","events","split","forEach","eventListeners","push","type","on","call","off","once","onceCallback","args","apply","triggerEvent","bubbles","detail","CustomEvent","assign","plyr","dispatchEvent","unbindListeners","item","ready","Promise","setTimeout","resolve","elements","container","then","wrap","wrapper","targets","from","reverse","index","child","cloneNode","parent","parentNode","sibling","nextSibling","appendChild","insertBefore","setAttributes","attributes","entries","filter","value","key","setAttribute","createElement","text","document","innerText","insertAfter","target","insertElement","removeElement","removeChild","emptyElement","childNodes","lastChild","replaceElement","newChild","oldChild","replaceChild","getAttributesFromSelector","sel","existingAttributes","existing","selector","s","trim","className","replace","stripped","parts","start","charAt","class","id","toggleHidden","hidden","hide","hasAttribute","removeAttribute","toggleClass","force","method","classList","contains","hasClass","matches","prototype","match","querySelectorAll","includes","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","getElements","getElement","querySelector","getFocusElement","focused","activeElement","body","trapFocus","focusable","first","last","trap","keyCode","shiftKey","focus","preventDefault","transitionEndEvent","WebkitTransition","MozTransition","OTransition","transition","find","style","undefined","repaint","offsetHeight","browser","isIE","documentMode","isWebkit","documentElement","navigator","userAgent","isIPhone","platform","isIos","defaultCodecs","support","audio","video","check","provider","playsinline","canPlayInline","api","ui","rangeInput","pip","webkitSetPresentationMode","airplay","WebKitPlaybackTargetAvailabilityEvent","mime","inputType","mediaType","isHTML5","media","canPlayType","err","textTracks","range","touch","transitions","reducedMotion","matchMedia","html5","getSources","sources","source","getAttribute","getQualityOptions","map","extend","player","set","currentTime","playing","src","onLoadedMetaData","load","play","quality","cancelRequests","config","blankVideo","debug","log","cloneDeep","JSON","parse","stringify","getDeep","path","reduce","obj","shift","generateId","prefix","Math","floor","random","format","toString","i","getPercentage","current","max","toFixed","replaceAll","RegExp","toTitleCase","toUpperCase","substr","toLowerCase","toPascalCase","toCamelCase","slice","stripHTML","fragment","createDocumentFragment","innerHTML","firstChild","getHTML","i18n","seekTime","title","dedupe","indexOf","closest","prev","curr","abs","Storage","enabled","storage","store","localStorage","getItem","json","setItem","removeItem","fetch","responseType","reject","request","XMLHttpRequest","responseText","response","Error","status","open","send","loadSprite","hasId","isCached","exists","getElementById","update","data","insertAdjacentElement","useStorage","cached","content","result","catch","getHours","parseInt","getMinutes","getSeconds","formatTime","time","displayHours","inverted","hours","mins","secs","controls","getIconUrl","URL","iconUrl","location","cors","host","svg4everybody","findElements","selectors","buttons","pause","restart","rewind","fastForward","mute","settings","captions","fullscreen","progress","inputs","seek","volume","display","buffer","duration","seekTooltip","classNames","tooltip","error","warn","toggleNativeControls","createIcon","namespace","iconPath","iconPrefix","icon","createElementNS","role","use","setAttributeNS","createLabel","attr","universals","join","createBadge","badge","menu","createButton","buttonType","button","label","labelPressed","iconPressed","control","controlPressed","enumerable","pressed","createRange","min","step","autocomplete","updateRangeFill","createProgress","suffixKey","played","suffix","createTime","createMenuItem","list","checked","children","node","forceHours","updateTimeDisplay","updateVolume","setRange","muted","updateProgress","setProgress","getElementsByTagName","nodeValue","buffered","percent","setProperty","updateSeekTooltip","tooltips","clientRect","getBoundingClientRect","visible","width","pageX","left","parseFloat","timeUpdate","invert","invertTime","seeking","durationUpdate","hasDuration","displayDuration","paused","toggleMenuButton","setting","setQualityMenu","panels","checkMenu","getBadge","sort","a","b","sorting","getLabel","updateSetting","pane","currentTrack","default","setCaptionsMenu","tracks","getTracks","toggled","language","unshift","bind","setSpeedMenu","speed","isVimeo","values","some","toggleMenu","popup","show","isMenuItem","isButton","stopPropagation","getMenuSize","tab","clone","position","opacity","scrollWidth","height","scrollHeight","showMenuPanel","size","restore","propertyName","create","inner","home","menuItem","flex","back","inject","props","seektime","insertAdjacentHTML","labels","parseUrl","safe","parser","href","buildUrlParams","params","URLSearchParams","setup","isVideo","isYouTube","hostname","protocol","createObjectURL","blob","languages","userLanguage","active","trackEvents","meta","currentTrackNode","languageExists","mode","updateCues","setLanguage","activeClass","findTrack","embed","enableTextTrack","has","sortIsDefault","sorted","every","getCurrentTrack","cues","activeCues","getCueAsHTML","cueText","changed","caption","defaults","autoplay","autopause","toggleInvert","ratio","clickToPlay","hideControls","resetOnEnd","disableContextMenu","loop","selected","keyboard","global","fallback","iosNative","seekLabel","unmute","enableCaptions","disableCaptions","enterFullscreen","exitFullscreen","frameTitle","menuBack","normal","end","all","reset","disabled","advertisement","qualityBadge","urls","vimeo","sdk","iframe","youtube","googleIMA","listeners","editable","embedContainer","poster","posterEnabled","ads","stopped","loading","hover","isTouch","uiSupported","noTransition","tabFocus","google","publisherId","providers","types","getProviderByUrl","noop","Console","console","onChange","toggleFallback","scrollPosition","x","scrollX","y","scrollY","scrollTo","overflow","Fullscreen","property","native","webkitEnterFullscreen","requestFullscreen","webkitExitFullscreen","cancelFullScreen","action","enter","exit","fullscreenElement","fullscreenEnabled","webkitFullscreenEnabled","mozFullScreenEnabled","msFullscreenEnabled","prefixes","pre","loadImage","minWidth","image","Image","handler","onload","onerror","naturalWidth","addStyleHook","build","checkPlaying","setTitle","setPoster","isEmbed","togglePoster","enable","backgroundImage","backgroundSize","toggleControls","checkLoading","clearTimeout","timers","Listeners","lastKey","handleKey","firstTouch","code","which","repeat","altKey","ctrlKey","metaKey","seekByKey","togglePlay","increaseVolume","decreaseVolume","forward","toggleCaptions","delay","hasAudio","initialized","managerPromise","isAudio","ended","proxyEvents","concat","inputEvent","proxy","defaultHandler","customHandlerKey","customHandler","hasCustomHandler","returned","showHomeTab","currentTarget","eventType","done","seekTo","webkitDirectionInvertedFromDevice","direction","deltaY","deltaX","define","this","loadScript","loadjs","success","parseId","regex","$2","getAspectRatio","getRatio","w","h","assurePlaybackState","hasPlayed","setAspectRatio","Vimeo","padding","paddingBottom","offset","transform","byline","portrait","transparent","gesture","thumbnail_large","pathname","Player","disableTextTrack","stop","restorePause","setVolume","setCurrentTime","setPlaybackRate","name","setLoop","currentSrc","getVideoUrl","getVideoWidth","getVideoHeight","dimensions","setAutopause","state","getVideoTitle","getCurrentTime","getDuration","getTextTracks","strippedCues","getPaused","frame","seconds","mapQualityUnit","qualities","hd2160","hd1440","hd1080","hd720","large","medium","small","tiny","entry","mapQualityUnits","levels","level","YT","onYouTubeReadyCallbacks","onYouTubeIframeAPIReady","getTitle","videoId","getVideoData","items","snippet","currentId","startsWith","posterSrc","playerVars","rel","showinfo","iv_load_policy","modestbranding","disablekb","widget_referrer","cc_load_policy","cc_lang_pref","onError","message","onPlaybackQualityChange","onPlaybackRateChange","instance","playbackRate","getPlaybackRate","onReady","playVideo","pauseVideo","stopVideo","getPlaybackQuality","setPlaybackQuality","getAvailablePlaybackRates","clearInterval","buffering","setInterval","getVideoLoadedFraction","lastBuffered","onStateChange","seeked","getAvailableQualityLevels","unMute","Ads","displayContainer","manager","loader","cuePoints","safetyTimer","countdownTimer","ima","trigger","startSafetyTimer","clearSafetyTimer","setupIMA","setVpaidMode","ImaSdkSettings","VpaidMode","ENABLED","setLocale","AdDisplayContainer","requestAds","AdsLoader","AdsManagerLoadedEvent","Type","ADS_MANAGER_LOADED","onAdsManagerLoaded","AdErrorEvent","AD_ERROR","onAdError","AdsRequest","adTagUrl","tagUrl","linearAdSlotWidth","offsetWidth","linearAdSlotHeight","nonLinearAdSlotWidth","nonLinearAdSlotHeight","forceNonLinearFullSlot","setAdWillPlayMuted","getRemainingTime","AdsRenderingSettings","restoreCustomPlaybackStateOnAdBreakComplete","enablePreloading","getAdsManager","getCuePoints","cuePoint","seekElement","cuePercentage","AdEvent","onAdEvent","ad","getAd","LOADED","pollCountdown","isLinear","ALL_ADS_COMPLETED","loadAds","CONTENT_PAUSE_REQUESTED","pauseContent","CONTENT_RESUME_REQUESTED","resumeContent","STARTED","MIDPOINT","COMPLETE","IMPRESSION","CLICK","cancel","contentComplete","seekedTime","discardAdBreak","splice","resize","ViewMode","NORMAL","initialize","init","adError","zIndex","destroy","handlers","AV_PUBLISHERID","AV_CHANNELID","AV_URL","cb","Date","now","AV_WIDTH","AV_HEIGHT","AV_CDIM2","base","insertElements","attribute","change","tagName","crossorigin","Plyr","failed","jQuery","original","searchParams","truthy","webkitShowPlaybackTargetPicker","isHidden","hiding","eventName","soft","unload","inputIsValid","fauxDuration","mozHasAudio","webkitAudioDecodedByteCount","audioTracks","states","inline","webkitPresentationMode","t"],"mappings":"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","file":"plyr.js","sourcesContent":["// ==========================================================================\n// Type checking utils\n// ==========================================================================\n\nconst getConstructor = input => (input !== null && typeof input !== 'undefined' ? input.constructor : null);\n\nconst instanceOf = (input, constructor) => Boolean(input && constructor && input instanceof constructor);\n\nconst is = {\n object(input) {\n return getConstructor(input) === Object;\n },\n number(input) {\n return getConstructor(input) === Number && !Number.isNaN(input);\n },\n string(input) {\n return getConstructor(input) === String;\n },\n boolean(input) {\n return getConstructor(input) === Boolean;\n },\n function(input) {\n return getConstructor(input) === Function;\n },\n array(input) {\n return !is.nullOrUndefined(input) && Array.isArray(input);\n },\n weakMap(input) {\n return instanceOf(input, WeakMap);\n },\n nodeList(input) {\n return instanceOf(input, NodeList);\n },\n element(input) {\n return instanceOf(input, Element);\n },\n textNode(input) {\n return getConstructor(input) === Text;\n },\n event(input) {\n return instanceOf(input, Event);\n },\n cue(input) {\n return instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue);\n },\n track(input) {\n return instanceOf(input, TextTrack) || (!is.nullOrUndefined(input) && is.string(input.kind));\n },\n url(input) {\n return (\n !is.nullOrUndefined(input) &&\n /(ftp|http|https):\\/\\/(\\w+:{0,1}\\w*@)?(\\S+)(:[0-9]+)?(\\/|\\/([\\w#!:.?+=&%@!\\-/]))?/.test(input)\n );\n },\n nullOrUndefined(input) {\n return input === null || typeof input === 'undefined';\n },\n empty(input) {\n return (\n is.nullOrUndefined(input) ||\n ((is.string(input) || is.array(input) || is.nodeList(input)) && !input.length) ||\n (is.object(input) && !Object.keys(input).length)\n );\n },\n};\n\nexport default is;\n","// ==========================================================================\n// Event utils\n// ==========================================================================\n\nimport is from './is';\n\n// Check for passive event listener support\n// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md\n// https://www.youtube.com/watch?v=NPM6172J22g\nconst supportsPassiveListeners = (() => {\n // Test via a getter in the options object to see if the passive property is accessed\n let supported = false;\n try {\n const options = Object.defineProperty({}, 'passive', {\n get() {\n supported = true;\n return null;\n },\n });\n window.addEventListener('test', null, options);\n window.removeEventListener('test', null, options);\n } catch (e) {\n // Do nothing\n }\n\n return supported;\n})();\n\n// Toggle event listener\nexport function toggleListener(element, event, callback, toggle = false, passive = true, capture = false) {\n // Bail if no element, event, or callback\n if (!element || !('addEventListener' in element) || is.empty(event) || !is.function(callback)) {\n return;\n }\n\n // Allow multiple events\n const events = event.split(' ');\n\n // Build options\n // Default to just the capture boolean for browsers with no passive listener support\n let options = capture;\n\n // If passive events listeners are supported\n if (supportsPassiveListeners) {\n options = {\n // Whether the listener can be passive (i.e. default never prevented)\n passive,\n // Whether the listener is a capturing listener or not\n capture,\n };\n }\n\n // If a single node is passed, bind the event listener\n events.forEach(type => {\n if (this && this.eventListeners && toggle) {\n // Cache event listener\n this.eventListeners.push({ element, type, callback, options });\n }\n\n element[toggle ? 'addEventListener' : 'removeEventListener'](type, callback, options);\n });\n}\n\n// Bind event handler\nexport function on(element, events = '', callback, passive = true, capture = false) {\n toggleListener.call(this, element, events, callback, true, passive, capture);\n}\n\n// Unbind event handler\nexport function off(element, events = '', callback, passive = true, capture = false) {\n toggleListener.call(this, element, events, callback, false, passive, capture);\n}\n\n// Bind once-only event handler\nexport function once(element, events = '', callback, passive = true, capture = false) {\n function onceCallback(...args) {\n off(element, events, onceCallback, passive, capture);\n callback.apply(this, args);\n }\n\n toggleListener.call(this, element, events, onceCallback, true, passive, capture);\n}\n\n// Trigger event\nexport function triggerEvent(element, type = '', bubbles = false, detail = {}) {\n // Bail if no element\n if (!is.element(element) || is.empty(type)) {\n return;\n }\n\n // Create and dispatch the event\n const event = new CustomEvent(type, {\n bubbles,\n detail: Object.assign({}, detail, {\n plyr: this,\n }),\n });\n\n // Dispatch the event\n element.dispatchEvent(event);\n}\n\n// Unbind all cached event listeners\nexport function unbindListeners() {\n if (this && this.eventListeners) {\n this.eventListeners.forEach(item => {\n const { element, type, callback, options } = item;\n element.removeEventListener(type, callback, options);\n });\n\n this.eventListeners = [];\n }\n}\n\n// Run method when / if player is ready\nexport function ready() {\n return new Promise(\n resolve => (this.ready ? setTimeout(resolve, 0) : on.call(this, this.elements.container, 'ready', resolve)),\n ).then(() => {});\n}\n","// ==========================================================================\n// Element utils\n// ==========================================================================\n\nimport { toggleListener } from './events';\nimport is from './is';\n\n// Wrap an element\nexport function wrap(elements, wrapper) {\n // Convert `elements` to an array, if necessary.\n const targets = elements.length ? elements : [elements];\n\n // Loops backwards to prevent having to clone the wrapper on the\n // first element (see `child` below).\n Array.from(targets)\n .reverse()\n .forEach((element, index) => {\n const child = index > 0 ? wrapper.cloneNode(true) : wrapper;\n\n // Cache the current parent and sibling.\n const parent = element.parentNode;\n const sibling = element.nextSibling;\n\n // Wrap the element (is automatically removed from its current\n // parent).\n child.appendChild(element);\n\n // If the element had a sibling, insert the wrapper before\n // the sibling to maintain the HTML structure; otherwise, just\n // append it to the parent.\n if (sibling) {\n parent.insertBefore(child, sibling);\n } else {\n parent.appendChild(child);\n }\n });\n}\n\n// Set attributes\nexport function setAttributes(element, attributes) {\n if (!is.element(element) || is.empty(attributes)) {\n return;\n }\n\n // Assume null and undefined attributes should be left out,\n // Setting them would otherwise convert them to \"null\" and \"undefined\"\n Object.entries(attributes)\n .filter(([, value]) => !is.nullOrUndefined(value))\n .forEach(([key, value]) => element.setAttribute(key, value));\n}\n\n// Create a DocumentFragment\nexport function createElement(type, attributes, text) {\n // Create a new <element>\n const element = document.createElement(type);\n\n // Set all passed attributes\n if (is.object(attributes)) {\n setAttributes(element, attributes);\n }\n\n // Add text node\n if (is.string(text)) {\n element.innerText = text;\n }\n\n // Return built element\n return element;\n}\n\n// Inaert an element after another\nexport function insertAfter(element, target) {\n if (!is.element(element) || !is.element(target)) {\n return;\n }\n\n target.parentNode.insertBefore(element, target.nextSibling);\n}\n\n// Insert a DocumentFragment\nexport function insertElement(type, parent, attributes, text) {\n if (!is.element(parent)) {\n return;\n }\n\n parent.appendChild(createElement(type, attributes, text));\n}\n\n// Remove element(s)\nexport function removeElement(element) {\n if (is.nodeList(element) || is.array(element)) {\n Array.from(element).forEach(removeElement);\n return;\n }\n\n if (!is.element(element) || !is.element(element.parentNode)) {\n return;\n }\n\n element.parentNode.removeChild(element);\n}\n\n// Remove all child elements\nexport function emptyElement(element) {\n if (!is.element(element)) {\n return;\n }\n\n let { length } = element.childNodes;\n\n while (length > 0) {\n element.removeChild(element.lastChild);\n length -= 1;\n }\n}\n\n// Replace element\nexport function replaceElement(newChild, oldChild) {\n if (!is.element(oldChild) || !is.element(oldChild.parentNode) || !is.element(newChild)) {\n return null;\n }\n\n oldChild.parentNode.replaceChild(newChild, oldChild);\n\n return newChild;\n}\n\n// Get an attribute object from a string selector\nexport function getAttributesFromSelector(sel, existingAttributes) {\n // For example:\n // '.test' to { class: 'test' }\n // '#test' to { id: 'test' }\n // '[data-test=\"test\"]' to { 'data-test': 'test' }\n\n if (!is.string(sel) || is.empty(sel)) {\n return {};\n }\n\n const attributes = {};\n const existing = existingAttributes;\n\n sel.split(',').forEach(s => {\n // Remove whitespace\n const selector = s.trim();\n const className = selector.replace('.', '');\n const stripped = selector.replace(/[[\\]]/g, '');\n\n // Get the parts and value\n const parts = stripped.split('=');\n const key = parts[0];\n const value = parts.length > 1 ? parts[1].replace(/[\"']/g, '') : '';\n\n // Get the first character\n const start = selector.charAt(0);\n\n switch (start) {\n case '.':\n // Add to existing classname\n if (is.object(existing) && is.string(existing.class)) {\n existing.class += ` ${className}`;\n }\n\n attributes.class = className;\n break;\n\n case '#':\n // ID selector\n attributes.id = selector.replace('#', '');\n break;\n\n case '[':\n // Attribute selector\n attributes[key] = value;\n\n break;\n\n default:\n break;\n }\n });\n\n return attributes;\n}\n\n// Toggle hidden\nexport function toggleHidden(element, hidden) {\n if (!is.element(element)) {\n return;\n }\n\n let hide = hidden;\n\n if (!is.boolean(hide)) {\n hide = !element.hasAttribute('hidden');\n }\n\n if (hide) {\n element.setAttribute('hidden', '');\n } else {\n element.removeAttribute('hidden');\n }\n}\n\n// Mirror Element.classList.toggle, with IE compatibility for \"force\" argument\nexport function toggleClass(element, className, force) {\n if (is.element(element)) {\n let method = 'toggle';\n if (typeof force !== 'undefined') {\n method = force ? 'add' : 'remove';\n }\n\n element.classList[method](className);\n return element.classList.contains(className);\n }\n\n return null;\n}\n\n// Has class name\nexport function hasClass(element, className) {\n return is.element(element) && element.classList.contains(className);\n}\n\n// Element matches selector\nexport function matches(element, selector) {\n const prototype = { Element };\n\n function match() {\n return Array.from(document.querySelectorAll(selector)).includes(this);\n }\n\n const matches =\n prototype.matches ||\n prototype.webkitMatchesSelector ||\n prototype.mozMatchesSelector ||\n prototype.msMatchesSelector ||\n match;\n\n return matches.call(element, selector);\n}\n\n// Find all elements\nexport function getElements(selector) {\n return this.elements.container.querySelectorAll(selector);\n}\n\n// Find a single element\nexport function getElement(selector) {\n return this.elements.container.querySelector(selector);\n}\n\n// Get the focused element\nexport function getFocusElement() {\n let focused = document.activeElement;\n\n if (!focused || focused === document.body) {\n focused = null;\n } else {\n focused = document.querySelector(':focus');\n }\n\n return focused;\n}\n\n// Trap focus inside container\nexport function trapFocus(element = null, toggle = false) {\n if (!is.element(element)) {\n return;\n }\n\n const focusable = getElements.call(this, 'button:not(:disabled), input:not(:disabled), [tabindex]');\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n const trap = event => {\n // Bail if not tab key or not fullscreen\n if (event.key !== 'Tab' || event.keyCode !== 9) {\n return;\n }\n\n // Get the current focused element\n const focused = getFocusElement();\n\n if (focused === last && !event.shiftKey) {\n // Move focus to first element that can be tabbed if Shift isn't used\n first.focus();\n event.preventDefault();\n } else if (focused === first && event.shiftKey) {\n // Move focus to last element that can be tabbed if Shift is used\n last.focus();\n event.preventDefault();\n }\n };\n\n toggleListener.call(this, this.elements.container, 'keydown', trap, toggle, false);\n}\n","// ==========================================================================\n// Animation utils\n// ==========================================================================\n\nimport { toggleHidden } from './elements';\nimport is from './is';\n\nexport const transitionEndEvent = (() => {\n const element = document.createElement('span');\n\n const events = {\n WebkitTransition: 'webkitTransitionEnd',\n MozTransition: 'transitionend',\n OTransition: 'oTransitionEnd otransitionend',\n transition: 'transitionend',\n };\n\n const type = Object.keys(events).find(event => element.style[event] !== undefined);\n\n return is.string(type) ? events[type] : false;\n})();\n\n// Force repaint of element\nexport function repaint(element) {\n setTimeout(() => {\n toggleHidden(element, true);\n element.offsetHeight; // eslint-disable-line\n toggleHidden(element, false);\n }, 0);\n}\n","// ==========================================================================\n// Browser sniffing\n// Unfortunately, due to mixed support, UA sniffing is required\n// ==========================================================================\n\nconst browser = {\n isIE: /* @cc_on!@ */ false || !!document.documentMode,\n isWebkit: 'WebkitAppearance' in document.documentElement.style && !/Edge/.test(navigator.userAgent),\n isIPhone: /(iPhone|iPod)/gi.test(navigator.platform),\n isIos: /(iPad|iPhone|iPod)/gi.test(navigator.platform),\n};\n\nexport default browser;\n","// ==========================================================================\n// Plyr support checks\n// ==========================================================================\n\nimport { transitionEndEvent } from './utils/animation';\nimport browser from './utils/browser';\nimport { createElement } from './utils/elements';\nimport is from './utils/is';\n\n// Default codecs for checking mimetype support\nconst defaultCodecs = {\n 'audio/ogg': 'vorbis',\n 'audio/wav': '1',\n 'video/webm': 'vp8, vorbis',\n 'video/mp4': 'avc1.42E01E, mp4a.40.2',\n 'video/ogg': 'theora',\n};\n\n// Check for feature support\nconst support = {\n // Basic support\n audio: 'canPlayType' in document.createElement('audio'),\n video: 'canPlayType' in document.createElement('video'),\n\n // Check for support\n // Basic functionality vs full UI\n check(type, provider, playsinline) {\n const canPlayInline = browser.isIPhone && playsinline && support.playsinline;\n const api = support[type] || provider !== 'html5';\n const ui = api && support.rangeInput && (type !== 'video' || !browser.isIPhone || canPlayInline);\n\n return {\n api,\n ui,\n };\n },\n\n // Picture-in-picture support\n // Safari only currently\n pip: (() => !browser.isIPhone && is.function(createElement('video').webkitSetPresentationMode))(),\n\n // Airplay support\n // Safari only currently\n airplay: is.function(window.WebKitPlaybackTargetAvailabilityEvent),\n\n // Inline playback support\n // https://webkit.org/blog/6784/new-video-policies-for-ios/\n playsinline: 'playsInline' in document.createElement('video'),\n\n // Check for mime type support against a player instance\n // Credits: http://diveintohtml5.info/everything.html\n // Related: http://www.leanbackplayer.com/test/h5mt.html\n mime(inputType) {\n const [mediaType] = inputType.split('/');\n if (!this.isHTML5 || mediaType !== this.type) {\n return false;\n }\n\n let type;\n if (inputType && inputType.includes('codecs=')) {\n // Use input directly\n type = inputType;\n } else if (inputType === 'audio/mpeg') {\n // Skip codec\n type = 'audio/mpeg;';\n } else if (inputType in defaultCodecs) {\n // Use codec\n type = `${inputType}; codecs=\"${defaultCodecs[inputType]}\"`;\n }\n\n try {\n return Boolean(type && this.media.canPlayType(type).replace(/no/, ''));\n } catch (err) {\n return false;\n }\n },\n\n // Check for textTracks support\n textTracks: 'textTracks' in document.createElement('video'),\n\n // <input type=\"range\"> Sliders\n rangeInput: (() => {\n const range = document.createElement('input');\n range.type = 'range';\n return range.type === 'range';\n })(),\n\n // Touch\n // NOTE: Remember a device can be mouse + touch enabled so we check on first touch event\n touch: 'ontouchstart' in document.documentElement,\n\n // Detect transitions support\n transitions: transitionEndEvent !== false,\n\n // Reduced motion iOS & MacOS setting\n // https://webkit.org/blog/7551/responsive-design-for-motion/\n reducedMotion: 'matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches,\n};\n\nexport default support;\n","// ==========================================================================\n// Plyr HTML5 helpers\n// ==========================================================================\n\nimport support from './support';\nimport { removeElement } from './utils/elements';\nimport { triggerEvent } from './utils/events';\n\nconst html5 = {\n getSources() {\n if (!this.isHTML5) {\n return [];\n }\n\n const sources = Array.from(this.media.querySelectorAll('source'));\n\n // Filter out unsupported sources\n return sources.filter(source => support.mime.call(this, source.getAttribute('type')));\n },\n\n // Get quality levels\n getQualityOptions() {\n // Get sizes from <source> elements\n return html5.getSources\n .call(this)\n .map(source => Number(source.getAttribute('size')))\n .filter(Boolean);\n },\n\n extend() {\n if (!this.isHTML5) {\n return;\n }\n\n const player = this;\n\n // Quality\n Object.defineProperty(player.media, 'quality', {\n get() {\n // Get sources\n const sources = html5.getSources.call(player);\n const [source] = sources.filter(source => source.getAttribute('src') === player.source);\n\n // Return size, if match is found\n return source && Number(source.getAttribute('size'));\n },\n set(input) {\n // Get sources\n const sources = html5.getSources.call(player);\n\n // Get first match for requested size\n const source = sources.find(source => Number(source.getAttribute('size')) === input);\n\n // No matching source found\n if (!source) {\n return;\n }\n\n // Get current state\n const { currentTime, playing } = player;\n\n // Set new source\n player.media.src = source.getAttribute('src');\n\n // Restore time\n const onLoadedMetaData = () => {\n player.currentTime = currentTime;\n };\n player.once('loadedmetadata', onLoadedMetaData);\n\n // Load new source\n player.media.load();\n\n // Resume playing\n if (playing) {\n player.play();\n }\n\n // Trigger change event\n triggerEvent.call(player, player.media, 'qualitychange', false, {\n quality: input,\n });\n },\n });\n },\n\n // Cancel current network requests\n // See https://github.com/sampotts/plyr/issues/174\n cancelRequests() {\n if (!this.isHTML5) {\n return;\n }\n\n // Remove child sources\n removeElement(html5.getSources.call(this));\n\n // Set blank video src attribute\n // This is to prevent a MEDIA_ERR_SRC_NOT_SUPPORTED error\n // Info: http://stackoverflow.com/questions/32231579/how-to-properly-dispose-of-an-html5-video-and-close-socket-or-connection\n this.media.setAttribute('src', this.config.blankVideo);\n\n // Load the new empty source\n // This will cancel existing requests\n // See https://github.com/sampotts/plyr/issues/174\n this.media.load();\n\n // Debugging\n this.debug.log('Cancelled network requests');\n },\n};\n\nexport default html5;\n","// ==========================================================================\n// Object utils\n// ==========================================================================\n\nimport is from './is';\n\n// Clone nested objects\nexport function cloneDeep(object) {\n return JSON.parse(JSON.stringify(object));\n}\n\n// Get a nested value in an object\nexport function getDeep(object, path) {\n return path.split('.').reduce((obj, key) => obj && obj[key], object);\n}\n\n// Deep extend destination object with N more objects\nexport function extend(target = {}, ...sources) {\n if (!sources.length) {\n return target;\n }\n\n const source = sources.shift();\n\n if (!is.object(source)) {\n return target;\n }\n\n Object.keys(source).forEach(key => {\n if (is.object(source[key])) {\n if (!Object.keys(target).includes(key)) {\n Object.assign(target, { [key]: {} });\n }\n\n extend(target[key], source[key]);\n } else {\n Object.assign(target, { [key]: source[key] });\n }\n });\n\n return extend(target, ...sources);\n}\n","// ==========================================================================\n// String utils\n// ==========================================================================\n\nimport is from './is';\n\n// Generate a random ID\nexport function generateId(prefix) {\n return `${prefix}-${Math.floor(Math.random() * 10000)}`;\n}\n\n// Format string\nexport function format(input, ...args) {\n if (is.empty(input)) {\n return input;\n }\n\n return input.toString().replace(/{(\\d+)}/g, (match, i) => args[i].toString());\n}\n\n// Get percentage\nexport function getPercentage(current, max) {\n if (current === 0 || max === 0 || Number.isNaN(current) || Number.isNaN(max)) {\n return 0;\n }\n\n return (current / max * 100).toFixed(2);\n}\n\n// Replace all occurances of a string in a string\nexport function replaceAll(input = '', find = '', replace = '') {\n return input.replace(\n new RegExp(find.toString().replace(/([.*+?^=!:${}()|[\\]/\\\\])/g, '\\\\$1'), 'g'),\n replace.toString(),\n );\n}\n\n// Convert to title case\nexport function toTitleCase(input = '') {\n return input.toString().replace(/\\w\\S*/g, text => text.charAt(0).toUpperCase() + text.substr(1).toLowerCase());\n}\n\n// Convert string to pascalCase\nexport function toPascalCase(input = '') {\n let string = input.toString();\n\n // Convert kebab case\n string = replaceAll(string, '-', ' ');\n\n // Convert snake case\n string = replaceAll(string, '_', ' ');\n\n // Convert to title case\n string = toTitleCase(string);\n\n // Convert to pascal case\n return replaceAll(string, ' ', '');\n}\n\n// Convert string to pascalCase\nexport function toCamelCase(input = '') {\n let string = input.toString();\n\n // Convert to pascal case\n string = toPascalCase(string);\n\n // Convert first character to lowercase\n return string.charAt(0).toLowerCase() + string.slice(1);\n}\n\n// Remove HTML from a string\nexport function stripHTML(source) {\n const fragment = document.createDocumentFragment();\n const element = document.createElement('div');\n fragment.appendChild(element);\n element.innerHTML = source;\n return fragment.firstChild.innerText;\n}\n\n// Like outerHTML, but also works for DocumentFragment\nexport function getHTML(element) {\n const wrapper = document.createElement('div');\n wrapper.appendChild(element);\n return wrapper.innerHTML;\n}\n","// ==========================================================================\n// Plyr internationalization\n// ==========================================================================\n\nimport is from './utils/is';\nimport { getDeep } from './utils/objects';\nimport { replaceAll } from './utils/strings';\n\nconst i18n = {\n get(key = '', config = {}) {\n if (is.empty(key) || is.empty(config)) {\n return '';\n }\n\n let string = getDeep(config.i18n, key);\n\n if (is.empty(string)) {\n return '';\n }\n\n const replace = {\n '{seektime}': config.seekTime,\n '{title}': config.title,\n };\n\n Object.entries(replace).forEach(([key, value]) => {\n string = replaceAll(string, key, value);\n });\n\n return string;\n },\n};\n\nexport default i18n;\n","// ==========================================================================\n// Array utils\n// ==========================================================================\n\nimport is from './is';\n\n// Remove duplicates in an array\nexport function dedupe(array) {\n if (!is.array(array)) {\n return array;\n }\n\n return array.filter((item, index) => array.indexOf(item) === index);\n}\n\n// Get the closest value in an array\nexport function closest(array, value) {\n if (!is.array(array) || !array.length) {\n return null;\n }\n\n return array.reduce((prev, curr) => (Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev));\n}\n","// ==========================================================================\n// Plyr storage\n// ==========================================================================\n\nimport is from './utils/is';\nimport { extend } from './utils/objects';\n\nclass Storage {\n constructor(player) {\n this.enabled = player.config.storage.enabled;\n this.key = player.config.storage.key;\n }\n\n // Check for actual support (see if we can use it)\n static get supported() {\n try {\n if (!('localStorage' in window)) {\n return false;\n }\n\n const test = '___test';\n\n // Try to use it (it might be disabled, e.g. user is in private mode)\n // see: https://github.com/sampotts/plyr/issues/131\n window.localStorage.setItem(test, test);\n window.localStorage.removeItem(test);\n\n return true;\n } catch (e) {\n return false;\n }\n }\n\n get(key) {\n if (!Storage.supported || !this.enabled) {\n return null;\n }\n\n const store = window.localStorage.getItem(this.key);\n\n if (is.empty(store)) {\n return null;\n }\n\n const json = JSON.parse(store);\n\n return is.string(key) && key.length ? json[key] : json;\n }\n\n set(object) {\n // Bail if we don't have localStorage support or it's disabled\n if (!Storage.supported || !this.enabled) {\n return;\n }\n\n // Can only store objectst\n if (!is.object(object)) {\n return;\n }\n\n // Get current storage\n let storage = this.get();\n\n // Default to empty object\n if (is.empty(storage)) {\n storage = {};\n }\n\n // Update the working copy of the values\n extend(storage, object);\n\n // Update storage\n window.localStorage.setItem(this.key, JSON.stringify(storage));\n }\n}\n\nexport default Storage;\n","// ==========================================================================\n// Fetch wrapper\n// Using XHR to avoid issues with older browsers\n// ==========================================================================\n\nexport default function fetch(url, responseType = 'text') {\n return new Promise((resolve, reject) => {\n try {\n const request = new XMLHttpRequest();\n\n // Check for CORS support\n if (!('withCredentials' in request)) {\n return;\n }\n\n request.addEventListener('load', () => {\n if (responseType === 'text') {\n try {\n resolve(JSON.parse(request.responseText));\n } catch (e) {\n resolve(request.responseText);\n }\n } else {\n resolve(request.response);\n }\n });\n\n request.addEventListener('error', () => {\n throw new Error(request.status);\n });\n\n request.open('GET', url, true);\n\n // Set the required response type\n request.responseType = responseType;\n\n request.send();\n } catch (e) {\n reject(e);\n }\n });\n}\n","// ==========================================================================\n// Sprite loader\n// ==========================================================================\n\nimport Storage from './../storage';\nimport fetch from './fetch';\nimport is from './is';\n\n// Load an external SVG sprite\nexport default function loadSprite(url, id) {\n if (!is.string(url)) {\n return;\n }\n\n const prefix = 'cache';\n const hasId = is.string(id);\n let isCached = false;\n\n const exists = () => document.getElementById(id) !== null;\n\n const update = (container, data) => {\n container.innerHTML = data;\n\n // Check again incase of race condition\n if (hasId && exists()) {\n return;\n }\n\n // Inject the SVG to the body\n document.body.insertAdjacentElement('afterbegin', container);\n };\n\n // Only load once if ID set\n if (!hasId || !exists()) {\n const useStorage = Storage.supported;\n\n // Create container\n const container = document.createElement('div');\n container.setAttribute('hidden', '');\n\n if (hasId) {\n container.setAttribute('id', id);\n }\n\n // Check in cache\n if (useStorage) {\n const cached = window.localStorage.getItem(`${prefix}-${id}`);\n isCached = cached !== null;\n\n if (isCached) {\n const data = JSON.parse(cached);\n update(container, data.content);\n }\n }\n\n // Get the sprite\n fetch(url)\n .then(result => {\n if (is.empty(result)) {\n return;\n }\n\n if (useStorage) {\n window.localStorage.setItem(\n `${prefix}-${id}`,\n JSON.stringify({\n content: result,\n }),\n );\n }\n\n update(container, result);\n })\n .catch(() => {});\n }\n}\n","// ==========================================================================\n// Time utils\n// ==========================================================================\n\nimport is from './is';\n\n// Time helpers\nexport const getHours = value => parseInt((value / 60 / 60) % 60, 10);\nexport const getMinutes = value => parseInt((value / 60) % 60, 10);\nexport const getSeconds = value => parseInt(value % 60, 10);\n\n// Format time to UI friendly string\nexport function formatTime(time = 0, displayHours = false, inverted = false) {\n // Bail if the value isn't a number\n if (!is.number(time)) {\n return formatTime(null, displayHours, inverted);\n }\n\n // Format time component to add leading zero\n const format = value => `0${value}`.slice(-2);\n\n // Breakdown to hours, mins, secs\n let hours = getHours(time);\n const mins = getMinutes(time);\n const secs = getSeconds(time);\n\n // Do we need to display hours?\n if (displayHours || hours > 0) {\n hours = `${hours}:`;\n } else {\n hours = '';\n }\n\n // Render\n return `${inverted && time > 0 ? '-' : ''}${hours}${format(mins)}:${format(secs)}`;\n}\n","// ==========================================================================\n// Plyr controls\n// ==========================================================================\n\nimport captions from './captions';\nimport html5 from './html5';\nimport i18n from './i18n';\nimport support from './support';\nimport { repaint, transitionEndEvent } from './utils/animation';\nimport { dedupe } from './utils/arrays';\nimport browser from './utils/browser';\nimport { createElement, emptyElement, getAttributesFromSelector, getElement, getElements, hasClass, matches, removeElement, setAttributes, toggleClass, toggleHidden } from './utils/elements';\nimport { off, on } from './utils/events';\nimport is from './utils/is';\nimport loadSprite from './utils/loadSprite';\nimport { extend } from './utils/objects';\nimport { getPercentage, replaceAll, toCamelCase, toTitleCase } from './utils/strings';\nimport { formatTime, getHours } from './utils/time';\n\n// TODO: Don't export a massive object - break down and create class\nconst controls = {\n // Get icon URL\n getIconUrl() {\n const url = new URL(this.config.iconUrl, window.location);\n const cors = url.host !== window.location.host || (browser.isIE && !window.svg4everybody);\n\n return {\n url: this.config.iconUrl,\n cors,\n };\n },\n\n // Find the UI controls\n findElements() {\n try {\n this.elements.controls = getElement.call(this, this.config.selectors.controls.wrapper);\n\n // Buttons\n this.elements.buttons = {\n play: getElements.call(this, this.config.selectors.buttons.play),\n pause: getElement.call(this, this.config.selectors.buttons.pause),\n restart: getElement.call(this, this.config.selectors.buttons.restart),\n rewind: getElement.call(this, this.config.selectors.buttons.rewind),\n fastForward: getElement.call(this, this.config.selectors.buttons.fastForward),\n mute: getElement.call(this, this.config.selectors.buttons.mute),\n pip: getElement.call(this, this.config.selectors.buttons.pip),\n airplay: getElement.call(this, this.config.selectors.buttons.airplay),\n settings: getElement.call(this, this.config.selectors.buttons.settings),\n captions: getElement.call(this, this.config.selectors.buttons.captions),\n fullscreen: getElement.call(this, this.config.selectors.buttons.fullscreen),\n };\n\n // Progress\n this.elements.progress = getElement.call(this, this.config.selectors.progress);\n\n // Inputs\n this.elements.inputs = {\n seek: getElement.call(this, this.config.selectors.inputs.seek),\n volume: getElement.call(this, this.config.selectors.inputs.volume),\n };\n\n // Display\n this.elements.display = {\n buffer: getElement.call(this, this.config.selectors.display.buffer),\n currentTime: getElement.call(this, this.config.selectors.display.currentTime),\n duration: getElement.call(this, this.config.selectors.display.duration),\n };\n\n // Seek tooltip\n if (is.element(this.elements.progress)) {\n this.elements.display.seekTooltip = this.elements.progress.querySelector(\n `.${this.config.classNames.tooltip}`,\n );\n }\n\n return true;\n } catch (error) {\n // Log it\n this.debug.warn('It looks like there is a problem with your custom controls HTML', error);\n\n // Restore native video controls\n this.toggleNativeControls(true);\n\n return false;\n }\n },\n\n // Create <svg> icon\n createIcon(type, attributes) {\n const namespace = 'http://www.w3.org/2000/svg';\n const iconUrl = controls.getIconUrl.call(this);\n const iconPath = `${!iconUrl.cors ? iconUrl.url : ''}#${this.config.iconPrefix}`;\n\n // Create <svg>\n const icon = document.createElementNS(namespace, 'svg');\n setAttributes(\n icon,\n extend(attributes, {\n role: 'presentation',\n focusable: 'false',\n }),\n );\n\n // Create the <use> to reference sprite\n const use = document.createElementNS(namespace, 'use');\n const path = `${iconPath}-${type}`;\n\n // Set `href` attributes\n // https://github.com/sampotts/plyr/issues/460\n // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href\n if ('href' in use) {\n use.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);\n } else {\n use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', path);\n }\n\n // Add <use> to <svg>\n icon.appendChild(use);\n\n return icon;\n },\n\n // Create hidden text label\n createLabel(type, attr = {}) {\n // Skip i18n for abbreviations and brand names\n const universals = {\n pip: 'PIP',\n airplay: 'AirPlay',\n };\n const text = universals[type] || i18n.get(type, this.config);\n\n const attributes = Object.assign({}, attr, {\n class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' '),\n });\n return createElement('span', attributes, text);\n },\n\n // Create a badge\n createBadge(text) {\n if (is.empty(text)) {\n return null;\n }\n\n const badge = createElement('span', {\n class: this.config.classNames.menu.value,\n });\n\n badge.appendChild(\n createElement(\n 'span',\n {\n class: this.config.classNames.menu.badge,\n },\n text,\n ),\n );\n\n return badge;\n },\n\n // Create a <button>\n createButton(buttonType, attr) {\n const button = createElement('button');\n const attributes = Object.assign({}, attr);\n let type = toCamelCase(buttonType);\n\n let toggle = false;\n let label;\n let icon;\n let labelPressed;\n let iconPressed;\n\n if (!('type' in attributes)) {\n attributes.type = 'button';\n }\n\n if ('class' in attributes) {\n if (attributes.class.includes(this.config.classNames.control)) {\n attributes.class += ` ${this.config.classNames.control}`;\n }\n } else {\n attributes.class = this.config.classNames.control;\n }\n\n // Large play button\n switch (buttonType) {\n case 'play':\n toggle = true;\n label = 'play';\n labelPressed = 'pause';\n icon = 'play';\n iconPressed = 'pause';\n break;\n\n case 'mute':\n toggle = true;\n label = 'mute';\n labelPressed = 'unmute';\n icon = 'volume';\n iconPressed = 'muted';\n break;\n\n case 'captions':\n toggle = true;\n label = 'enableCaptions';\n labelPressed = 'disableCaptions';\n icon = 'captions-off';\n iconPressed = 'captions-on';\n break;\n\n case 'fullscreen':\n toggle = true;\n label = 'enterFullscreen';\n labelPressed = 'exitFullscreen';\n icon = 'enter-fullscreen';\n iconPressed = 'exit-fullscreen';\n break;\n\n case 'play-large':\n attributes.class += ` ${this.config.classNames.control}--overlaid`;\n type = 'play';\n label = 'play';\n icon = 'play';\n break;\n\n default:\n label = type;\n icon = buttonType;\n }\n\n // Setup toggle icon and labels\n if (toggle) {\n // Icon\n button.appendChild(controls.createIcon.call(this, iconPressed, { class: 'icon--pressed' }));\n button.appendChild(controls.createIcon.call(this, icon, { class: 'icon--not-pressed' }));\n\n // Label/Tooltip\n button.appendChild(controls.createLabel.call(this, labelPressed, { class: 'label--pressed' }));\n button.appendChild(controls.createLabel.call(this, label, { class: 'label--not-pressed' }));\n } else {\n button.appendChild(controls.createIcon.call(this, icon));\n button.appendChild(controls.createLabel.call(this, label));\n }\n\n // Merge attributes\n extend(attributes, getAttributesFromSelector(this.config.selectors.buttons[type], attributes));\n\n setAttributes(button, attributes);\n\n // We have multiple play buttons\n if (type === 'play') {\n if (!is.array(this.elements.buttons[type])) {\n this.elements.buttons[type] = [];\n }\n\n this.elements.buttons[type].push(button);\n } else {\n this.elements.buttons[type] = button;\n }\n\n // Toggle classname when pressed property is set\n const className = this.config.classNames.controlPressed;\n Object.defineProperty(button, 'pressed', {\n enumerable: true,\n get() {\n return hasClass(button, className);\n },\n set(pressed = false) {\n toggleClass(button, className, pressed);\n },\n });\n\n return button;\n },\n\n // Create an <input type='range'>\n createRange(type, attributes) {\n // Seek input\n const input = createElement(\n 'input',\n extend(\n getAttributesFromSelector(this.config.selectors.inputs[type]),\n {\n type: 'range',\n min: 0,\n max: 100,\n step: 0.01,\n value: 0,\n autocomplete: 'off',\n // A11y fixes for https://github.com/sampotts/plyr/issues/905\n role: 'slider',\n 'aria-label': i18n.get(type, this.config),\n 'aria-valuemin': 0,\n 'aria-valuemax': 100,\n 'aria-valuenow': 0,\n },\n attributes,\n ),\n );\n\n this.elements.inputs[type] = input;\n\n // Set the fill for webkit now\n controls.updateRangeFill.call(this, input);\n\n return input;\n },\n\n // Create a <progress>\n createProgress(type, attributes) {\n const progress = createElement(\n 'progress',\n extend(\n getAttributesFromSelector(this.config.selectors.display[type]),\n {\n min: 0,\n max: 100,\n value: 0,\n role: 'presentation',\n 'aria-hidden': true,\n },\n attributes,\n ),\n );\n\n // Create the label inside\n if (type !== 'volume') {\n progress.appendChild(createElement('span', null, '0'));\n\n const suffixKey = {\n played: 'played',\n buffer: 'buffered',\n }[type];\n const suffix = suffixKey ? i18n.get(suffixKey, this.config) : '';\n\n progress.innerText = `% ${suffix.toLowerCase()}`;\n }\n\n this.elements.display[type] = progress;\n\n return progress;\n },\n\n // Create time display\n createTime(type) {\n const attributes = getAttributesFromSelector(this.config.selectors.display[type]);\n\n const container = createElement(\n 'div',\n extend(attributes, {\n class: `${this.config.classNames.display.time} ${attributes.class ? attributes.class : ''}`.trim(),\n 'aria-label': i18n.get(type, this.config),\n }),\n '00:00',\n );\n\n // Reference for updates\n this.elements.display[type] = container;\n\n return container;\n },\n\n // Create a settings menu item\n createMenuItem({ value, list, type, title, badge = null, checked = false }) {\n const attributes = getAttributesFromSelector(this.config.selectors.inputs[type]);\n\n const item = createElement(\n 'button',\n extend(attributes, {\n type: 'button',\n role: 'menuitemradio',\n class: `${this.config.classNames.control} ${attributes.class ? attributes.class : ''}`.trim(),\n value,\n 'aria-checked': checked,\n })\n );\n\n // We have to set as HTML incase of special characters\n item.innerHTML = title;\n\n if (is.element(badge)) {\n item.appendChild(badge);\n }\n\n Object.defineProperty(item, 'checked', {\n enumerable: true,\n get() {\n return item.getAttribute('aria-checked') === 'true';\n },\n set(checked) {\n // Ensure exclusivity\n if (checked) {\n Array.from(item.parentNode.children)\n .filter(node => matches(node, '[role=\"menuitemradio\"]'))\n .forEach(node => node.setAttribute('aria-checked', 'false'));\n }\n\n item.setAttribute('aria-checked', checked ? 'true' : 'false');\n },\n });\n\n list.appendChild(item);\n },\n\n // Format a time for display\n formatTime(time = 0, inverted = false) {\n // Bail if the value isn't a number\n if (!is.number(time)) {\n return time;\n }\n\n // Always display hours if duration is over an hour\n const forceHours = getHours(this.duration) > 0;\n\n return formatTime(time, forceHours, inverted);\n },\n\n // Update the displayed time\n updateTimeDisplay(target = null, time = 0, inverted = false) {\n // Bail if there's no element to display or the value isn't a number\n if (!is.element(target) || !is.number(time)) {\n return;\n }\n\n // eslint-disable-next-line no-param-reassign\n target.innerText = controls.formatTime(time, inverted);\n },\n\n // Update volume UI and storage\n updateVolume() {\n if (!this.supported.ui) {\n return;\n }\n\n // Update range\n if (is.element(this.elements.inputs.volume)) {\n controls.setRange.call(this, this.elements.inputs.volume, this.muted ? 0 : this.volume);\n }\n\n // Update mute state\n if (is.element(this.elements.buttons.mute)) {\n this.elements.buttons.mute.pressed = this.muted || this.volume === 0;\n }\n },\n\n // Update seek value and lower fill\n setRange(target, value = 0) {\n if (!is.element(target)) {\n return;\n }\n\n // eslint-disable-next-line\n target.value = value;\n\n // Webkit range fill\n controls.updateRangeFill.call(this, target);\n },\n\n // Update <progress> elements\n updateProgress(event) {\n if (!this.supported.ui || !is.event(event)) {\n return;\n }\n\n let value = 0;\n\n const setProgress = (target, input) => {\n const value = is.number(input) ? input : 0;\n const progress = is.element(target) ? target : this.elements.display.buffer;\n\n // Update value and label\n if (is.element(progress)) {\n progress.value = value;\n\n // Update text label inside\n const label = progress.getElementsByTagName('span')[0];\n if (is.element(label)) {\n label.childNodes[0].nodeValue = value;\n }\n }\n };\n\n if (event) {\n switch (event.type) {\n // Video playing\n case 'timeupdate':\n case 'seeking':\n case 'seeked':\n value = getPercentage(this.currentTime, this.duration);\n\n // Set seek range value only if it's a 'natural' time event\n if (event.type === 'timeupdate') {\n controls.setRange.call(this, this.elements.inputs.seek, value);\n }\n\n break;\n\n // Check buffer status\n case 'playing':\n case 'progress':\n setProgress(this.elements.display.buffer, this.buffered * 100);\n\n break;\n\n default:\n break;\n }\n }\n },\n\n // Webkit polyfill for lower fill range\n updateRangeFill(target) {\n // Get range from event if event passed\n const range = is.event(target) ? target.target : target;\n\n // Needs to be a valid <input type='range'>\n if (!is.element(range) || range.getAttribute('type') !== 'range') {\n return;\n }\n\n // Set aria values for https://github.com/sampotts/plyr/issues/905\n if (matches(range, this.config.selectors.inputs.seek)) {\n range.setAttribute('aria-valuenow', this.currentTime);\n const currentTime = controls.formatTime(this.currentTime);\n const duration = controls.formatTime(this.duration);\n const format = i18n.get('seekLabel', this.config);\n range.setAttribute(\n 'aria-valuetext',\n format.replace('{currentTime}', currentTime).replace('{duration}', duration),\n );\n } else if (matches(range, this.config.selectors.inputs.volume)) {\n const percent = range.value * 100;\n range.setAttribute('aria-valuenow', percent);\n range.setAttribute('aria-valuetext', `${percent}%`);\n } else {\n range.setAttribute('aria-valuenow', range.value);\n }\n\n // WebKit only\n if (!browser.isWebkit) {\n return;\n }\n\n // Set CSS custom property\n range.style.setProperty('--value', `${range.value / range.max * 100}%`);\n },\n\n // Update hover tooltip for seeking\n updateSeekTooltip(event) {\n // Bail if setting not true\n if (\n !this.config.tooltips.seek ||\n !is.element(this.elements.inputs.seek) ||\n !is.element(this.elements.display.seekTooltip) ||\n this.duration === 0\n ) {\n return;\n }\n\n // Calculate percentage\n let percent = 0;\n const clientRect = this.elements.progress.getBoundingClientRect();\n const visible = `${this.config.classNames.tooltip}--visible`;\n\n const toggle = toggle => {\n toggleClass(this.elements.display.seekTooltip, visible, toggle);\n };\n\n // Hide on touch\n if (this.touch) {\n toggle(false);\n return;\n }\n\n // Determine percentage, if already visible\n if (is.event(event)) {\n percent = 100 / clientRect.width * (event.pageX - clientRect.left);\n } else if (hasClass(this.elements.display.seekTooltip, visible)) {\n percent = parseFloat(this.elements.display.seekTooltip.style.left, 10);\n } else {\n return;\n }\n\n // Set bounds\n if (percent < 0) {\n percent = 0;\n } else if (percent > 100) {\n percent = 100;\n }\n\n // Display the time a click would seek to\n controls.updateTimeDisplay.call(this, this.elements.display.seekTooltip, this.duration / 100 * percent);\n\n // Set position\n this.elements.display.seekTooltip.style.left = `${percent}%`;\n\n // Show/hide the tooltip\n // If the event is a moues in/out and percentage is inside bounds\n if (is.event(event) && ['mouseenter', 'mouseleave'].includes(event.type)) {\n toggle(event.type === 'mouseenter');\n }\n },\n\n // Handle time change event\n timeUpdate(event) {\n // Only invert if only one time element is displayed and used for both duration and currentTime\n const invert = !is.element(this.elements.display.duration) && this.config.invertTime;\n\n // Duration\n controls.updateTimeDisplay.call(\n this,\n this.elements.display.currentTime,\n invert ? this.duration - this.currentTime : this.currentTime,\n invert,\n );\n\n // Ignore updates while seeking\n if (event && event.type === 'timeupdate' && this.media.seeking) {\n return;\n }\n\n // Playing progress\n controls.updateProgress.call(this, event);\n },\n\n // Show the duration on metadataloaded or durationchange events\n durationUpdate() {\n // Bail if no UI or durationchange event triggered after playing/seek when invertTime is false\n if (!this.supported.ui || (!this.config.invertTime && this.currentTime)) {\n return;\n }\n\n // Update ARIA values\n if (is.element(this.elements.inputs.seek)) {\n this.elements.inputs.seek.setAttribute('aria-valuemax', this.duration);\n }\n\n // If there's a spot to display duration\n const hasDuration = is.element(this.elements.display.duration);\n\n // If there's only one time display, display duration there\n if (!hasDuration && this.config.displayDuration && this.paused) {\n controls.updateTimeDisplay.call(this, this.elements.display.currentTime, this.duration);\n }\n\n // If there's a duration element, update content\n if (hasDuration) {\n controls.updateTimeDisplay.call(this, this.elements.display.duration, this.duration);\n }\n\n // Update the tooltip (if visible)\n controls.updateSeekTooltip.call(this);\n },\n\n // Hide/show a tab\n toggleMenuButton(setting, toggle) {\n toggleHidden(this.elements.settings.buttons[setting], !toggle);\n },\n\n // Set the quality menu\n setQualityMenu(options) {\n // Menu required\n if (!is.element(this.elements.settings.panels.quality)) {\n return;\n }\n\n const type = 'quality';\n const list = this.elements.settings.panels.quality.querySelector('[role=\"menu\"]');\n\n // Set options if passed and filter based on uniqueness and config\n if (is.array(options)) {\n this.options.quality = dedupe(options).filter(quality => this.config.quality.options.includes(quality));\n }\n\n // Toggle the pane and tab\n const toggle = !is.empty(this.options.quality) && this.options.quality.length > 1;\n controls.toggleMenuButton.call(this, type, toggle);\n\n // Check if we need to toggle the parent\n controls.checkMenu.call(this);\n\n // If we're hiding, nothing more to do\n if (!toggle) {\n return;\n }\n\n // Empty the menu\n emptyElement(list);\n\n // Get the badge HTML for HD, 4K etc\n const getBadge = quality => {\n const label = i18n.get(`qualityBadge.${quality}`, this.config);\n\n if (!label.length) {\n return null;\n }\n\n return controls.createBadge.call(this, label);\n };\n\n // Sort options by the config and then render options\n this.options.quality\n .sort((a, b) => {\n const sorting = this.config.quality.options;\n return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;\n })\n .forEach(quality => {\n controls.createMenuItem.call(this, {\n value: quality,\n list,\n type,\n title: controls.getLabel.call(this, 'quality', quality),\n badge: getBadge(quality),\n });\n });\n\n controls.updateSetting.call(this, type, list);\n },\n\n // Translate a value into a nice label\n getLabel(setting, value) {\n switch (setting) {\n case 'speed':\n return value === 1 ? i18n.get('normal', this.config) : `${value}×`;\n\n case 'quality':\n if (is.number(value)) {\n const label = i18n.get(`qualityLabel.${value}`, this.config);\n\n if (!label.length) {\n return `${value}p`;\n }\n\n return label;\n }\n\n return toTitleCase(value);\n\n case 'captions':\n return captions.getLabel.call(this);\n\n default:\n return null;\n }\n },\n\n // Update the selected setting\n updateSetting(setting, container, input) {\n const pane = this.elements.settings.panels[setting];\n let value = null;\n let list = container;\n\n if (setting === 'captions') {\n value = this.currentTrack;\n } else {\n value = !is.empty(input) ? input : this[setting];\n\n // Get default\n if (is.empty(value)) {\n value = this.config[setting].default;\n }\n\n // Unsupported value\n if (!is.empty(this.options[setting]) && !this.options[setting].includes(value)) {\n this.debug.warn(`Unsupported value of '${value}' for ${setting}`);\n return;\n }\n\n // Disabled value\n if (!this.config[setting].options.includes(value)) {\n this.debug.warn(`Disabled value of '${value}' for ${setting}`);\n return;\n }\n }\n\n // Get the list if we need to\n if (!is.element(list)) {\n list = pane && pane.querySelector('[role=\"menu\"]');\n }\n\n // If there's no list it means it's not been rendered...\n if (!is.element(list)) {\n return;\n }\n\n // Update the label\n const label = this.elements.settings.buttons[setting].querySelector(`.${this.config.classNames.menu.value}`);\n label.innerHTML = controls.getLabel.call(this, setting, value);\n\n // Find the radio option and check it\n const target = list && list.querySelector(`[value=\"${value}\"]`);\n\n if (is.element(target)) {\n target.checked = true;\n }\n },\n\n // Set the looping options\n /* setLoopMenu() {\n // Menu required\n if (!is.element(this.elements.settings.panels.loop)) {\n return;\n }\n\n const options = ['start', 'end', 'all', 'reset'];\n const list = this.elements.settings.panels.loop.querySelector('[role=\"menu\"]');\n\n // Show the pane and tab\n toggleHidden(this.elements.settings.buttons.loop, false);\n toggleHidden(this.elements.settings.panels.loop, false);\n\n // Toggle the pane and tab\n const toggle = !is.empty(this.loop.options);\n controls.toggleMenuButton.call(this, 'loop', toggle);\n\n // Empty the menu\n emptyElement(list);\n\n options.forEach(option => {\n const item = createElement('li');\n\n const button = createElement(\n 'button',\n extend(getAttributesFromSelector(this.config.selectors.buttons.loop), {\n type: 'button',\n class: this.config.classNames.control,\n 'data-plyr-loop-action': option,\n }),\n i18n.get(option, this.config)\n );\n\n if (['start', 'end'].includes(option)) {\n const badge = controls.createBadge.call(this, '00:00');\n button.appendChild(badge);\n }\n\n item.appendChild(button);\n list.appendChild(item);\n });\n }, */\n\n // Get current selected caption language\n // TODO: rework this to user the getter in the API?\n\n // Set a list of available captions languages\n setCaptionsMenu() {\n // TODO: Captions or language? Currently it's mixed\n const type = 'captions';\n const list = this.elements.settings.panels.captions.querySelector('[role=\"menu\"]');\n const tracks = captions.getTracks.call(this);\n\n // Toggle the pane and tab\n controls.toggleMenuButton.call(this, type, tracks.length);\n\n // Empty the menu\n emptyElement(list);\n\n // Check if we need to toggle the parent\n controls.checkMenu.call(this);\n\n // If there's no captions, bail\n if (!tracks.length) {\n return;\n }\n\n // Generate options data\n const options = tracks.map((track, value) => ({\n value,\n checked: this.captions.toggled && this.currentTrack === value,\n title: captions.getLabel.call(this, track),\n badge: track.language && controls.createBadge.call(this, track.language.toUpperCase()),\n list,\n type: 'language',\n }));\n\n // Add the \"Disabled\" option to turn off captions\n options.unshift({\n value: -1,\n checked: !this.captions.toggled,\n title: i18n.get('disabled', this.config),\n list,\n type: 'language',\n });\n\n // Generate options\n options.forEach(controls.createMenuItem.bind(this));\n\n controls.updateSetting.call(this, type, list);\n },\n\n // Set a list of available captions languages\n setSpeedMenu(options) {\n // Do nothing if not selected\n if (!this.config.controls.includes('settings') || !this.config.settings.includes('speed')) {\n return;\n }\n\n // Menu required\n if (!is.element(this.elements.settings.panels.speed)) {\n return;\n }\n\n const type = 'speed';\n\n // Set the speed options\n if (is.array(options)) {\n this.options.speed = options;\n } else if (this.isHTML5 || this.isVimeo) {\n this.options.speed = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];\n }\n\n // Set options if passed and filter based on config\n this.options.speed = this.options.speed.filter(speed => this.config.speed.options.includes(speed));\n\n // Toggle the pane and tab\n const toggle = !is.empty(this.options.speed) && this.options.speed.length > 1;\n controls.toggleMenuButton.call(this, type, toggle);\n\n // Check if we need to toggle the parent\n controls.checkMenu.call(this);\n\n // If we're hiding, nothing more to do\n if (!toggle) {\n return;\n }\n\n // Get the list to populate\n const list = this.elements.settings.panels.speed.querySelector('[role=\"menu\"]');\n\n // Empty the menu\n emptyElement(list);\n\n // Create items\n this.options.speed.forEach(speed => {\n controls.createMenuItem.call(this, {\n value: speed,\n list,\n type,\n title: controls.getLabel.call(this, 'speed', speed),\n });\n });\n\n controls.updateSetting.call(this, type, list);\n },\n\n // Check if we need to hide/show the settings menu\n checkMenu() {\n const { buttons } = this.elements.settings;\n const visible = !is.empty(buttons) && Object.values(buttons).some(button => !button.hidden);\n\n toggleHidden(this.elements.settings.menu, !visible);\n },\n\n // Show/hide menu\n toggleMenu(event) {\n const { popup } = this.elements.settings;\n const button = this.elements.buttons.settings;\n\n // Menu and button are required\n if (!is.element(popup) || !is.element(button)) {\n return;\n }\n\n const show = is.boolean(event) ? event : is.element(popup) && popup.hasAttribute('hidden');\n\n if (is.event(event)) {\n const isMenuItem = is.element(popup) && popup.contains(event.target);\n const isButton = event.target === this.elements.buttons.settings;\n\n // If the click was inside the form or if the click\n // wasn't the button or menu item and we're trying to\n // show the menu (a doc click shouldn't show the menu)\n if (isMenuItem || (!isMenuItem && !isButton && show)) {\n return;\n }\n\n // Prevent the toggle being caught by the doc listener\n if (isButton) {\n event.stopPropagation();\n }\n }\n\n // Set form and button attributes\n if (is.element(button)) {\n button.setAttribute('aria-expanded', show);\n }\n\n if (is.element(popup)) {\n toggleHidden(popup, !show);\n toggleClass(this.elements.container, this.config.classNames.menu.open, show);\n\n if (show) {\n popup.removeAttribute('tabindex');\n } else {\n popup.setAttribute('tabindex', -1);\n }\n }\n },\n\n // Get the natural size of a menu panel\n getMenuSize(tab) {\n const clone = tab.cloneNode(true);\n clone.style.position = 'absolute';\n clone.style.opacity = 0;\n clone.removeAttribute('hidden');\n\n // Append to parent so we get the \"real\" size\n tab.parentNode.appendChild(clone);\n\n // Get the sizes before we remove\n const width = clone.scrollWidth;\n const height = clone.scrollHeight;\n\n // Remove from the DOM\n removeElement(clone);\n\n return {\n width,\n height,\n };\n },\n\n // Show a panel in the menu\n showMenuPanel(type = '') {\n const target = document.getElementById(`plyr-settings-${this.id}-${type}`);\n\n // Nothing to show, bail\n if (!is.element(target)) {\n return;\n }\n\n // Hide all other panels\n const container = target.parentNode;\n const current = Array.from(container.children).find(node => !node.hidden);\n\n // If we can do fancy animations, we'll animate the height/width\n if (support.transitions && !support.reducedMotion) {\n // Set the current width as a base\n container.style.width = `${current.scrollWidth}px`;\n container.style.height = `${current.scrollHeight}px`;\n\n // Get potential sizes\n const size = controls.getMenuSize.call(this, target);\n\n // Restore auto height/width\n const restore = event => {\n // We're only bothered about height and width on the container\n if (event.target !== container || !['width', 'height'].includes(event.propertyName)) {\n return;\n }\n\n // Revert back to auto\n container.style.width = '';\n container.style.height = '';\n\n // Only listen once\n off.call(this, container, transitionEndEvent, restore);\n };\n\n // Listen for the transition finishing and restore auto height/width\n on.call(this, container, transitionEndEvent, restore);\n\n // Set dimensions to target\n container.style.width = `${size.width}px`;\n container.style.height = `${size.height}px`;\n }\n\n // Set attributes on current tab\n toggleHidden(current, true);\n // current.setAttribute('tabindex', -1);\n\n // Set attributes on target\n toggleHidden(target, false);\n\n // Focus the first item\n target.querySelectorAll('[role^=\"menuitem\"]')[0].focus();\n },\n\n // Build the default HTML\n // TODO: Set order based on order in the config.controls array?\n create(data) {\n // Do nothing if we want no controls\n if (is.empty(this.config.controls)) {\n return null;\n }\n\n // Create the container\n const container = createElement('div', getAttributesFromSelector(this.config.selectors.controls.wrapper));\n\n // Restart button\n if (this.config.controls.includes('restart')) {\n container.appendChild(controls.createButton.call(this, 'restart'));\n }\n\n // Rewind button\n if (this.config.controls.includes('rewind')) {\n container.appendChild(controls.createButton.call(this, 'rewind'));\n }\n\n // Play/Pause button\n if (this.config.controls.includes('play')) {\n container.appendChild(controls.createButton.call(this, 'play'));\n }\n\n // Fast forward button\n if (this.config.controls.includes('fast-forward')) {\n container.appendChild(controls.createButton.call(this, 'fast-forward'));\n }\n\n // Progress\n if (this.config.controls.includes('progress')) {\n const progress = createElement('div', getAttributesFromSelector(this.config.selectors.progress));\n\n // Seek range slider\n progress.appendChild(\n controls.createRange.call(this, 'seek', {\n id: `plyr-seek-${data.id}`,\n }),\n );\n\n // Buffer progress\n progress.appendChild(controls.createProgress.call(this, 'buffer'));\n\n // TODO: Add loop display indicator\n\n // Seek tooltip\n if (this.config.tooltips.seek) {\n const tooltip = createElement(\n 'span',\n {\n class: this.config.classNames.tooltip,\n },\n '00:00',\n );\n\n progress.appendChild(tooltip);\n this.elements.display.seekTooltip = tooltip;\n }\n\n this.elements.progress = progress;\n container.appendChild(this.elements.progress);\n }\n\n // Media current time display\n if (this.config.controls.includes('current-time')) {\n container.appendChild(controls.createTime.call(this, 'currentTime'));\n }\n\n // Media duration display\n if (this.config.controls.includes('duration')) {\n container.appendChild(controls.createTime.call(this, 'duration'));\n }\n\n // Toggle mute button\n if (this.config.controls.includes('mute')) {\n container.appendChild(controls.createButton.call(this, 'mute'));\n }\n\n // Volume range control\n if (this.config.controls.includes('volume')) {\n const volume = createElement('div', {\n class: 'plyr__volume',\n });\n\n // Set the attributes\n const attributes = {\n max: 1,\n step: 0.05,\n value: this.config.volume,\n };\n\n // Create the volume range slider\n volume.appendChild(\n controls.createRange.call(\n this,\n 'volume',\n extend(attributes, {\n id: `plyr-volume-${data.id}`,\n }),\n ),\n );\n\n this.elements.volume = volume;\n\n container.appendChild(volume);\n }\n\n // Toggle captions button\n if (this.config.controls.includes('captions')) {\n container.appendChild(controls.createButton.call(this, 'captions'));\n }\n\n // Settings button / menu\n if (this.config.controls.includes('settings') && !is.empty(this.config.settings)) {\n const control = createElement('div', {\n class: 'plyr__menu',\n hidden: '',\n });\n\n control.appendChild(\n controls.createButton.call(this, 'settings', {\n id: `plyr-settings-toggle-${data.id}`,\n 'aria-haspopup': true,\n 'aria-controls': `plyr-settings-${data.id}`,\n 'aria-expanded': false,\n }),\n );\n\n const popup = createElement('div', {\n class: 'plyr__menu__container',\n id: `plyr-settings-${data.id}`,\n hidden: '',\n 'aria-labelled-by': `plyr-settings-toggle-${data.id}`,\n });\n\n const inner = createElement('div');\n\n const home = createElement('div', {\n id: `plyr-settings-${data.id}-home`,\n });\n\n // Create the menu\n const menu = createElement('div', {\n role: 'menu',\n });\n\n // Build the menu items\n this.config.settings.forEach(type => {\n const menuItem = createElement(\n 'button',\n extend(getAttributesFromSelector(this.config.selectors.buttons.settings), {\n type: 'button',\n class: `${this.config.classNames.control} ${this.config.classNames.control}--forward`,\n role: 'menuitem',\n 'aria-haspopup': true,\n }),\n );\n\n const flex = createElement('span', null, i18n.get(type, this.config));\n\n const value = createElement('span', {\n class: this.config.classNames.menu.value,\n });\n\n // Speed contains HTML entities\n value.innerHTML = data[type];\n\n flex.appendChild(value);\n menuItem.appendChild(flex);\n menu.appendChild(menuItem);\n\n // Build the panes\n const pane = createElement('div', {\n id: `plyr-settings-${data.id}-${type}`,\n hidden: '',\n });\n\n // Back button\n const back = createElement(\n 'button',\n {\n type: 'button',\n class: `${this.config.classNames.control} ${this.config.classNames.control}--back`,\n },\n i18n.get(type, this.config),\n );\n back.addEventListener('click', () => {\n controls.showMenuPanel.call(this, 'home');\n });\n pane.appendChild(back);\n\n // Menu\n pane.appendChild(\n createElement('div', {\n role: 'menu',\n }),\n );\n\n inner.appendChild(pane);\n\n menuItem.addEventListener('click', () => {\n controls.showMenuPanel.call(this, type);\n });\n\n this.elements.settings.buttons[type] = menuItem;\n this.elements.settings.panels[type] = pane;\n });\n\n home.appendChild(menu);\n inner.appendChild(home);\n\n popup.appendChild(inner);\n control.appendChild(popup);\n container.appendChild(control);\n\n this.elements.settings.popup = popup;\n this.elements.settings.menu = control;\n }\n\n // Picture in picture button\n if (this.config.controls.includes('pip') && support.pip) {\n container.appendChild(controls.createButton.call(this, 'pip'));\n }\n\n // Airplay button\n if (this.config.controls.includes('airplay') && support.airplay) {\n container.appendChild(controls.createButton.call(this, 'airplay'));\n }\n\n // Toggle fullscreen button\n if (this.config.controls.includes('fullscreen')) {\n container.appendChild(controls.createButton.call(this, 'fullscreen'));\n }\n\n // Larger overlaid play button\n if (this.config.controls.includes('play-large')) {\n this.elements.container.appendChild(controls.createButton.call(this, 'play-large'));\n }\n\n this.elements.controls = container;\n\n if (this.isHTML5) {\n controls.setQualityMenu.call(this, html5.getQualityOptions.call(this));\n }\n\n controls.setSpeedMenu.call(this);\n\n return container;\n },\n\n // Insert controls\n inject() {\n // Sprite\n if (this.config.loadSprite) {\n const icon = controls.getIconUrl.call(this);\n\n // Only load external sprite using AJAX\n if (icon.cors) {\n loadSprite(icon.url, 'sprite-plyr');\n }\n }\n\n // Create a unique ID\n this.id = Math.floor(Math.random() * 10000);\n\n // Null by default\n let container = null;\n this.elements.controls = null;\n\n // Set template properties\n const props = {\n id: this.id,\n seektime: this.config.seekTime,\n title: this.config.title,\n };\n let update = true;\n\n if (is.string(this.config.controls) || is.element(this.config.controls)) {\n // String or HTMLElement passed as the option\n container = this.config.controls;\n } else if (is.function(this.config.controls)) {\n // A custom function to build controls\n // The function can return a HTMLElement or String\n container = this.config.controls.call(this, props);\n } else {\n // Create controls\n container = controls.create.call(this, {\n id: this.id,\n seektime: this.config.seekTime,\n speed: this.speed,\n quality: this.quality,\n captions: captions.getLabel.call(this),\n // TODO: Looping\n // loop: 'None',\n });\n update = false;\n }\n\n // Replace props with their value\n const replace = input => {\n let result = input;\n\n Object.entries(props).forEach(([key, value]) => {\n result = replaceAll(result, `{${key}}`, value);\n });\n\n return result;\n };\n\n // Update markup\n if (update) {\n if (is.string(this.config.controls)) {\n container = replace(container);\n } else if (is.element(container)) {\n container.innerHTML = replace(container.innerHTML);\n }\n }\n\n // Controls container\n let target;\n\n // Inject to custom location\n if (is.string(this.config.selectors.controls.container)) {\n target = document.querySelector(this.config.selectors.controls.container);\n }\n\n // Inject into the container by default\n if (!is.element(target)) {\n target = this.elements.container;\n }\n\n // Inject controls HTML\n if (is.element(container)) {\n target.appendChild(container);\n } else if (container) {\n target.insertAdjacentHTML('beforeend', container);\n }\n\n // Find the elements if need be\n if (!is.element(this.elements.controls)) {\n controls.findElements.call(this);\n }\n\n // Edge sometimes doesn't finish the paint so force a redraw\n if (window.navigator.userAgent.includes('Edge')) {\n repaint(target);\n }\n\n // Setup tooltips\n if (this.config.tooltips.controls) {\n const { classNames, selectors } = this.config;\n const selector = `${selectors.controls.wrapper} ${selectors.labels} .${classNames.hidden}`;\n const labels = getElements.call(this, selector);\n\n Array.from(labels).forEach(label => {\n toggleClass(label, this.config.classNames.hidden, false);\n toggleClass(label, this.config.classNames.tooltip, true);\n });\n }\n },\n};\n\nexport default controls;\n","// ==========================================================================\n// URL utils\n// ==========================================================================\n\nimport is from './is';\n\n/**\n * Parse a string to a URL object\n * @param {string} input - the URL to be parsed\n * @param {boolean} safe - failsafe parsing\n */\nexport function parseUrl(input, safe = true) {\n let url = input;\n\n if (safe) {\n const parser = document.createElement('a');\n parser.href = url;\n url = parser.href;\n }\n\n try {\n return new URL(url);\n } catch (e) {\n return null;\n }\n}\n\n// Convert object to URLSearchParams\nexport function buildUrlParams(input) {\n const params = new URLSearchParams();\n\n if (is.object(input)) {\n Object.entries(input).forEach(([key, value]) => {\n params.set(key, value);\n });\n }\n\n return params;\n}\n","// ==========================================================================\n// Plyr Captions\n// TODO: Create as class\n// ==========================================================================\n\nimport controls from './controls';\nimport i18n from './i18n';\nimport support from './support';\nimport { dedupe } from './utils/arrays';\nimport browser from './utils/browser';\nimport {\n createElement,\n emptyElement,\n getAttributesFromSelector,\n insertAfter,\n removeElement,\n toggleClass,\n} from './utils/elements';\nimport { on, triggerEvent } from './utils/events';\nimport fetch from './utils/fetch';\nimport is from './utils/is';\nimport { getHTML } from './utils/strings';\nimport { parseUrl } from './utils/urls';\n\nconst captions = {\n // Setup captions\n setup() {\n // Requires UI support\n if (!this.supported.ui) {\n return;\n }\n\n // Only Vimeo and HTML5 video supported at this point\n if (!this.isVideo || this.isYouTube || (this.isHTML5 && !support.textTracks)) {\n // Clear menu and hide\n if (\n is.array(this.config.controls) &&\n this.config.controls.includes('settings') &&\n this.config.settings.includes('captions')\n ) {\n controls.setCaptionsMenu.call(this);\n }\n\n return;\n }\n\n // Inject the container\n if (!is.element(this.elements.captions)) {\n this.elements.captions = createElement('div', getAttributesFromSelector(this.config.selectors.captions));\n\n insertAfter(this.elements.captions, this.elements.wrapper);\n }\n\n // Fix IE captions if CORS is used\n // Fetch captions and inject as blobs instead (data URIs not supported!)\n if (browser.isIE && window.URL) {\n const elements = this.media.querySelectorAll('track');\n\n Array.from(elements).forEach(track => {\n const src = track.getAttribute('src');\n const url = parseUrl(src);\n\n if (\n url !== null &&\n url.hostname !== window.location.href.hostname &&\n ['http:', 'https:'].includes(url.protocol)\n ) {\n fetch(src, 'blob')\n .then(blob => {\n track.setAttribute('src', window.URL.createObjectURL(blob));\n })\n .catch(() => {\n removeElement(track);\n });\n }\n });\n }\n\n // Get and set initial data\n // The \"preferred\" options are not realized unless / until the wanted language has a match\n // * languages: Array of user's browser languages.\n // * language: The language preferred by user settings or config\n // * active: The state preferred by user settings or config\n // * toggled: The real captions state\n\n const languages = dedupe(\n Array.from(navigator.languages || navigator.userLanguage).map(language => language.split('-')[0]),\n );\n\n let language = (this.storage.get('language') || this.config.captions.language || 'auto').toLowerCase();\n\n // Use first browser language when language is 'auto'\n if (language === 'auto') {\n [language] = languages;\n }\n\n let active = this.storage.get('captions');\n if (!is.boolean(active)) {\n ({ active } = this.config.captions);\n }\n\n Object.assign(this.captions, {\n toggled: false,\n active,\n language,\n languages,\n });\n\n // Watch changes to textTracks and update captions menu\n if (this.isHTML5) {\n const trackEvents = this.config.captions.update ? 'addtrack removetrack' : 'removetrack';\n on.call(this, this.media.textTracks, trackEvents, captions.update.bind(this));\n }\n\n // Update available languages in list next tick (the event must not be triggered before the listeners)\n setTimeout(captions.update.bind(this), 0);\n },\n\n // Update available language options in settings based on tracks\n update() {\n const tracks = captions.getTracks.call(this, true);\n // Get the wanted language\n const { active, language, meta, currentTrackNode } = this.captions;\n const languageExists = Boolean(tracks.find(track => track.language === language));\n\n // Handle tracks (add event listener and \"pseudo\"-default)\n if (this.isHTML5 && this.isVideo) {\n tracks.filter(track => !meta.get(track)).forEach(track => {\n this.debug.log('Track added', track);\n // Attempt to store if the original dom element was \"default\"\n meta.set(track, {\n default: track.mode === 'showing',\n });\n\n // Turn off native caption rendering to avoid double captions\n track.mode = 'hidden';\n\n // Add event listener for cue changes\n on.call(this, track, 'cuechange', () => captions.updateCues.call(this));\n });\n }\n\n // Update language first time it matches, or if the previous matching track was removed\n if ((languageExists && this.language !== language) || !tracks.includes(currentTrackNode)) {\n captions.setLanguage.call(this, language);\n captions.toggle.call(this, active && languageExists);\n }\n\n // Enable or disable captions based on track length\n toggleClass(this.elements.container, this.config.classNames.captions.enabled, !is.empty(tracks));\n\n // Update available languages in list\n if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) {\n controls.setCaptionsMenu.call(this);\n }\n },\n\n // Toggle captions display\n // Used internally for the toggleCaptions method, with the passive option forced to false\n toggle(input, passive = true) {\n // If there's no full support\n if (!this.supported.ui) {\n return;\n }\n\n const { toggled } = this.captions; // Current state\n const activeClass = this.config.classNames.captions.active;\n\n // Get the next state\n // If the method is called without parameter, toggle based on current value\n const active = is.nullOrUndefined(input) ? !toggled : input;\n\n // Update state and trigger event\n if (active !== toggled) {\n // When passive, don't override user preferences\n if (!passive) {\n this.captions.active = active;\n this.storage.set({ captions: active });\n }\n\n // Force language if the call isn't passive and there is no matching language to toggle to\n if (!this.language && active && !passive) {\n const tracks = captions.getTracks.call(this);\n const track = captions.findTrack.call(this, [this.captions.language, ...this.captions.languages], true);\n\n // Override user preferences to avoid switching languages if a matching track is added\n this.captions.language = track.language;\n\n // Set caption, but don't store in localStorage as user preference\n captions.set.call(this, tracks.indexOf(track));\n return;\n }\n\n // Toggle state\n this.elements.buttons.captions.pressed = active;\n\n // Add class hook\n toggleClass(this.elements.container, activeClass, active);\n\n this.captions.toggled = active;\n\n // Update settings menu\n controls.updateSetting.call(this, 'captions');\n\n // Trigger event (not used internally)\n triggerEvent.call(this, this.media, active ? 'captionsenabled' : 'captionsdisabled');\n }\n },\n\n // Set captions by track index\n // Used internally for the currentTrack setter with the passive option forced to false\n set(index, passive = true) {\n const tracks = captions.getTracks.call(this);\n\n // Disable captions if setting to -1\n if (index === -1) {\n captions.toggle.call(this, false, passive);\n return;\n }\n\n if (!is.number(index)) {\n this.debug.warn('Invalid caption argument', index);\n return;\n }\n\n if (!(index in tracks)) {\n this.debug.warn('Track not found', index);\n return;\n }\n\n if (this.captions.currentTrack !== index) {\n this.captions.currentTrack = index;\n const track = tracks[index];\n const { language } = track || {};\n\n // Store reference to node for invalidation on remove\n this.captions.currentTrackNode = track;\n\n // Update settings menu\n controls.updateSetting.call(this, 'captions');\n\n // When passive, don't override user preferences\n if (!passive) {\n this.captions.language = language;\n this.storage.set({ language });\n }\n\n // Handle Vimeo captions\n if (this.isVimeo) {\n this.embed.enableTextTrack(language);\n }\n\n // Trigger event\n triggerEvent.call(this, this.media, 'languagechange');\n }\n\n // Show captions\n captions.toggle.call(this, true, passive);\n\n if (this.isHTML5 && this.isVideo) {\n // If we change the active track while a cue is already displayed we need to update it\n captions.updateCues.call(this);\n }\n },\n\n // Set captions by language\n // Used internally for the language setter with the passive option forced to false\n setLanguage(input, passive = true) {\n if (!is.string(input)) {\n this.debug.warn('Invalid language argument', input);\n return;\n }\n // Normalize\n const language = input.toLowerCase();\n this.captions.language = language;\n\n // Set currentTrack\n const tracks = captions.getTracks.call(this);\n const track = captions.findTrack.call(this, [language]);\n captions.set.call(this, tracks.indexOf(track), passive);\n },\n\n // Get current valid caption tracks\n // If update is false it will also ignore tracks without metadata\n // This is used to \"freeze\" the language options when captions.update is false\n getTracks(update = false) {\n // Handle media or textTracks missing or null\n const tracks = Array.from((this.media || {}).textTracks || []);\n // For HTML5, use cache instead of current tracks when it exists (if captions.update is false)\n // Filter out removed tracks and tracks that aren't captions/subtitles (for example metadata)\n return tracks\n .filter(track => !this.isHTML5 || update || this.captions.meta.has(track))\n .filter(track => ['captions', 'subtitles'].includes(track.kind));\n },\n\n // Match tracks based on languages and get the first\n findTrack(languages, force = false) {\n const tracks = captions.getTracks.call(this);\n const sortIsDefault = track => Number((this.captions.meta.get(track) || {}).default);\n const sorted = Array.from(tracks).sort((a, b) => sortIsDefault(b) - sortIsDefault(a));\n let track;\n languages.every(language => {\n track = sorted.find(track => track.language === language);\n return !track; // Break iteration if there is a match\n });\n // If no match is found but is required, get first\n return track || (force ? sorted[0] : undefined);\n },\n\n // Get the current track\n getCurrentTrack() {\n return captions.getTracks.call(this)[this.currentTrack];\n },\n\n // Get UI label for track\n getLabel(track) {\n let currentTrack = track;\n\n if (!is.track(currentTrack) && support.textTracks && this.captions.toggled) {\n currentTrack = captions.getCurrentTrack.call(this);\n }\n\n if (is.track(currentTrack)) {\n if (!is.empty(currentTrack.label)) {\n return currentTrack.label;\n }\n\n if (!is.empty(currentTrack.language)) {\n return track.language.toUpperCase();\n }\n\n return i18n.get('enabled', this.config);\n }\n\n return i18n.get('disabled', this.config);\n },\n\n // Update captions using current track's active cues\n // Also optional array argument in case there isn't any track (ex: vimeo)\n updateCues(input) {\n // Requires UI\n if (!this.supported.ui) {\n return;\n }\n\n if (!is.element(this.elements.captions)) {\n this.debug.warn('No captions element to render to');\n return;\n }\n\n // Only accept array or empty input\n if (!is.nullOrUndefined(input) && !Array.isArray(input)) {\n this.debug.warn('updateCues: Invalid input', input);\n return;\n }\n\n let cues = input;\n\n // Get cues from track\n if (!cues) {\n const track = captions.getCurrentTrack.call(this);\n cues = Array.from((track || {}).activeCues || [])\n .map(cue => cue.getCueAsHTML())\n .map(getHTML);\n }\n\n // Set new caption text\n const content = cues.map(cueText => cueText.trim()).join('\\n');\n const changed = content !== this.elements.captions.innerHTML;\n\n if (changed) {\n // Empty the container and create a new child element\n emptyElement(this.elements.captions);\n const caption = createElement('span', getAttributesFromSelector(this.config.selectors.caption));\n caption.innerHTML = content;\n this.elements.captions.appendChild(caption);\n\n // Trigger event\n triggerEvent.call(this, this.media, 'cuechange');\n }\n },\n};\n\nexport default captions;\n","// ==========================================================================\n// Plyr default config\n// ==========================================================================\n\nconst defaults = {\n // Disable\n enabled: true,\n\n // Custom media title\n title: '',\n\n // Logging to console\n debug: false,\n\n // Auto play (if supported)\n autoplay: false,\n\n // Only allow one media playing at once (vimeo only)\n autopause: true,\n\n // Allow inline playback on iOS (this effects YouTube/Vimeo - HTML5 requires the attribute present)\n // TODO: Remove iosNative fullscreen option in favour of this (logic needs work)\n playsinline: true,\n\n // Default time to skip when rewind/fast forward\n seekTime: 10,\n\n // Default volume\n volume: 1,\n muted: false,\n\n // Pass a custom duration\n duration: null,\n\n // Display the media duration on load in the current time position\n // If you have opted to display both duration and currentTime, this is ignored\n displayDuration: true,\n\n // Invert the current time to be a countdown\n invertTime: true,\n\n // Clicking the currentTime inverts it's value to show time left rather than elapsed\n toggleInvert: true,\n\n // Aspect ratio (for embeds)\n ratio: '16:9',\n\n // Click video container to play/pause\n clickToPlay: true,\n\n // Auto hide the controls\n hideControls: true,\n\n // Reset to start when playback ended\n resetOnEnd: false,\n\n // Disable the standard context menu\n disableContextMenu: true,\n\n // Sprite (for icons)\n loadSprite: true,\n iconPrefix: 'plyr',\n iconUrl: 'https://cdn.plyr.io/3.3.12/plyr.svg',\n\n // Blank video (used to prevent errors on source change)\n blankVideo: 'https://cdn.plyr.io/static/blank.mp4',\n\n // Quality default\n quality: {\n default: 576,\n options: [\n 4320,\n 2880,\n 2160,\n 1440,\n 1080,\n 720,\n 576,\n 480,\n 360,\n 240,\n 'default', // YouTube's \"auto\"\n ],\n },\n\n // Set loops\n loop: {\n active: false,\n // start: null,\n // end: null,\n },\n\n // Speed default and options to display\n speed: {\n selected: 1,\n options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],\n },\n\n // Keyboard shortcut settings\n keyboard: {\n focused: true,\n global: false,\n },\n\n // Display tooltips\n tooltips: {\n controls: false,\n seek: true,\n },\n\n // Captions settings\n captions: {\n active: false,\n language: 'auto',\n // Listen to new tracks added after Plyr is initialized.\n // This is needed for streaming captions, but may result in unselectable options\n update: false,\n },\n\n // Fullscreen settings\n fullscreen: {\n enabled: true, // Allow fullscreen?\n fallback: true, // Fallback for vintage browsers\n iosNative: false, // Use the native fullscreen in iOS (disables custom controls)\n },\n\n // Local storage\n storage: {\n enabled: true,\n key: 'plyr',\n },\n\n // Default controls\n controls: [\n 'play-large',\n // 'restart',\n // 'rewind',\n 'play',\n // 'fast-forward',\n 'progress',\n 'current-time',\n 'mute',\n 'volume',\n 'captions',\n 'settings',\n 'pip',\n 'airplay',\n 'fullscreen',\n ],\n settings: ['captions', 'quality', 'speed'],\n\n // Localisation\n i18n: {\n restart: 'Restart',\n rewind: 'Rewind {seektime}s',\n play: 'Play',\n pause: 'Pause',\n fastForward: 'Forward {seektime}s',\n seek: 'Seek',\n seekLabel: '{currentTime} of {duration}',\n played: 'Played',\n buffered: 'Buffered',\n currentTime: 'Current time',\n duration: 'Duration',\n volume: 'Volume',\n mute: 'Mute',\n unmute: 'Unmute',\n enableCaptions: 'Enable captions',\n disableCaptions: 'Disable captions',\n enterFullscreen: 'Enter fullscreen',\n exitFullscreen: 'Exit fullscreen',\n frameTitle: 'Player for {title}',\n captions: 'Captions',\n settings: 'Settings',\n menuBack: 'Go back to previous menu',\n speed: 'Speed',\n normal: 'Normal',\n quality: 'Quality',\n loop: 'Loop',\n start: 'Start',\n end: 'End',\n all: 'All',\n reset: 'Reset',\n disabled: 'Disabled',\n enabled: 'Enabled',\n advertisement: 'Ad',\n qualityBadge: {\n 2160: '4K',\n 1440: 'HD',\n 1080: 'HD',\n 720: 'HD',\n 576: 'SD',\n 480: 'SD',\n },\n },\n\n // URLs\n urls: {\n vimeo: {\n sdk: 'https://player.vimeo.com/api/player.js',\n iframe: 'https://player.vimeo.com/video/{0}?{1}',\n api: 'https://vimeo.com/api/v2/video/{0}.json',\n },\n youtube: {\n sdk: 'https://www.youtube.com/iframe_api',\n api:\n 'https://www.googleapis.com/youtube/v3/videos?id={0}&key={1}&fields=items(snippet(title))&part=snippet',\n },\n googleIMA: {\n sdk: 'https://imasdk.googleapis.com/js/sdkloader/ima3.js',\n },\n },\n\n // Custom control listeners\n listeners: {\n seek: null,\n play: null,\n pause: null,\n restart: null,\n rewind: null,\n fastForward: null,\n mute: null,\n volume: null,\n captions: null,\n fullscreen: null,\n pip: null,\n airplay: null,\n speed: null,\n quality: null,\n loop: null,\n language: null,\n },\n\n // Events to watch and bubble\n events: [\n // Events to watch on HTML5 media elements and bubble\n // https://developer.mozilla.org/en/docs/Web/Guide/Events/Media_events\n 'ended',\n 'progress',\n 'stalled',\n 'playing',\n 'waiting',\n 'canplay',\n 'canplaythrough',\n 'loadstart',\n 'loadeddata',\n 'loadedmetadata',\n 'timeupdate',\n 'volumechange',\n 'play',\n 'pause',\n 'error',\n 'seeking',\n 'seeked',\n 'emptied',\n 'ratechange',\n 'cuechange',\n\n // Custom events\n 'enterfullscreen',\n 'exitfullscreen',\n 'captionsenabled',\n 'captionsdisabled',\n 'languagechange',\n 'controlshidden',\n 'controlsshown',\n 'ready',\n\n // YouTube\n 'statechange',\n 'qualitychange',\n 'qualityrequested',\n\n // Ads\n 'adsloaded',\n 'adscontentpause',\n 'adscontentresume',\n 'adstarted',\n 'adsmidpoint',\n 'adscomplete',\n 'adsallcomplete',\n 'adsimpression',\n 'adsclick',\n ],\n\n // Selectors\n // Change these to match your template if using custom HTML\n selectors: {\n editable: 'input, textarea, select, [contenteditable]',\n container: '.plyr',\n controls: {\n container: null,\n wrapper: '.plyr__controls',\n },\n labels: '[data-plyr]',\n buttons: {\n play: '[data-plyr=\"play\"]',\n pause: '[data-plyr=\"pause\"]',\n restart: '[data-plyr=\"restart\"]',\n rewind: '[data-plyr=\"rewind\"]',\n fastForward: '[data-plyr=\"fast-forward\"]',\n mute: '[data-plyr=\"mute\"]',\n captions: '[data-plyr=\"captions\"]',\n fullscreen: '[data-plyr=\"fullscreen\"]',\n pip: '[data-plyr=\"pip\"]',\n airplay: '[data-plyr=\"airplay\"]',\n settings: '[data-plyr=\"settings\"]',\n loop: '[data-plyr=\"loop\"]',\n },\n inputs: {\n seek: '[data-plyr=\"seek\"]',\n volume: '[data-plyr=\"volume\"]',\n speed: '[data-plyr=\"speed\"]',\n language: '[data-plyr=\"language\"]',\n quality: '[data-plyr=\"quality\"]',\n },\n display: {\n currentTime: '.plyr__time--current',\n duration: '.plyr__time--duration',\n buffer: '.plyr__progress__buffer',\n loop: '.plyr__progress__loop', // Used later\n volume: '.plyr__volume--display',\n },\n progress: '.plyr__progress',\n captions: '.plyr__captions',\n caption: '.plyr__caption',\n menu: {\n quality: '.js-plyr__menu__list--quality',\n },\n },\n\n // Class hooks added to the player in different states\n classNames: {\n type: 'plyr--{0}',\n provider: 'plyr--{0}',\n video: 'plyr__video-wrapper',\n embed: 'plyr__video-embed',\n embedContainer: 'plyr__video-embed__container',\n poster: 'plyr__poster',\n posterEnabled: 'plyr__poster-enabled',\n ads: 'plyr__ads',\n control: 'plyr__control',\n controlPressed: 'plyr__control--pressed',\n playing: 'plyr--playing',\n paused: 'plyr--paused',\n stopped: 'plyr--stopped',\n loading: 'plyr--loading',\n hover: 'plyr--hover',\n tooltip: 'plyr__tooltip',\n cues: 'plyr__cues',\n hidden: 'plyr__sr-only',\n hideControls: 'plyr--hide-controls',\n isIos: 'plyr--is-ios',\n isTouch: 'plyr--is-touch',\n uiSupported: 'plyr--full-ui',\n noTransition: 'plyr--no-transition',\n display: {\n time: 'plyr__time',\n },\n menu: {\n value: 'plyr__menu__value',\n badge: 'plyr__badge',\n open: 'plyr--menu-open',\n },\n captions: {\n enabled: 'plyr--captions-enabled',\n active: 'plyr--captions-active',\n },\n fullscreen: {\n enabled: 'plyr--fullscreen-enabled',\n fallback: 'plyr--fullscreen-fallback',\n },\n pip: {\n supported: 'plyr--pip-supported',\n active: 'plyr--pip-active',\n },\n airplay: {\n supported: 'plyr--airplay-supported',\n active: 'plyr--airplay-active',\n },\n tabFocus: 'plyr__tab-focus',\n },\n\n // Embed attributes\n attributes: {\n embed: {\n provider: 'data-plyr-provider',\n id: 'data-plyr-embed-id',\n },\n },\n\n // API keys\n keys: {\n google: null,\n },\n\n // Advertisements plugin\n // Register for an account here: http://vi.ai/publisher-video-monetization/?aid=plyrio\n ads: {\n enabled: false,\n publisherId: '',\n },\n};\n\nexport default defaults;\n","// ==========================================================================\n// Plyr supported types and providers\n// ==========================================================================\n\nexport const providers = {\n html5: 'html5',\n youtube: 'youtube',\n vimeo: 'vimeo',\n};\n\nexport const types = {\n audio: 'audio',\n video: 'video',\n};\n\n/**\n * Get provider by URL\n * @param {string} url\n */\nexport function getProviderByUrl(url) {\n // YouTube\n if (/^(https?:\\/\\/)?(www\\.)?(youtube\\.com|youtu\\.?be)\\/.+$/.test(url)) {\n return providers.youtube;\n }\n\n // Vimeo\n if (/^https?:\\/\\/player.vimeo.com\\/video\\/\\d{0,9}(?=\\b|\\/)/.test(url)) {\n return providers.vimeo;\n }\n\n return null;\n}\n\nexport default { providers, types };\n","// ==========================================================================\n// Console wrapper\n// ==========================================================================\n\nconst noop = () => {};\n\nexport default class Console {\n constructor(enabled = false) {\n this.enabled = window.console && enabled;\n\n if (this.enabled) {\n this.log('Debugging enabled');\n }\n }\n\n get log() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.log, console) : noop;\n }\n get warn() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.warn, console) : noop;\n }\n get error() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.error, console) : noop;\n }\n}\n","// ==========================================================================\n// Fullscreen wrapper\n// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API#prefixing\n// ==========================================================================\n\nimport browser from './utils/browser';\nimport { hasClass, toggleClass, trapFocus } from './utils/elements';\nimport { on, triggerEvent } from './utils/events';\nimport is from './utils/is';\n\nfunction onChange() {\n if (!this.enabled) {\n return;\n }\n\n // Update toggle button\n const button = this.player.elements.buttons.fullscreen;\n if (is.element(button)) {\n button.pressed = this.active;\n }\n\n // Trigger an event\n triggerEvent.call(this.player, this.target, this.active ? 'enterfullscreen' : 'exitfullscreen', true);\n\n // Trap focus in container\n if (!browser.isIos) {\n trapFocus.call(this.player, this.target, this.active);\n }\n}\n\nfunction toggleFallback(toggle = false) {\n // Store or restore scroll position\n if (toggle) {\n this.scrollPosition = {\n x: window.scrollX || 0,\n y: window.scrollY || 0,\n };\n } else {\n window.scrollTo(this.scrollPosition.x, this.scrollPosition.y);\n }\n\n // Toggle scroll\n document.body.style.overflow = toggle ? 'hidden' : '';\n\n // Toggle class hook\n toggleClass(this.target, this.player.config.classNames.fullscreen.fallback, toggle);\n\n // Toggle button and fire events\n onChange.call(this);\n}\n\nclass Fullscreen {\n constructor(player) {\n // Keep reference to parent\n this.player = player;\n\n // Get prefix\n this.prefix = Fullscreen.prefix;\n this.property = Fullscreen.property;\n\n // Scroll position\n this.scrollPosition = { x: 0, y: 0 };\n\n // Register event listeners\n // Handle event (incase user presses escape etc)\n on.call(\n this.player,\n document,\n this.prefix === 'ms' ? 'MSFullscreenChange' : `${this.prefix}fullscreenchange`,\n () => {\n // TODO: Filter for target??\n onChange.call(this);\n },\n );\n\n // Fullscreen toggle on double click\n on.call(this.player, this.player.elements.container, 'dblclick', event => {\n // Ignore double click in controls\n if (is.element(this.player.elements.controls) && this.player.elements.controls.contains(event.target)) {\n return;\n }\n\n this.toggle();\n });\n\n // Update the UI\n this.update();\n }\n\n // Determine if native supported\n static get native() {\n return !!(\n document.fullscreenEnabled ||\n document.webkitFullscreenEnabled ||\n document.mozFullScreenEnabled ||\n document.msFullscreenEnabled\n );\n }\n\n // Get the prefix for handlers\n static get prefix() {\n // No prefix\n if (is.function(document.exitFullscreen)) {\n return '';\n }\n\n // Check for fullscreen support by vendor prefix\n let value = '';\n const prefixes = ['webkit', 'moz', 'ms'];\n\n prefixes.some(pre => {\n if (is.function(document[`${pre}ExitFullscreen`]) || is.function(document[`${pre}CancelFullScreen`])) {\n value = pre;\n return true;\n }\n\n return false;\n });\n\n return value;\n }\n\n static get property() {\n return this.prefix === 'moz' ? 'FullScreen' : 'Fullscreen';\n }\n\n // Determine if fullscreen is enabled\n get enabled() {\n return (\n (Fullscreen.native || this.player.config.fullscreen.fallback) &&\n this.player.config.fullscreen.enabled &&\n this.player.supported.ui &&\n this.player.isVideo\n );\n }\n\n // Get active state\n get active() {\n if (!this.enabled) {\n return false;\n }\n\n // Fallback using classname\n if (!Fullscreen.native) {\n return hasClass(this.target, this.player.config.classNames.fullscreen.fallback);\n }\n\n const element = !this.prefix ? document.fullscreenElement : document[`${this.prefix}${this.property}Element`];\n\n return element === this.target;\n }\n\n // Get target element\n get target() {\n return browser.isIos && this.player.config.fullscreen.iosNative\n ? this.player.media\n : this.player.elements.container;\n }\n\n // Update UI\n update() {\n if (this.enabled) {\n this.player.debug.log(`${Fullscreen.native ? 'Native' : 'Fallback'} fullscreen enabled`);\n } else {\n this.player.debug.log('Fullscreen not supported and fallback disabled');\n }\n\n // Add styling hook to show button\n toggleClass(this.player.elements.container, this.player.config.classNames.fullscreen.enabled, this.enabled);\n }\n\n // Make an element fullscreen\n enter() {\n if (!this.enabled) {\n return;\n }\n\n // iOS native fullscreen doesn't need the request step\n if (browser.isIos && this.player.config.fullscreen.iosNative) {\n if (this.player.playing) {\n this.target.webkitEnterFullscreen();\n }\n } else if (!Fullscreen.native) {\n toggleFallback.call(this, true);\n } else if (!this.prefix) {\n this.target.requestFullscreen();\n } else if (!is.empty(this.prefix)) {\n this.target[`${this.prefix}Request${this.property}`]();\n }\n }\n\n // Bail from fullscreen\n exit() {\n if (!this.enabled) {\n return;\n }\n\n // iOS native fullscreen\n if (browser.isIos && this.player.config.fullscreen.iosNative) {\n this.target.webkitExitFullscreen();\n this.player.play();\n } else if (!Fullscreen.native) {\n toggleFallback.call(this, false);\n } else if (!this.prefix) {\n (document.cancelFullScreen || document.exitFullscreen).call(document);\n } else if (!is.empty(this.prefix)) {\n const action = this.prefix === 'moz' ? 'Cancel' : 'Exit';\n document[`${this.prefix}${action}${this.property}`]();\n }\n }\n\n // Toggle state\n toggle() {\n if (!this.active) {\n this.enter();\n } else {\n this.exit();\n }\n }\n}\n\nexport default Fullscreen;\n","// ==========================================================================\n// Load image avoiding xhr/fetch CORS issues\n// Server status can't be obtained this way unfortunately, so this uses \"naturalWidth\" to determine if the image has loaded\n// By default it checks if it is at least 1px, but you can add a second argument to change this\n// ==========================================================================\n\nexport default function loadImage(src, minWidth = 1) {\n return new Promise((resolve, reject) => {\n const image = new Image();\n\n const handler = () => {\n delete image.onload;\n delete image.onerror;\n (image.naturalWidth >= minWidth ? resolve : reject)(image);\n };\n\n Object.assign(image, { onload: handler, onerror: handler, src });\n });\n}\n","// ==========================================================================\n// Plyr UI\n// ==========================================================================\n\nimport captions from './captions';\nimport controls from './controls';\nimport i18n from './i18n';\nimport support from './support';\nimport browser from './utils/browser';\nimport { getElement, toggleClass } from './utils/elements';\nimport { ready, triggerEvent } from './utils/events';\nimport is from './utils/is';\nimport loadImage from './utils/loadImage';\n\nconst ui = {\n addStyleHook() {\n toggleClass(this.elements.container, this.config.selectors.container.replace('.', ''), true);\n toggleClass(this.elements.container, this.config.classNames.uiSupported, this.supported.ui);\n },\n\n // Toggle native HTML5 media controls\n toggleNativeControls(toggle = false) {\n if (toggle && this.isHTML5) {\n this.media.setAttribute('controls', '');\n } else {\n this.media.removeAttribute('controls');\n }\n },\n\n // Setup the UI\n build() {\n // Re-attach media element listeners\n // TODO: Use event bubbling?\n this.listeners.media();\n\n // Don't setup interface if no support\n if (!this.supported.ui) {\n this.debug.warn(`Basic support only for ${this.provider} ${this.type}`);\n\n // Restore native controls\n ui.toggleNativeControls.call(this, true);\n\n // Bail\n return;\n }\n\n // Inject custom controls if not present\n if (!is.element(this.elements.controls)) {\n // Inject custom controls\n controls.inject.call(this);\n\n // Re-attach control listeners\n this.listeners.controls();\n }\n\n // Remove native controls\n ui.toggleNativeControls.call(this);\n\n // Setup captions for HTML5\n if (this.isHTML5) {\n captions.setup.call(this);\n }\n\n // Reset volume\n this.volume = null;\n\n // Reset mute state\n this.muted = null;\n\n // Reset speed\n this.speed = null;\n\n // Reset loop state\n this.loop = null;\n\n // Reset quality setting\n this.quality = null;\n\n // Reset volume display\n controls.updateVolume.call(this);\n\n // Reset time display\n controls.timeUpdate.call(this);\n\n // Update the UI\n ui.checkPlaying.call(this);\n\n // Check for picture-in-picture support\n toggleClass(\n this.elements.container,\n this.config.classNames.pip.supported,\n support.pip && this.isHTML5 && this.isVideo,\n );\n\n // Check for airplay support\n toggleClass(this.elements.container, this.config.classNames.airplay.supported, support.airplay && this.isHTML5);\n\n // Add iOS class\n toggleClass(this.elements.container, this.config.classNames.isIos, browser.isIos);\n\n // Add touch class\n toggleClass(this.elements.container, this.config.classNames.isTouch, this.touch);\n\n // Ready for API calls\n this.ready = true;\n\n // Ready event at end of execution stack\n setTimeout(() => {\n triggerEvent.call(this, this.media, 'ready');\n }, 0);\n\n // Set the title\n ui.setTitle.call(this);\n\n // Assure the poster image is set, if the property was added before the element was created\n if (this.poster) {\n ui.setPoster.call(this, this.poster, false).catch(() => {});\n }\n\n // Manually set the duration if user has overridden it.\n // The event listeners for it doesn't get called if preload is disabled (#701)\n if (this.config.duration) {\n controls.durationUpdate.call(this);\n }\n },\n\n // Setup aria attribute for play and iframe title\n setTitle() {\n // Find the current text\n let label = i18n.get('play', this.config);\n\n // If there's a media title set, use that for the label\n if (is.string(this.config.title) && !is.empty(this.config.title)) {\n label += `, ${this.config.title}`;\n }\n\n // If there's a play button, set label\n if (is.nodeList(this.elements.buttons.play)) {\n Array.from(this.elements.buttons.play).forEach(button => {\n button.setAttribute('aria-label', label);\n });\n }\n\n // Set iframe title\n // https://github.com/sampotts/plyr/issues/124\n if (this.isEmbed) {\n const iframe = getElement.call(this, 'iframe');\n\n if (!is.element(iframe)) {\n return;\n }\n\n // Default to media type\n const title = !is.empty(this.config.title) ? this.config.title : 'video';\n const format = i18n.get('frameTitle', this.config);\n\n iframe.setAttribute('title', format.replace('{title}', title));\n }\n },\n\n // Toggle poster\n togglePoster(enable) {\n toggleClass(this.elements.container, this.config.classNames.posterEnabled, enable);\n },\n\n // Set the poster image (async)\n // Used internally for the poster setter, with the passive option forced to false\n setPoster(poster, passive = true) {\n // Don't override if call is passive\n if (passive && this.poster) {\n return Promise.reject(new Error('Poster already set'));\n }\n\n // Set property synchronously to respect the call order\n this.media.setAttribute('poster', poster);\n\n // Wait until ui is ready\n return (\n ready\n .call(this)\n // Load image\n .then(() => loadImage(poster))\n .catch(err => {\n // Hide poster on error unless it's been set by another call\n if (poster === this.poster) {\n ui.togglePoster.call(this, false);\n }\n // Rethrow\n throw err;\n })\n .then(() => {\n // Prevent race conditions\n if (poster !== this.poster) {\n throw new Error('setPoster cancelled by later call to setPoster');\n }\n })\n .then(() => {\n Object.assign(this.elements.poster.style, {\n backgroundImage: `url('${poster}')`,\n // Reset backgroundSize as well (since it can be set to \"cover\" for padded thumbnails for youtube)\n backgroundSize: '',\n });\n ui.togglePoster.call(this, true);\n return poster;\n })\n );\n },\n\n // Check playing state\n checkPlaying(event) {\n // Class hooks\n toggleClass(this.elements.container, this.config.classNames.playing, this.playing);\n toggleClass(this.elements.container, this.config.classNames.paused, this.paused);\n toggleClass(this.elements.container, this.config.classNames.stopped, this.stopped);\n\n // Set state\n if (is.nodeList(this.elements.buttons.play)) {\n Array.from(this.elements.buttons.play).forEach(target => {\n target.pressed = this.playing;\n });\n }\n\n // Only update controls on non timeupdate events\n if (is.event(event) && event.type === 'timeupdate') {\n return;\n }\n\n // Toggle controls\n ui.toggleControls.call(this);\n },\n\n // Check if media is loading\n checkLoading(event) {\n this.loading = ['stalled', 'waiting'].includes(event.type);\n\n // Clear timer\n clearTimeout(this.timers.loading);\n\n // Timer to prevent flicker when seeking\n this.timers.loading = setTimeout(() => {\n // Update progress bar loading class state\n toggleClass(this.elements.container, this.config.classNames.loading, this.loading);\n\n // Update controls visibility\n ui.toggleControls.call(this);\n }, this.loading ? 250 : 0);\n },\n\n // Toggle controls based on state and `force` argument\n toggleControls(force) {\n const { controls } = this.elements;\n\n if (controls && this.config.hideControls) {\n // Show controls if force, loading, paused, or button interaction, otherwise hide\n this.toggleControls(Boolean(force || this.loading || this.paused || controls.pressed || controls.hover));\n }\n },\n};\n\nexport default ui;\n","// ==========================================================================\n// Plyr Event Listeners\n// ==========================================================================\n\nimport controls from './controls';\nimport ui from './ui';\nimport browser from './utils/browser';\nimport { getElement, getElements, getFocusElement, matches, toggleClass, toggleHidden } from './utils/elements';\nimport { on, once, toggleListener, triggerEvent } from './utils/events';\nimport is from './utils/is';\n\nclass Listeners {\n constructor(player) {\n this.player = player;\n this.lastKey = null;\n\n this.handleKey = this.handleKey.bind(this);\n this.toggleMenu = this.toggleMenu.bind(this);\n this.firstTouch = this.firstTouch.bind(this);\n }\n\n // Handle key presses\n handleKey(event) {\n const code = event.keyCode ? event.keyCode : event.which;\n const pressed = event.type === 'keydown';\n const repeat = pressed && code === this.lastKey;\n\n // Bail if a modifier key is set\n if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {\n return;\n }\n\n // If the event is bubbled from the media element\n // Firefox doesn't get the keycode for whatever reason\n if (!is.number(code)) {\n return;\n }\n\n // Seek by the number keys\n const seekByKey = () => {\n // Divide the max duration into 10th's and times by the number value\n this.player.currentTime = this.player.duration / 10 * (code - 48);\n };\n\n // Handle the key on keydown\n // Reset on keyup\n if (pressed) {\n // Which keycodes should we prevent default\n const preventDefault = [32, 37, 38, 39, 40, 48, 49, 50, 51, 52, 53, 54, 56, 57, 67, 70, 73, 75, 76, 77, 79];\n\n // Check focused element\n // and if the focused element is not editable (e.g. text input)\n // and any that accept key input http://webaim.org/techniques/keyboard/\n const focused = getFocusElement();\n if (\n is.element(focused) &&\n (focused !== this.player.elements.inputs.seek &&\n matches(focused, this.player.config.selectors.editable))\n ) {\n return;\n }\n\n // If the code is found prevent default (e.g. prevent scrolling for arrows)\n if (preventDefault.includes(code)) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n switch (code) {\n case 48:\n case 49:\n case 50:\n case 51:\n case 52:\n case 53:\n case 54:\n case 55:\n case 56:\n case 57:\n // 0-9\n if (!repeat) {\n seekByKey();\n }\n break;\n\n case 32:\n case 75:\n // Space and K key\n if (!repeat) {\n this.player.togglePlay();\n }\n break;\n\n case 38:\n // Arrow up\n this.player.increaseVolume(0.1);\n break;\n\n case 40:\n // Arrow down\n this.player.decreaseVolume(0.1);\n break;\n\n case 77:\n // M key\n if (!repeat) {\n this.player.muted = !this.player.muted;\n }\n break;\n\n case 39:\n // Arrow forward\n this.player.forward();\n break;\n\n case 37:\n // Arrow back\n this.player.rewind();\n break;\n\n case 70:\n // F key\n this.player.fullscreen.toggle();\n break;\n\n case 67:\n // C key\n if (!repeat) {\n this.player.toggleCaptions();\n }\n break;\n\n case 76:\n // L key\n this.player.loop = !this.player.loop;\n break;\n\n /* case 73:\n this.setLoop('start');\n break;\n\n case 76:\n this.setLoop();\n break;\n\n case 79:\n this.setLoop('end');\n break; */\n\n default:\n break;\n }\n\n // Escape is handle natively when in full screen\n // So we only need to worry about non native\n if (!this.player.fullscreen.enabled && this.player.fullscreen.active && code === 27) {\n this.player.fullscreen.toggle();\n }\n\n // Store last code for next cycle\n this.lastKey = code;\n } else {\n this.lastKey = null;\n }\n }\n\n // Toggle menu\n toggleMenu(event) {\n controls.toggleMenu.call(this.player, event);\n }\n\n // Device is touch enabled\n firstTouch() {\n this.player.touch = true;\n\n // Add touch class\n toggleClass(this.player.elements.container, this.player.config.classNames.isTouch, true);\n }\n\n // Global window & document listeners\n global(toggle = true) {\n // Keyboard shortcuts\n if (this.player.config.keyboard.global) {\n toggleListener.call(this.player, window, 'keydown keyup', this.handleKey, toggle, false);\n }\n\n // Click anywhere closes menu\n toggleListener.call(this.player, document.body, 'click', this.toggleMenu, toggle);\n\n // Detect touch by events\n once.call(this.player, document.body, 'touchstart', this.firstTouch);\n }\n\n // Container listeners\n container() {\n // Keyboard shortcuts\n if (!this.player.config.keyboard.global && this.player.config.keyboard.focused) {\n on.call(this.player, this.player.elements.container, 'keydown keyup', this.handleKey, false);\n }\n\n // Detect tab focus\n // Remove class on blur/focusout\n on.call(this.player, this.player.elements.container, 'focusout', event => {\n toggleClass(event.target, this.player.config.classNames.tabFocus, false);\n });\n // Add classname to tabbed elements\n on.call(this.player, this.player.elements.container, 'keydown', event => {\n if (event.keyCode !== 9) {\n return;\n }\n\n // Delay the adding of classname until the focus has changed\n // This event fires before the focusin event\n setTimeout(() => {\n toggleClass(getFocusElement(), this.player.config.classNames.tabFocus, true);\n }, 0);\n });\n\n // Toggle controls on mouse events and entering fullscreen\n on.call(\n this.player,\n this.player.elements.container,\n 'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen',\n event => {\n const { controls } = this.player.elements;\n\n // Remove button states for fullscreen\n if (event.type === 'enterfullscreen') {\n controls.pressed = false;\n controls.hover = false;\n }\n\n // Show, then hide after a timeout unless another control event occurs\n const show = ['touchstart', 'touchmove', 'mousemove'].includes(event.type);\n\n let delay = 0;\n\n if (show) {\n ui.toggleControls.call(this.player, true);\n // Use longer timeout for touch devices\n delay = this.player.touch ? 3000 : 2000;\n }\n\n // Clear timer\n clearTimeout(this.player.timers.controls);\n // Timer to prevent flicker when seeking\n this.player.timers.controls = setTimeout(() => ui.toggleControls.call(this.player, false), delay);\n },\n );\n }\n\n // Listen for media events\n media() {\n // Time change on media\n on.call(this.player, this.player.media, 'timeupdate seeking seeked', event =>\n controls.timeUpdate.call(this.player, event),\n );\n\n // Display duration\n on.call(this.player, this.player.media, 'durationchange loadeddata loadedmetadata', event =>\n controls.durationUpdate.call(this.player, event),\n );\n\n // Check for audio tracks on load\n // We can't use `loadedmetadata` as it doesn't seem to have audio tracks at that point\n on.call(this.player, this.player.media, 'canplay', () => {\n toggleHidden(this.player.elements.volume, !this.player.hasAudio);\n toggleHidden(this.player.elements.buttons.mute, !this.player.hasAudio);\n });\n\n // Handle the media finishing\n on.call(this.player, this.player.media, 'ended', () => {\n // Show poster on end\n if (this.player.isHTML5 && this.player.isVideo && this.player.config.resetOnEnd) {\n // Restart\n this.player.restart();\n }\n });\n\n // Check for buffer progress\n on.call(this.player, this.player.media, 'progress playing seeking seeked', event =>\n controls.updateProgress.call(this.player, event),\n );\n\n // Handle volume changes\n on.call(this.player, this.player.media, 'volumechange', event =>\n controls.updateVolume.call(this.player, event),\n );\n\n // Handle play/pause\n on.call(this.player, this.player.media, 'playing play pause ended emptied timeupdate', event =>\n ui.checkPlaying.call(this.player, event),\n );\n\n // Loading state\n on.call(this.player, this.player.media, 'waiting canplay seeked playing', event =>\n ui.checkLoading.call(this.player, event),\n );\n\n // If autoplay, then load advertisement if required\n // TODO: Show some sort of loading state while the ad manager loads else there's a delay before ad shows\n on.call(this.player, this.player.media, 'playing', () => {\n if (!this.player.ads) {\n return;\n }\n\n // If ads are enabled, wait for them first\n if (this.player.ads.enabled && !this.player.ads.initialized) {\n // Wait for manager response\n this.player.ads.managerPromise.then(() => this.player.ads.play()).catch(() => this.player.play());\n }\n });\n\n // Click video\n if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) {\n // Re-fetch the wrapper\n const wrapper = getElement.call(this.player, `.${this.player.config.classNames.video}`);\n\n // Bail if there's no wrapper (this should never happen)\n if (!is.element(wrapper)) {\n return;\n }\n\n // On click play, pause ore restart\n on.call(this.player, wrapper, 'click', () => {\n // Touch devices will just show controls (if we're hiding controls)\n if (this.player.config.hideControls && this.player.touch && !this.player.paused) {\n return;\n }\n\n if (this.player.paused) {\n this.player.play();\n } else if (this.player.ended) {\n this.player.restart();\n this.player.play();\n } else {\n this.player.pause();\n }\n });\n }\n\n // Disable right click\n if (this.player.supported.ui && this.player.config.disableContextMenu) {\n on.call(\n this.player,\n this.player.elements.wrapper,\n 'contextmenu',\n event => {\n event.preventDefault();\n },\n false,\n );\n }\n\n // Volume change\n on.call(this.player, this.player.media, 'volumechange', () => {\n // Save to storage\n this.player.storage.set({ volume: this.player.volume, muted: this.player.muted });\n });\n\n // Speed change\n on.call(this.player, this.player.media, 'ratechange', () => {\n // Update UI\n controls.updateSetting.call(this.player, 'speed');\n\n // Save to storage\n this.player.storage.set({ speed: this.player.speed });\n });\n\n // Quality request\n on.call(this.player, this.player.media, 'qualityrequested', event => {\n // Save to storage\n this.player.storage.set({ quality: event.detail.quality });\n });\n\n // Quality change\n on.call(this.player, this.player.media, 'qualitychange', event => {\n // Update UI\n controls.updateSetting.call(this.player, 'quality', null, event.detail.quality);\n });\n\n // Proxy events to container\n // Bubble up key events for Edge\n const proxyEvents = this.player.config.events.concat(['keyup', 'keydown']).join(' ');\n on.call(this.player, this.player.media, proxyEvents, event => {\n let { detail = {} } = event;\n\n // Get error details from media\n if (event.type === 'error') {\n detail = this.player.media.error;\n }\n\n triggerEvent.call(this.player, this.player.elements.container, event.type, true, detail);\n });\n }\n\n // Listen for control events\n controls() {\n // IE doesn't support input event, so we fallback to change\n const inputEvent = browser.isIE ? 'change' : 'input';\n\n // Run default and custom handlers\n const proxy = (event, defaultHandler, customHandlerKey) => {\n const customHandler = this.player.config.listeners[customHandlerKey];\n const hasCustomHandler = is.function(customHandler);\n let returned = true;\n\n // Execute custom handler\n if (hasCustomHandler) {\n returned = customHandler.call(this.player, event);\n }\n\n // Only call default handler if not prevented in custom handler\n if (returned && is.function(defaultHandler)) {\n defaultHandler.call(this.player, event);\n }\n };\n\n // Trigger custom and default handlers\n const bind = (element, type, defaultHandler, customHandlerKey, passive = true) => {\n const customHandler = this.player.config.listeners[customHandlerKey];\n const hasCustomHandler = is.function(customHandler);\n\n on.call(\n this.player,\n element,\n type,\n event => proxy(event, defaultHandler, customHandlerKey),\n passive && !hasCustomHandler,\n );\n };\n\n // Play/pause toggle\n Array.from(this.player.elements.buttons.play).forEach(button => {\n bind(button, 'click', this.player.togglePlay, 'play');\n });\n\n // Pause\n bind(this.player.elements.buttons.restart, 'click', this.player.restart, 'restart');\n\n // Rewind\n bind(this.player.elements.buttons.rewind, 'click', this.player.rewind, 'rewind');\n\n // Rewind\n bind(this.player.elements.buttons.fastForward, 'click', this.player.forward, 'fastForward');\n\n // Mute toggle\n bind(\n this.player.elements.buttons.mute,\n 'click',\n () => {\n this.player.muted = !this.player.muted;\n },\n 'mute',\n );\n\n // Captions toggle\n bind(this.player.elements.buttons.captions, 'click', () => this.player.toggleCaptions());\n\n // Fullscreen toggle\n bind(\n this.player.elements.buttons.fullscreen,\n 'click',\n () => {\n this.player.fullscreen.toggle();\n },\n 'fullscreen',\n );\n\n // Picture-in-Picture\n bind(\n this.player.elements.buttons.pip,\n 'click',\n () => {\n this.player.pip = 'toggle';\n },\n 'pip',\n );\n\n // Airplay\n bind(this.player.elements.buttons.airplay, 'click', this.player.airplay, 'airplay');\n\n // Settings menu\n bind(this.player.elements.buttons.settings, 'click', event => {\n controls.toggleMenu.call(this.player, event);\n });\n\n // Settings menu\n bind(this.player.elements.settings.popup, 'click', event => {\n event.stopPropagation();\n\n // Go back to home tab on click\n const showHomeTab = () => {\n controls.showMenuPanel.call(this.player, 'home');\n };\n\n // Settings menu items - use event delegation as items are added/removed\n if (matches(event.target, this.player.config.selectors.inputs.language)) {\n proxy(\n event,\n () => {\n this.player.currentTrack = Number(event.target.value);\n showHomeTab();\n },\n 'language',\n );\n } else if (matches(event.target, this.player.config.selectors.inputs.quality)) {\n proxy(\n event,\n () => {\n this.player.quality = event.target.value;\n showHomeTab();\n },\n 'quality',\n );\n } else if (matches(event.target, this.player.config.selectors.inputs.speed)) {\n proxy(\n event,\n () => {\n this.player.speed = parseFloat(event.target.value);\n showHomeTab();\n },\n 'speed',\n );\n }\n });\n\n // Set range input alternative \"value\", which matches the tooltip time (#954)\n bind(this.player.elements.inputs.seek, 'mousedown mousemove', event => {\n const clientRect = this.player.elements.progress.getBoundingClientRect();\n const percent = 100 / clientRect.width * (event.pageX - clientRect.left);\n event.currentTarget.setAttribute('seek-value', percent);\n });\n\n // Pause while seeking\n bind(this.player.elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', event => {\n const seek = event.currentTarget;\n\n const code = event.keyCode ? event.keyCode : event.which;\n const eventType = event.type;\n\n if ((eventType === 'keydown' || eventType === 'keyup') && (code !== 39 && code !== 37)) {\n return;\n }\n // Was playing before?\n const play = seek.hasAttribute('play-on-seeked');\n\n // Done seeking\n const done = ['mouseup', 'touchend', 'keyup'].includes(event.type);\n\n // If we're done seeking and it was playing, resume playback\n if (play && done) {\n seek.removeAttribute('play-on-seeked');\n this.player.play();\n } else if (!done && this.player.playing) {\n seek.setAttribute('play-on-seeked', '');\n this.player.pause();\n }\n });\n\n // Seek\n bind(\n this.player.elements.inputs.seek,\n inputEvent,\n event => {\n const seek = event.currentTarget;\n\n // If it exists, use seek-value instead of \"value\" for consistency with tooltip time (#954)\n let seekTo = seek.getAttribute('seek-value');\n\n if (is.empty(seekTo)) {\n seekTo = seek.value;\n }\n\n seek.removeAttribute('seek-value');\n\n this.player.currentTime = seekTo / seek.max * this.player.duration;\n },\n 'seek',\n );\n\n // Current time invert\n // Only if one time element is used for both currentTime and duration\n if (this.player.config.toggleInvert && !is.element(this.player.elements.display.duration)) {\n bind(this.player.elements.display.currentTime, 'click', () => {\n // Do nothing if we're at the start\n if (this.player.currentTime === 0) {\n return;\n }\n\n this.player.config.invertTime = !this.player.config.invertTime;\n\n controls.timeUpdate.call(this.player);\n });\n }\n\n // Volume\n bind(\n this.player.elements.inputs.volume,\n inputEvent,\n event => {\n this.player.volume = event.target.value;\n },\n 'volume',\n );\n\n // Polyfill for lower fill in <input type=\"range\"> for webkit\n if (browser.isWebkit) {\n Array.from(getElements.call(this.player, 'input[type=\"range\"]')).forEach(element => {\n bind(element, 'input', event => controls.updateRangeFill.call(this.player, event.target));\n });\n }\n\n // Seek tooltip\n bind(this.player.elements.progress, 'mouseenter mouseleave mousemove', event =>\n controls.updateSeekTooltip.call(this.player, event),\n );\n\n // Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)\n bind(this.player.elements.controls, 'mouseenter mouseleave', event => {\n this.player.elements.controls.hover = !this.player.touch && event.type === 'mouseenter';\n });\n\n // Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)\n bind(this.player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {\n this.player.elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);\n });\n\n // Focus in/out on controls\n bind(this.player.elements.controls, 'focusin focusout', event => {\n const { config, elements, timers } = this.player;\n\n // Skip transition to prevent focus from scrolling the parent element\n toggleClass(elements.controls, config.classNames.noTransition, event.type === 'focusin');\n\n // Toggle\n ui.toggleControls.call(this.player, event.type === 'focusin');\n\n // If focusin, hide again after delay\n if (event.type === 'focusin') {\n // Restore transition\n setTimeout(() => {\n toggleClass(elements.controls, config.classNames.noTransition, false);\n }, 0);\n\n // Delay a little more for keyboard users\n const delay = this.touch ? 3000 : 4000;\n\n // Clear timer\n clearTimeout(timers.controls);\n // Hide\n timers.controls = setTimeout(() => ui.toggleControls.call(this.player, false), delay);\n }\n });\n\n // Mouse wheel for volume\n bind(\n this.player.elements.inputs.volume,\n 'wheel',\n event => {\n // Detect \"natural\" scroll - suppored on OS X Safari only\n // Other browsers on OS X will be inverted until support improves\n const inverted = event.webkitDirectionInvertedFromDevice;\n const step = 1 / 50;\n let direction = 0;\n\n // Scroll down (or up on natural) to decrease\n if (event.deltaY < 0 || event.deltaX > 0) {\n if (inverted) {\n this.player.decreaseVolume(step);\n direction = -1;\n } else {\n this.player.increaseVolume(step);\n direction = 1;\n }\n }\n\n // Scroll up (or down on natural) to increase\n if (event.deltaY > 0 || event.deltaX < 0) {\n if (inverted) {\n this.player.increaseVolume(step);\n direction = 1;\n } else {\n this.player.decreaseVolume(step);\n direction = -1;\n }\n }\n\n // Don't break page scrolling at max and min\n if (\n (direction === 1 && this.player.media.volume < 1) ||\n (direction === -1 && this.player.media.volume > 0)\n ) {\n event.preventDefault();\n }\n },\n 'volume',\n false,\n );\n }\n}\n\nexport default Listeners;\n","(function(root, factory) {\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.loadjs = factory();\n }\n}(this, function() {\n/**\n * Global dependencies.\n * @global {Object} document - DOM\n */\n\nvar devnull = function() {},\n bundleIdCache = {},\n bundleResultCache = {},\n bundleCallbackQueue = {};\n\n\n/**\n * Subscribe to bundle load event.\n * @param {string[]} bundleIds - Bundle ids\n * @param {Function} callbackFn - The callback function\n */\nfunction subscribe(bundleIds, callbackFn) {\n // listify\n bundleIds = bundleIds.push ? bundleIds : [bundleIds];\n\n var depsNotFound = [],\n i = bundleIds.length,\n numWaiting = i,\n fn,\n bundleId,\n r,\n q;\n\n // define callback function\n fn = function (bundleId, pathsNotFound) {\n if (pathsNotFound.length) depsNotFound.push(bundleId);\n\n numWaiting--;\n if (!numWaiting) callbackFn(depsNotFound);\n };\n\n // register callback\n while (i--) {\n bundleId = bundleIds[i];\n\n // execute callback if in result cache\n r = bundleResultCache[bundleId];\n if (r) {\n fn(bundleId, r);\n continue;\n }\n\n // add to callback queue\n q = bundleCallbackQueue[bundleId] = bundleCallbackQueue[bundleId] || [];\n q.push(fn);\n }\n}\n\n\n/**\n * Publish bundle load event.\n * @param {string} bundleId - Bundle id\n * @param {string[]} pathsNotFound - List of files not found\n */\nfunction publish(bundleId, pathsNotFound) {\n // exit if id isn't defined\n if (!bundleId) return;\n\n var q = bundleCallbackQueue[bundleId];\n\n // cache result\n bundleResultCache[bundleId] = pathsNotFound;\n\n // exit if queue is empty\n if (!q) return;\n\n // empty callback queue\n while (q.length) {\n q[0](bundleId, pathsNotFound);\n q.splice(0, 1);\n }\n}\n\n\n/**\n * Execute callbacks.\n * @param {Object or Function} args - The callback args\n * @param {string[]} depsNotFound - List of dependencies not found\n */\nfunction executeCallbacks(args, depsNotFound) {\n // accept function as argument\n if (args.call) args = {success: args};\n\n // success and error callbacks\n if (depsNotFound.length) (args.error || devnull)(depsNotFound);\n else (args.success || devnull)(args);\n}\n\n\n/**\n * Load individual file.\n * @param {string} path - The file path\n * @param {Function} callbackFn - The callback function\n */\nfunction loadFile(path, callbackFn, args, numTries) {\n var doc = document,\n async = args.async,\n maxTries = (args.numRetries || 0) + 1,\n beforeCallbackFn = args.before || devnull,\n pathStripped = path.replace(/^(css|img)!/, ''),\n isCss,\n e;\n\n numTries = numTries || 0;\n\n if (/(^css!|\\.css$)/.test(path)) {\n isCss = true;\n\n // css\n e = doc.createElement('link');\n e.rel = 'stylesheet';\n e.href = pathStripped; //.replace(/^css!/, ''); // remove \"css!\" prefix\n } else if (/(^img!|\\.(png|gif|jpg|svg)$)/.test(path)) {\n // image\n e = doc.createElement('img');\n e.src = pathStripped; \n } else {\n // javascript\n e = doc.createElement('script');\n e.src = path;\n e.async = async === undefined ? true : async;\n }\n\n e.onload = e.onerror = e.onbeforeload = function (ev) {\n var result = ev.type[0];\n\n // Note: The following code isolates IE using `hideFocus` and treats empty\n // stylesheets as failures to get around lack of onerror support\n if (isCss && 'hideFocus' in e) {\n try {\n if (!e.sheet.cssText.length) result = 'e';\n } catch (x) {\n // sheets objects created from load errors don't allow access to\n // `cssText`\n result = 'e';\n }\n }\n\n // handle retries in case of load failure\n if (result == 'e') {\n // increment counter\n numTries += 1;\n\n // exit function and try again\n if (numTries < maxTries) {\n return loadFile(path, callbackFn, args, numTries);\n }\n }\n\n // execute callback\n callbackFn(path, result, ev.defaultPrevented);\n };\n\n // add to document (unless callback returns `false`)\n if (beforeCallbackFn(path, e) !== false) doc.head.appendChild(e);\n}\n\n\n/**\n * Load multiple files.\n * @param {string[]} paths - The file paths\n * @param {Function} callbackFn - The callback function\n */\nfunction loadFiles(paths, callbackFn, args) {\n // listify paths\n paths = paths.push ? paths : [paths];\n\n var numWaiting = paths.length,\n x = numWaiting,\n pathsNotFound = [],\n fn,\n i;\n\n // define callback function\n fn = function(path, result, defaultPrevented) {\n // handle error\n if (result == 'e') pathsNotFound.push(path);\n\n // handle beforeload event. If defaultPrevented then that means the load\n // will be blocked (ex. Ghostery/ABP on Safari)\n if (result == 'b') {\n if (defaultPrevented) pathsNotFound.push(path);\n else return;\n }\n\n numWaiting--;\n if (!numWaiting) callbackFn(pathsNotFound);\n };\n\n // load scripts\n for (i=0; i < x; i++) loadFile(paths[i], fn, args);\n}\n\n\n/**\n * Initiate script load and register bundle.\n * @param {(string|string[])} paths - The file paths\n * @param {(string|Function)} [arg1] - The bundleId or success callback\n * @param {Function} [arg2] - The success or error callback\n * @param {Function} [arg3] - The error callback\n */\nfunction loadjs(paths, arg1, arg2) {\n var bundleId,\n args;\n\n // bundleId (if string)\n if (arg1 && arg1.trim) bundleId = arg1;\n\n // args (default is {})\n args = (bundleId ? arg2 : arg1) || {};\n\n // throw error if bundle is already defined\n if (bundleId) {\n if (bundleId in bundleIdCache) {\n throw \"LoadJS\";\n } else {\n bundleIdCache[bundleId] = true;\n }\n }\n\n // load scripts\n loadFiles(paths, function (pathsNotFound) {\n // execute callbacks\n executeCallbacks(args, pathsNotFound);\n\n // publish bundle load event\n publish(bundleId, pathsNotFound);\n }, args);\n}\n\n\n/**\n * Execute callbacks when dependencies have been satisfied.\n * @param {(string|string[])} deps - List of bundle ids\n * @param {Object} args - success/error arguments\n */\nloadjs.ready = function ready(deps, args) {\n // subscribe to bundle load event\n subscribe(deps, function (depsNotFound) {\n // execute callbacks\n executeCallbacks(args, depsNotFound);\n });\n\n return loadjs;\n};\n\n\n/**\n * Manually satisfy bundle dependencies.\n * @param {string} bundleId - The bundle id\n */\nloadjs.done = function done(bundleId) {\n publish(bundleId, []);\n};\n\n\n/**\n * Reset loadjs dependencies statuses\n */\nloadjs.reset = function reset() {\n bundleIdCache = {};\n bundleResultCache = {};\n bundleCallbackQueue = {};\n};\n\n\n/**\n * Determine if bundle has already been defined\n * @param String} bundleId - The bundle id\n */\nloadjs.isDefined = function isDefined(bundleId) {\n return bundleId in bundleIdCache;\n};\n\n\n// export\nreturn loadjs;\n\n}));\n","// ==========================================================================\n// Load an external script\n// ==========================================================================\n\nimport loadjs from 'loadjs';\n\nexport default function loadScript(url) {\n return new Promise((resolve, reject) => {\n loadjs(url, {\n success: resolve,\n error: reject,\n });\n });\n}\n","// ==========================================================================\n// Vimeo plugin\n// ==========================================================================\n\nimport captions from './../captions';\nimport controls from './../controls';\nimport ui from './../ui';\nimport { createElement, replaceElement, toggleClass } from './../utils/elements';\nimport { triggerEvent } from './../utils/events';\nimport fetch from './../utils/fetch';\nimport is from './../utils/is';\nimport loadScript from './../utils/loadScript';\nimport { format, stripHTML } from './../utils/strings';\nimport { buildUrlParams } from './../utils/urls';\n\n// Parse Vimeo ID from URL\nfunction parseId(url) {\n if (is.empty(url)) {\n return null;\n }\n\n if (is.number(Number(url))) {\n return url;\n }\n\n const regex = /^.*(vimeo.com\\/|video\\/)(\\d+).*/;\n return url.match(regex) ? RegExp.$2 : url;\n}\n\n// Get aspect ratio for dimensions\nfunction getAspectRatio(width, height) {\n const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h));\n const ratio = getRatio(width, height);\n return `${width / ratio}:${height / ratio}`;\n}\n\n// Set playback state and trigger change (only on actual change)\nfunction assurePlaybackState(play) {\n if (play && !this.embed.hasPlayed) {\n this.embed.hasPlayed = true;\n }\n if (this.media.paused === play) {\n this.media.paused = !play;\n triggerEvent.call(this, this.media, play ? 'play' : 'pause');\n }\n}\n\nconst vimeo = {\n setup() {\n // Add embed class for responsive\n toggleClass(this.elements.wrapper, this.config.classNames.embed, true);\n\n // Set intial ratio\n vimeo.setAspectRatio.call(this);\n\n // Load the API if not already\n if (!is.object(window.Vimeo)) {\n loadScript(this.config.urls.vimeo.sdk)\n .then(() => {\n vimeo.ready.call(this);\n })\n .catch(error => {\n this.debug.warn('Vimeo API failed to load', error);\n });\n } else {\n vimeo.ready.call(this);\n }\n },\n\n // Set aspect ratio\n // For Vimeo we have an extra 300% height <div> to hide the standard controls and UI\n setAspectRatio(input) {\n const [x, y] = (is.string(input) ? input : this.config.ratio).split(':');\n const padding = 100 / x * y;\n this.elements.wrapper.style.paddingBottom = `${padding}%`;\n\n if (this.supported.ui) {\n const height = 240;\n const offset = (height - padding) / (height / 50);\n\n this.media.style.transform = `translateY(-${offset}%)`;\n }\n },\n\n // API Ready\n ready() {\n const player = this;\n\n // Get Vimeo params for the iframe\n const options = {\n loop: player.config.loop.active,\n autoplay: player.autoplay,\n // muted: player.muted,\n byline: false,\n portrait: false,\n title: false,\n speed: true,\n transparent: 0,\n gesture: 'media',\n playsinline: !this.config.fullscreen.iosNative,\n };\n const params = buildUrlParams(options);\n\n // Get the source URL or ID\n let source = player.media.getAttribute('src');\n\n // Get from <div> if needed\n if (is.empty(source)) {\n source = player.media.getAttribute(player.config.attributes.embed.id);\n }\n\n const id = parseId(source);\n\n // Build an iframe\n const iframe = createElement('iframe');\n const src = format(player.config.urls.vimeo.iframe, id, params);\n iframe.setAttribute('src', src);\n iframe.setAttribute('allowfullscreen', '');\n iframe.setAttribute('allowtransparency', '');\n iframe.setAttribute('allow', 'autoplay');\n\n // Get poster, if already set\n const { poster } = player;\n\n // Inject the package\n const wrapper = createElement('div', { poster, class: player.config.classNames.embedContainer });\n wrapper.appendChild(iframe);\n player.media = replaceElement(wrapper, player.media);\n\n // Get poster image\n fetch(format(player.config.urls.vimeo.api, id), 'json').then(response => {\n if (is.empty(response)) {\n return;\n }\n\n // Get the URL for thumbnail\n const url = new URL(response[0].thumbnail_large);\n\n // Get original image\n url.pathname = `${url.pathname.split('_')[0]}.jpg`;\n\n // Set and show poster\n ui.setPoster.call(player, url.href).catch(() => {});\n });\n\n // Setup instance\n // https://github.com/vimeo/player.js\n player.embed = new window.Vimeo.Player(iframe, {\n autopause: player.config.autopause,\n muted: player.muted,\n });\n\n player.media.paused = true;\n player.media.currentTime = 0;\n\n // Disable native text track rendering\n if (player.supported.ui) {\n player.embed.disableTextTrack();\n }\n\n // Create a faux HTML5 API using the Vimeo API\n player.media.play = () => {\n assurePlaybackState.call(player, true);\n return player.embed.play();\n };\n\n player.media.pause = () => {\n assurePlaybackState.call(player, false);\n return player.embed.pause();\n };\n\n player.media.stop = () => {\n player.pause();\n player.currentTime = 0;\n };\n\n // Seeking\n let { currentTime } = player.media;\n Object.defineProperty(player.media, 'currentTime', {\n get() {\n return currentTime;\n },\n set(time) {\n // Vimeo will automatically play on seek if the video hasn't been played before\n\n // Get current paused state and volume etc\n const { embed, media, paused, volume } = player;\n const restorePause = paused && !embed.hasPlayed;\n\n // Set seeking state and trigger event\n media.seeking = true;\n triggerEvent.call(player, media, 'seeking');\n\n // If paused, mute until seek is complete\n Promise.resolve(restorePause && embed.setVolume(0))\n // Seek\n .then(() => embed.setCurrentTime(time))\n // Restore paused\n .then(() => restorePause && embed.pause())\n // Restore volume\n .then(() => restorePause && embed.setVolume(volume))\n .catch(() => {\n // Do nothing\n });\n },\n });\n\n // Playback speed\n let speed = player.config.speed.selected;\n Object.defineProperty(player.media, 'playbackRate', {\n get() {\n return speed;\n },\n set(input) {\n player.embed\n .setPlaybackRate(input)\n .then(() => {\n speed = input;\n triggerEvent.call(player, player.media, 'ratechange');\n })\n .catch(error => {\n // Hide menu item (and menu if empty)\n if (error.name === 'Error') {\n controls.setSpeedMenu.call(player, []);\n }\n });\n },\n });\n\n // Volume\n let { volume } = player.config;\n Object.defineProperty(player.media, 'volume', {\n get() {\n return volume;\n },\n set(input) {\n player.embed.setVolume(input).then(() => {\n volume = input;\n triggerEvent.call(player, player.media, 'volumechange');\n });\n },\n });\n\n // Muted\n let { muted } = player.config;\n Object.defineProperty(player.media, 'muted', {\n get() {\n return muted;\n },\n set(input) {\n const toggle = is.boolean(input) ? input : false;\n\n player.embed.setVolume(toggle ? 0 : player.config.volume).then(() => {\n muted = toggle;\n triggerEvent.call(player, player.media, 'volumechange');\n });\n },\n });\n\n // Loop\n let { loop } = player.config;\n Object.defineProperty(player.media, 'loop', {\n get() {\n return loop;\n },\n set(input) {\n const toggle = is.boolean(input) ? input : player.config.loop.active;\n\n player.embed.setLoop(toggle).then(() => {\n loop = toggle;\n });\n },\n });\n\n // Source\n let currentSrc;\n player.embed\n .getVideoUrl()\n .then(value => {\n currentSrc = value;\n })\n .catch(error => {\n this.debug.warn(error);\n });\n\n Object.defineProperty(player.media, 'currentSrc', {\n get() {\n return currentSrc;\n },\n });\n\n // Ended\n Object.defineProperty(player.media, 'ended', {\n get() {\n return player.currentTime === player.duration;\n },\n });\n\n // Set aspect ratio based on video size\n Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then(dimensions => {\n const ratio = getAspectRatio(dimensions[0], dimensions[1]);\n vimeo.setAspectRatio.call(this, ratio);\n });\n\n // Set autopause\n player.embed.setAutopause(player.config.autopause).then(state => {\n player.config.autopause = state;\n });\n\n // Get title\n player.embed.getVideoTitle().then(title => {\n player.config.title = title;\n ui.setTitle.call(this);\n });\n\n // Get current time\n player.embed.getCurrentTime().then(value => {\n currentTime = value;\n triggerEvent.call(player, player.media, 'timeupdate');\n });\n\n // Get duration\n player.embed.getDuration().then(value => {\n player.media.duration = value;\n triggerEvent.call(player, player.media, 'durationchange');\n });\n\n // Get captions\n player.embed.getTextTracks().then(tracks => {\n player.media.textTracks = tracks;\n captions.setup.call(player);\n });\n\n player.embed.on('cuechange', ({ cues = [] }) => {\n const strippedCues = cues.map(cue => stripHTML(cue.text));\n captions.updateCues.call(player, strippedCues);\n });\n\n player.embed.on('loaded', () => {\n // Assure state and events are updated on autoplay\n player.embed.getPaused().then(paused => {\n assurePlaybackState.call(player, !paused);\n if (!paused) {\n triggerEvent.call(player, player.media, 'playing');\n }\n });\n\n if (is.element(player.embed.element) && player.supported.ui) {\n const frame = player.embed.element;\n\n // Fix keyboard focus issues\n // https://github.com/sampotts/plyr/issues/317\n frame.setAttribute('tabindex', -1);\n }\n });\n\n player.embed.on('play', () => {\n assurePlaybackState.call(player, true);\n triggerEvent.call(player, player.media, 'playing');\n });\n\n player.embed.on('pause', () => {\n assurePlaybackState.call(player, false);\n });\n\n player.embed.on('timeupdate', data => {\n player.media.seeking = false;\n currentTime = data.seconds;\n triggerEvent.call(player, player.media, 'timeupdate');\n });\n\n player.embed.on('progress', data => {\n player.media.buffered = data.percent;\n triggerEvent.call(player, player.media, 'progress');\n\n // Check all loaded\n if (parseInt(data.percent, 10) === 1) {\n triggerEvent.call(player, player.media, 'canplaythrough');\n }\n\n // Get duration as if we do it before load, it gives an incorrect value\n // https://github.com/sampotts/plyr/issues/891\n player.embed.getDuration().then(value => {\n if (value !== player.media.duration) {\n player.media.duration = value;\n triggerEvent.call(player, player.media, 'durationchange');\n }\n });\n });\n\n player.embed.on('seeked', () => {\n player.media.seeking = false;\n triggerEvent.call(player, player.media, 'seeked');\n });\n\n player.embed.on('ended', () => {\n player.media.paused = true;\n triggerEvent.call(player, player.media, 'ended');\n });\n\n player.embed.on('error', detail => {\n player.media.error = detail;\n triggerEvent.call(player, player.media, 'error');\n });\n\n // Rebuild UI\n setTimeout(() => ui.build.call(player), 0);\n },\n};\n\nexport default vimeo;\n","// ==========================================================================\n// YouTube plugin\n// ==========================================================================\n\nimport controls from './../controls';\nimport ui from './../ui';\nimport { dedupe } from './../utils/arrays';\nimport { createElement, replaceElement, toggleClass } from './../utils/elements';\nimport { triggerEvent } from './../utils/events';\nimport fetch from './../utils/fetch';\nimport is from './../utils/is';\nimport loadImage from './../utils/loadImage';\nimport loadScript from './../utils/loadScript';\nimport { format, generateId } from './../utils/strings';\n\n// Parse YouTube ID from URL\nfunction parseId(url) {\n if (is.empty(url)) {\n return null;\n }\n\n const regex = /^.*(youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=|&v=)([^#&?]*).*/;\n return url.match(regex) ? RegExp.$2 : url;\n}\n\n// Standardise YouTube quality unit\nfunction mapQualityUnit(input) {\n const qualities = {\n hd2160: 2160,\n hd1440: 1440,\n hd1080: 1080,\n hd720: 720,\n large: 480,\n medium: 360,\n small: 240,\n tiny: 144,\n };\n\n const entry = Object.entries(qualities).find(entry => entry.includes(input));\n\n if (entry) {\n // Get the match corresponding to the input\n return entry.find(value => value !== input);\n }\n\n return 'default';\n}\n\nfunction mapQualityUnits(levels) {\n if (is.empty(levels)) {\n return levels;\n }\n\n return dedupe(levels.map(level => mapQualityUnit(level)));\n}\n\n// Set playback state and trigger change (only on actual change)\nfunction assurePlaybackState(play) {\n if (play && !this.embed.hasPlayed) {\n this.embed.hasPlayed = true;\n }\n if (this.media.paused === play) {\n this.media.paused = !play;\n triggerEvent.call(this, this.media, play ? 'play' : 'pause');\n }\n}\n\nconst youtube = {\n setup() {\n // Add embed class for responsive\n toggleClass(this.elements.wrapper, this.config.classNames.embed, true);\n\n // Set aspect ratio\n youtube.setAspectRatio.call(this);\n\n // Setup API\n if (is.object(window.YT) && is.function(window.YT.Player)) {\n youtube.ready.call(this);\n } else {\n // Load the API\n loadScript(this.config.urls.youtube.sdk).catch(error => {\n this.debug.warn('YouTube API failed to load', error);\n });\n\n // Setup callback for the API\n // YouTube has it's own system of course...\n window.onYouTubeReadyCallbacks = window.onYouTubeReadyCallbacks || [];\n\n // Add to queue\n window.onYouTubeReadyCallbacks.push(() => {\n youtube.ready.call(this);\n });\n\n // Set callback to process queue\n window.onYouTubeIframeAPIReady = () => {\n window.onYouTubeReadyCallbacks.forEach(callback => {\n callback();\n });\n };\n }\n },\n\n // Get the media title\n getTitle(videoId) {\n // Try via undocumented API method first\n // This method disappears now and then though...\n // https://github.com/sampotts/plyr/issues/709\n if (is.function(this.embed.getVideoData)) {\n const { title } = this.embed.getVideoData();\n\n if (is.empty(title)) {\n this.config.title = title;\n ui.setTitle.call(this);\n return;\n }\n }\n\n // Or via Google API\n const key = this.config.keys.google;\n if (is.string(key) && !is.empty(key)) {\n const url = format(this.config.urls.youtube.api, videoId, key);\n\n fetch(url)\n .then(result => {\n if (is.object(result)) {\n this.config.title = result.items[0].snippet.title;\n ui.setTitle.call(this);\n }\n })\n .catch(() => {});\n }\n },\n\n // Set aspect ratio\n setAspectRatio() {\n const ratio = this.config.ratio.split(':');\n this.elements.wrapper.style.paddingBottom = `${100 / ratio[0] * ratio[1]}%`;\n },\n\n // API ready\n ready() {\n const player = this;\n\n // Ignore already setup (race condition)\n const currentId = player.media.getAttribute('id');\n if (!is.empty(currentId) && currentId.startsWith('youtube-')) {\n return;\n }\n\n // Get the source URL or ID\n let source = player.media.getAttribute('src');\n\n // Get from <div> if needed\n if (is.empty(source)) {\n source = player.media.getAttribute(this.config.attributes.embed.id);\n }\n\n // Replace the <iframe> with a <div> due to YouTube API issues\n const videoId = parseId(source);\n const id = generateId(player.provider);\n\n // Get poster, if already set\n const { poster } = player;\n\n // Replace media element\n const container = createElement('div', { id, poster });\n player.media = replaceElement(container, player.media);\n\n // Id to poster wrapper\n const posterSrc = format => `https://img.youtube.com/vi/${videoId}/${format}default.jpg`;\n\n // Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)\n loadImage(posterSrc('maxres'), 121) // Higest quality and unpadded\n .catch(() => loadImage(posterSrc('sd'), 121)) // 480p padded 4:3\n .catch(() => loadImage(posterSrc('hq'))) // 360p padded 4:3. Always exists\n .then(image => ui.setPoster.call(player, image.src))\n .then(posterSrc => {\n // If the image is padded, use background-size \"cover\" instead (like youtube does too with their posters)\n if (!posterSrc.includes('maxres')) {\n player.elements.poster.style.backgroundSize = 'cover';\n }\n })\n .catch(() => {});\n\n // Setup instance\n // https://developers.google.com/youtube/iframe_api_reference\n player.embed = new window.YT.Player(id, {\n videoId,\n playerVars: {\n autoplay: player.config.autoplay ? 1 : 0, // Autoplay\n controls: player.supported.ui ? 0 : 1, // Only show controls if not fully supported\n rel: 0, // No related vids\n showinfo: 0, // Hide info\n iv_load_policy: 3, // Hide annotations\n modestbranding: 1, // Hide logos as much as possible (they still show one in the corner when paused)\n disablekb: 1, // Disable keyboard as we handle it\n playsinline: 1, // Allow iOS inline playback\n\n // Tracking for stats\n // origin: window ? `${window.location.protocol}//${window.location.host}` : null,\n widget_referrer: window ? window.location.href : null,\n\n // Captions are flaky on YouTube\n cc_load_policy: player.captions.active ? 1 : 0,\n cc_lang_pref: player.config.captions.language,\n },\n events: {\n onError(event) {\n // YouTube may fire onError twice, so only handle it once\n if (!player.media.error) {\n const code = event.data;\n // Messages copied from https://developers.google.com/youtube/iframe_api_reference#onError\n const message =\n {\n 2: 'The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.',\n 5: 'The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.',\n 100: 'The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.',\n 101: 'The owner of the requested video does not allow it to be played in embedded players.',\n 150: 'The owner of the requested video does not allow it to be played in embedded players.',\n }[code] || 'An unknown error occured';\n\n player.media.error = { code, message };\n\n triggerEvent.call(player, player.media, 'error');\n }\n },\n onPlaybackQualityChange() {\n triggerEvent.call(player, player.media, 'qualitychange', false, {\n quality: player.media.quality,\n });\n },\n onPlaybackRateChange(event) {\n // Get the instance\n const instance = event.target;\n\n // Get current speed\n player.media.playbackRate = instance.getPlaybackRate();\n\n triggerEvent.call(player, player.media, 'ratechange');\n },\n onReady(event) {\n // Get the instance\n const instance = event.target;\n\n // Get the title\n youtube.getTitle.call(player, videoId);\n\n // Create a faux HTML5 API using the YouTube API\n player.media.play = () => {\n assurePlaybackState.call(player, true);\n instance.playVideo();\n };\n\n player.media.pause = () => {\n assurePlaybackState.call(player, false);\n instance.pauseVideo();\n };\n\n player.media.stop = () => {\n instance.stopVideo();\n };\n\n player.media.duration = instance.getDuration();\n player.media.paused = true;\n\n // Seeking\n player.media.currentTime = 0;\n Object.defineProperty(player.media, 'currentTime', {\n get() {\n return Number(instance.getCurrentTime());\n },\n set(time) {\n // If paused, mute audio preventively (YouTube starts playing on seek if the video hasn't been played yet).\n if (player.paused) {\n player.embed.mute();\n }\n\n // Set seeking state and trigger event\n player.media.seeking = true;\n triggerEvent.call(player, player.media, 'seeking');\n\n // Seek after events sent\n instance.seekTo(time);\n },\n });\n\n // Playback speed\n Object.defineProperty(player.media, 'playbackRate', {\n get() {\n return instance.getPlaybackRate();\n },\n set(input) {\n instance.setPlaybackRate(input);\n },\n });\n\n // Quality\n Object.defineProperty(player.media, 'quality', {\n get() {\n return mapQualityUnit(instance.getPlaybackQuality());\n },\n set(input) {\n instance.setPlaybackQuality(mapQualityUnit(input));\n },\n });\n\n // Volume\n let { volume } = player.config;\n Object.defineProperty(player.media, 'volume', {\n get() {\n return volume;\n },\n set(input) {\n volume = input;\n instance.setVolume(volume * 100);\n triggerEvent.call(player, player.media, 'volumechange');\n },\n });\n\n // Muted\n let { muted } = player.config;\n Object.defineProperty(player.media, 'muted', {\n get() {\n return muted;\n },\n set(input) {\n const toggle = is.boolean(input) ? input : muted;\n muted = toggle;\n instance[toggle ? 'mute' : 'unMute']();\n triggerEvent.call(player, player.media, 'volumechange');\n },\n });\n\n // Source\n Object.defineProperty(player.media, 'currentSrc', {\n get() {\n return instance.getVideoUrl();\n },\n });\n\n // Ended\n Object.defineProperty(player.media, 'ended', {\n get() {\n return player.currentTime === player.duration;\n },\n });\n\n // Get available speeds\n player.options.speed = instance.getAvailablePlaybackRates();\n\n // Set the tabindex to avoid focus entering iframe\n if (player.supported.ui) {\n player.media.setAttribute('tabindex', -1);\n }\n\n triggerEvent.call(player, player.media, 'timeupdate');\n triggerEvent.call(player, player.media, 'durationchange');\n\n // Reset timer\n clearInterval(player.timers.buffering);\n\n // Setup buffering\n player.timers.buffering = setInterval(() => {\n // Get loaded % from YouTube\n player.media.buffered = instance.getVideoLoadedFraction();\n\n // Trigger progress only when we actually buffer something\n if (player.media.lastBuffered === null || player.media.lastBuffered < player.media.buffered) {\n triggerEvent.call(player, player.media, 'progress');\n }\n\n // Set last buffer point\n player.media.lastBuffered = player.media.buffered;\n\n // Bail if we're at 100%\n if (player.media.buffered === 1) {\n clearInterval(player.timers.buffering);\n\n // Trigger event\n triggerEvent.call(player, player.media, 'canplaythrough');\n }\n }, 200);\n\n // Rebuild UI\n setTimeout(() => ui.build.call(player), 50);\n },\n onStateChange(event) {\n // Get the instance\n const instance = event.target;\n\n // Reset timer\n clearInterval(player.timers.playing);\n\n const seeked = player.media.seeking && [1, 2].includes(event.data);\n\n if (seeked) {\n // Unset seeking and fire seeked event\n player.media.seeking = false;\n triggerEvent.call(player, player.media, 'seeked');\n }\n\n // Handle events\n // -1 Unstarted\n // 0 Ended\n // 1 Playing\n // 2 Paused\n // 3 Buffering\n // 5 Video cued\n switch (event.data) {\n case -1:\n // Update scrubber\n triggerEvent.call(player, player.media, 'timeupdate');\n\n // Get loaded % from YouTube\n player.media.buffered = instance.getVideoLoadedFraction();\n triggerEvent.call(player, player.media, 'progress');\n\n break;\n\n case 0:\n assurePlaybackState.call(player, false);\n\n // YouTube doesn't support loop for a single video, so mimick it.\n if (player.media.loop) {\n // YouTube needs a call to `stopVideo` before playing again\n instance.stopVideo();\n instance.playVideo();\n } else {\n triggerEvent.call(player, player.media, 'ended');\n }\n\n break;\n\n case 1:\n // Restore paused state (YouTube starts playing on seek if the video hasn't been played yet)\n if (player.media.paused && !player.embed.hasPlayed) {\n player.media.pause();\n } else {\n assurePlaybackState.call(player, true);\n\n triggerEvent.call(player, player.media, 'playing');\n\n // Poll to get playback progress\n player.timers.playing = setInterval(() => {\n triggerEvent.call(player, player.media, 'timeupdate');\n }, 50);\n\n // Check duration again due to YouTube bug\n // https://github.com/sampotts/plyr/issues/374\n // https://code.google.com/p/gdata-issues/issues/detail?id=8690\n if (player.media.duration !== instance.getDuration()) {\n player.media.duration = instance.getDuration();\n triggerEvent.call(player, player.media, 'durationchange');\n }\n\n // Get quality\n controls.setQualityMenu.call(\n player,\n mapQualityUnits(instance.getAvailableQualityLevels()),\n );\n }\n\n break;\n\n case 2:\n // Restore audio (YouTube starts playing on seek if the video hasn't been played yet)\n if (!player.muted) {\n player.embed.unMute();\n }\n assurePlaybackState.call(player, false);\n\n break;\n\n default:\n break;\n }\n\n triggerEvent.call(player, player.elements.container, 'statechange', false, {\n code: event.data,\n });\n },\n },\n });\n },\n};\n\nexport default youtube;\n","// ==========================================================================\n// Plyr Media\n// ==========================================================================\n\nimport html5 from './html5';\nimport vimeo from './plugins/vimeo';\nimport youtube from './plugins/youtube';\nimport { createElement, toggleClass, wrap } from './utils/elements';\n\nconst media = {\n // Setup media\n setup() {\n // If there's no media, bail\n if (!this.media) {\n this.debug.warn('No media element found!');\n return;\n }\n\n // Add type class\n toggleClass(this.elements.container, this.config.classNames.type.replace('{0}', this.type), true);\n\n // Add provider class\n toggleClass(this.elements.container, this.config.classNames.provider.replace('{0}', this.provider), true);\n\n // Add video class for embeds\n // This will require changes if audio embeds are added\n if (this.isEmbed) {\n toggleClass(this.elements.container, this.config.classNames.type.replace('{0}', 'video'), true);\n }\n\n // Inject the player wrapper\n if (this.isVideo) {\n // Create the wrapper div\n this.elements.wrapper = createElement('div', {\n class: this.config.classNames.video,\n });\n\n // Wrap the video in a container\n wrap(this.media, this.elements.wrapper);\n\n // Faux poster container\n this.elements.poster = createElement('div', {\n class: this.config.classNames.poster,\n });\n\n this.elements.wrapper.appendChild(this.elements.poster);\n }\n\n if (this.isHTML5) {\n html5.extend.call(this);\n } else if (this.isYouTube) {\n youtube.setup.call(this);\n } else if (this.isVimeo) {\n vimeo.setup.call(this);\n }\n },\n};\n\nexport default media;\n","// ==========================================================================\n// Advertisement plugin using Google IMA HTML5 SDK\n// Create an account with our ad partner, vi here:\n// https://www.vi.ai/publisher-video-monetization/\n// ==========================================================================\n\n/* global google */\n\nimport i18n from '../i18n';\nimport { createElement } from './../utils/elements';\nimport { triggerEvent } from './../utils/events';\nimport is from './../utils/is';\nimport loadScript from './../utils/loadScript';\nimport { formatTime } from './../utils/time';\nimport { buildUrlParams } from './../utils/urls';\n\nclass Ads {\n /**\n * Ads constructor.\n * @param {object} player\n * @return {Ads}\n */\n constructor(player) {\n this.player = player;\n this.publisherId = player.config.ads.publisherId;\n this.playing = false;\n this.initialized = false;\n this.elements = {\n container: null,\n displayContainer: null,\n };\n this.manager = null;\n this.loader = null;\n this.cuePoints = null;\n this.events = {};\n this.safetyTimer = null;\n this.countdownTimer = null;\n\n // Setup a promise to resolve when the IMA manager is ready\n this.managerPromise = new Promise((resolve, reject) => {\n // The ad is loaded and ready\n this.on('loaded', resolve);\n\n // Ads failed\n this.on('error', reject);\n });\n\n this.load();\n }\n\n get enabled() {\n return this.player.isVideo && this.player.config.ads.enabled && !is.empty(this.publisherId);\n }\n\n /**\n * Load the IMA SDK\n */\n load() {\n if (this.enabled) {\n // Check if the Google IMA3 SDK is loaded or load it ourselves\n if (!is.object(window.google) || !is.object(window.google.ima)) {\n loadScript(this.player.config.urls.googleIMA.sdk)\n .then(() => {\n this.ready();\n })\n .catch(() => {\n // Script failed to load or is blocked\n this.trigger('error', new Error('Google IMA SDK failed to load'));\n });\n } else {\n this.ready();\n }\n }\n }\n\n /**\n * Get the ads instance ready\n */\n ready() {\n // Start ticking our safety timer. If the whole advertisement\n // thing doesn't resolve within our set time; we bail\n this.startSafetyTimer(12000, 'ready()');\n\n // Clear the safety timer\n this.managerPromise.then(() => {\n this.clearSafetyTimer('onAdsManagerLoaded()');\n });\n\n // Set listeners on the Plyr instance\n this.listeners();\n\n // Setup the IMA SDK\n this.setupIMA();\n }\n\n // Build the default tag URL\n get tagUrl() {\n const params = {\n AV_PUBLISHERID: '58c25bb0073ef448b1087ad6',\n AV_CHANNELID: '5a0458dc28a06145e4519d21',\n AV_URL: location.hostname,\n cb: Date.now(),\n AV_WIDTH: 640,\n AV_HEIGHT: 480,\n AV_CDIM2: this.publisherId,\n };\n\n const base = 'https://go.aniview.com/api/adserver6/vast/';\n\n return `${base}?${buildUrlParams(params)}`;\n }\n\n /**\n * In order for the SDK to display ads for our video, we need to tell it where to put them,\n * so here we define our ad container. This div is set up to render on top of the video player.\n * Using the code below, we tell the SDK to render ads within that div. We also provide a\n * handle to the content video player - the SDK will poll the current time of our player to\n * properly place mid-rolls. After we create the ad display container, we initialize it. On\n * mobile devices, this initialization is done as the result of a user action.\n */\n setupIMA() {\n // Create the container for our advertisements\n this.elements.container = createElement('div', {\n class: this.player.config.classNames.ads,\n });\n this.player.elements.container.appendChild(this.elements.container);\n\n // So we can run VPAID2\n google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED);\n\n // Set language\n google.ima.settings.setLocale(this.player.config.ads.language);\n\n // We assume the adContainer is the video container of the plyr element\n // that will house the ads\n this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container);\n\n // Request video ads to be pre-loaded\n this.requestAds();\n }\n\n /**\n * Request advertisements\n */\n requestAds() {\n const { container } = this.player.elements;\n\n try {\n // Create ads loader\n this.loader = new google.ima.AdsLoader(this.elements.displayContainer);\n\n // Listen and respond to ads loaded and error events\n this.loader.addEventListener(\n google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,\n event => this.onAdsManagerLoaded(event),\n false,\n );\n this.loader.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error), false);\n\n // Request video ads\n const request = new google.ima.AdsRequest();\n request.adTagUrl = this.tagUrl;\n\n // Specify the linear and nonlinear slot sizes. This helps the SDK\n // to select the correct creative if multiple are returned\n request.linearAdSlotWidth = container.offsetWidth;\n request.linearAdSlotHeight = container.offsetHeight;\n request.nonLinearAdSlotWidth = container.offsetWidth;\n request.nonLinearAdSlotHeight = container.offsetHeight;\n\n // We only overlay ads as we only support video.\n request.forceNonLinearFullSlot = false;\n\n // Mute based on current state\n request.setAdWillPlayMuted(!this.player.muted);\n\n this.loader.requestAds(request);\n } catch (e) {\n this.onAdError(e);\n }\n }\n\n /**\n * Update the ad countdown\n * @param {boolean} start\n */\n pollCountdown(start = false) {\n if (!start) {\n clearInterval(this.countdownTimer);\n this.elements.container.removeAttribute('data-badge-text');\n return;\n }\n\n const update = () => {\n const time = formatTime(Math.max(this.manager.getRemainingTime(), 0));\n const label = `${i18n.get('advertisement', this.player.config)} - ${time}`;\n this.elements.container.setAttribute('data-badge-text', label);\n };\n\n this.countdownTimer = setInterval(update, 100);\n }\n\n /**\n * This method is called whenever the ads are ready inside the AdDisplayContainer\n * @param {Event} adsManagerLoadedEvent\n */\n onAdsManagerLoaded(event) {\n // Get the ads manager\n const settings = new google.ima.AdsRenderingSettings();\n\n // Tell the SDK to save and restore content video state on our behalf\n settings.restoreCustomPlaybackStateOnAdBreakComplete = true;\n settings.enablePreloading = true;\n\n // The SDK is polling currentTime on the contentPlayback. And needs a duration\n // so it can determine when to start the mid- and post-roll\n this.manager = event.getAdsManager(this.player, settings);\n\n // Get the cue points for any mid-rolls by filtering out the pre- and post-roll\n this.cuePoints = this.manager.getCuePoints();\n\n // Add advertisement cue's within the time line if available\n if (!is.empty(this.cuePoints)) {\n this.cuePoints.forEach(cuePoint => {\n if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < this.player.duration) {\n const seekElement = this.player.elements.progress;\n\n if (is.element(seekElement)) {\n const cuePercentage = 100 / this.player.duration * cuePoint;\n const cue = createElement('span', {\n class: this.player.config.classNames.cues,\n });\n\n cue.style.left = `${cuePercentage.toString()}%`;\n seekElement.appendChild(cue);\n }\n }\n });\n }\n\n // Get skippable state\n // TODO: Skip button\n // this.player.debug.warn(this.manager.getAdSkippableState());\n\n // Set volume to match player\n this.manager.setVolume(this.player.volume);\n\n // Add listeners to the required events\n // Advertisement error events\n this.manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error));\n\n // Advertisement regular events\n Object.keys(google.ima.AdEvent.Type).forEach(type => {\n this.manager.addEventListener(google.ima.AdEvent.Type[type], event => this.onAdEvent(event));\n });\n\n // Resolve our adsManager\n this.trigger('loaded');\n }\n\n /**\n * This is where all the event handling takes place. Retrieve the ad from the event. Some\n * events (e.g. ALL_ADS_COMPLETED) don't have the ad object associated\n * https://developers.google.com/interactive-media-ads/docs/sdks/html5/v3/apis#ima.AdEvent.Type\n * @param {Event} event\n */\n onAdEvent(event) {\n const { container } = this.player.elements;\n\n // Retrieve the ad from the event. Some events (e.g. ALL_ADS_COMPLETED)\n // don't have ad object associated\n const ad = event.getAd();\n\n // Proxy event\n const dispatchEvent = type => {\n const event = `ads${type.replace(/_/g, '').toLowerCase()}`;\n triggerEvent.call(this.player, this.player.media, event);\n };\n\n switch (event.type) {\n case google.ima.AdEvent.Type.LOADED:\n // This is the first event sent for an ad - it is possible to determine whether the\n // ad is a video ad or an overlay\n this.trigger('loaded');\n\n // Bubble event\n dispatchEvent(event.type);\n\n // Start countdown\n this.pollCountdown(true);\n\n if (!ad.isLinear()) {\n // Position AdDisplayContainer correctly for overlay\n ad.width = container.offsetWidth;\n ad.height = container.offsetHeight;\n }\n\n // console.info('Ad type: ' + event.getAd().getAdPodInfo().getPodIndex());\n // console.info('Ad time: ' + event.getAd().getAdPodInfo().getTimeOffset());\n break;\n\n case google.ima.AdEvent.Type.ALL_ADS_COMPLETED:\n // All ads for the current videos are done. We can now request new advertisements\n // in case the video is re-played\n\n // Fire event\n dispatchEvent(event.type);\n\n // TODO: Example for what happens when a next video in a playlist would be loaded.\n // So here we load a new video when all ads are done.\n // Then we load new ads within a new adsManager. When the video\n // Is started - after - the ads are loaded, then we get ads.\n // You can also easily test cancelling and reloading by running\n // player.ads.cancel() and player.ads.play from the console I guess.\n // this.player.source = {\n // type: 'video',\n // title: 'View From A Blue Moon',\n // sources: [{\n // src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4', type:\n // 'video/mp4', }], poster:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg', tracks:\n // [ { kind: 'captions', label: 'English', srclang: 'en', src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt',\n // default: true, }, { kind: 'captions', label: 'French', srclang: 'fr', src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt', }, ],\n // };\n\n // TODO: So there is still this thing where a video should only be allowed to start\n // playing when the IMA SDK is ready or has failed\n\n this.loadAds();\n break;\n\n case google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED:\n // This event indicates the ad has started - the video player can adjust the UI,\n // for example display a pause button and remaining time. Fired when content should\n // be paused. This usually happens right before an ad is about to cover the content\n\n dispatchEvent(event.type);\n\n this.pauseContent();\n\n break;\n\n case google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED:\n // This event indicates the ad has finished - the video player can perform\n // appropriate UI actions, such as removing the timer for remaining time detection.\n // Fired when content should be resumed. This usually happens when an ad finishes\n // or collapses\n\n dispatchEvent(event.type);\n\n this.pollCountdown();\n\n this.resumeContent();\n\n break;\n\n case google.ima.AdEvent.Type.STARTED:\n case google.ima.AdEvent.Type.MIDPOINT:\n case google.ima.AdEvent.Type.COMPLETE:\n case google.ima.AdEvent.Type.IMPRESSION:\n case google.ima.AdEvent.Type.CLICK:\n dispatchEvent(event.type);\n break;\n\n default:\n break;\n }\n }\n\n /**\n * Any ad error handling comes through here\n * @param {Event} event\n */\n onAdError(event) {\n this.cancel();\n this.player.debug.warn('Ads error', event);\n }\n\n /**\n * Setup hooks for Plyr and window events. This ensures\n * the mid- and post-roll launch at the correct time. And\n * resize the advertisement when the player resizes\n */\n listeners() {\n const { container } = this.player.elements;\n let time;\n\n // Add listeners to the required events\n this.player.on('ended', () => {\n this.loader.contentComplete();\n });\n\n this.player.on('seeking', () => {\n time = this.player.currentTime;\n return time;\n });\n\n this.player.on('seeked', () => {\n const seekedTime = this.player.currentTime;\n\n if (is.empty(this.cuePoints)) {\n return;\n }\n\n this.cuePoints.forEach((cuePoint, index) => {\n if (time < cuePoint && cuePoint < seekedTime) {\n this.manager.discardAdBreak();\n this.cuePoints.splice(index, 1);\n }\n });\n });\n\n // Listen to the resizing of the window. And resize ad accordingly\n // TODO: eventually implement ResizeObserver\n window.addEventListener('resize', () => {\n if (this.manager) {\n this.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);\n }\n });\n }\n\n /**\n * Initialize the adsManager and start playing advertisements\n */\n play() {\n const { container } = this.player.elements;\n\n if (!this.managerPromise) {\n this.resumeContent();\n }\n\n // Play the requested advertisement whenever the adsManager is ready\n this.managerPromise\n .then(() => {\n // Initialize the container. Must be done via a user action on mobile devices\n this.elements.displayContainer.initialize();\n\n try {\n if (!this.initialized) {\n // Initialize the ads manager. Ad rules playlist will start at this time\n this.manager.init(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);\n\n // Call play to start showing the ad. Single video and overlay ads will\n // start at this time; the call will be ignored for ad rules\n this.manager.start();\n }\n\n this.initialized = true;\n } catch (adError) {\n // An error may be thrown if there was a problem with the\n // VAST response\n this.onAdError(adError);\n }\n })\n .catch(() => {});\n }\n\n /**\n * Resume our video\n */\n resumeContent() {\n // Hide the advertisement container\n this.elements.container.style.zIndex = '';\n\n // Ad is stopped\n this.playing = false;\n\n // Play our video\n if (this.player.currentTime < this.player.duration) {\n this.player.play();\n }\n }\n\n /**\n * Pause our video\n */\n pauseContent() {\n // Show the advertisement container\n this.elements.container.style.zIndex = 3;\n\n // Ad is playing.\n this.playing = true;\n\n // Pause our video.\n this.player.pause();\n }\n\n /**\n * Destroy the adsManager so we can grab new ads after this. If we don't then we're not\n * allowed to call new ads based on google policies, as they interpret this as an accidental\n * video requests. https://developers.google.com/interactive-\n * media-ads/docs/sdks/android/faq#8\n */\n cancel() {\n // Pause our video\n if (this.initialized) {\n this.resumeContent();\n }\n\n // Tell our instance that we're done for now\n this.trigger('error');\n\n // Re-create our adsManager\n this.loadAds();\n }\n\n /**\n * Re-create our adsManager\n */\n loadAds() {\n // Tell our adsManager to go bye bye\n this.managerPromise\n .then(() => {\n // Destroy our adsManager\n if (this.manager) {\n this.manager.destroy();\n }\n\n // Re-set our adsManager promises\n this.managerPromise = new Promise(resolve => {\n this.on('loaded', resolve);\n this.player.debug.log(this.manager);\n });\n\n // Now request some new advertisements\n this.requestAds();\n })\n .catch(() => {});\n }\n\n /**\n * Handles callbacks after an ad event was invoked\n * @param {string} event - Event type\n */\n trigger(event, ...args) {\n const handlers = this.events[event];\n\n if (is.array(handlers)) {\n handlers.forEach(handler => {\n if (is.function(handler)) {\n handler.apply(this, args);\n }\n });\n }\n }\n\n /**\n * Add event listeners\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n * @return {Ads}\n */\n on(event, callback) {\n if (!is.array(this.events[event])) {\n this.events[event] = [];\n }\n\n this.events[event].push(callback);\n\n return this;\n }\n\n /**\n * Setup a safety timer for when the ad network doesn't respond for whatever reason.\n * The advertisement has 12 seconds to get its things together. We stop this timer when the\n * advertisement is playing, or when a user action is required to start, then we clear the\n * timer on ad ready\n * @param {number} time\n * @param {string} from\n */\n startSafetyTimer(time, from) {\n this.player.debug.log(`Safety timer invoked from: ${from}`);\n\n this.safetyTimer = setTimeout(() => {\n this.cancel();\n this.clearSafetyTimer('startSafetyTimer()');\n }, time);\n }\n\n /**\n * Clear our safety timer(s)\n * @param {string} from\n */\n clearSafetyTimer(from) {\n if (!is.nullOrUndefined(this.safetyTimer)) {\n this.player.debug.log(`Safety timer cleared from: ${from}`);\n\n clearTimeout(this.safetyTimer);\n this.safetyTimer = null;\n }\n }\n}\n\nexport default Ads;\n","// ==========================================================================\n// Plyr source update\n// ==========================================================================\n\nimport { providers } from './config/types';\nimport html5 from './html5';\nimport media from './media';\nimport support from './support';\nimport ui from './ui';\nimport { createElement, insertElement, removeElement } from './utils/elements';\nimport is from './utils/is';\nimport { getDeep } from './utils/objects';\n\nconst source = {\n // Add elements to HTML5 media (source, tracks, etc)\n insertElements(type, attributes) {\n if (is.string(attributes)) {\n insertElement(type, this.media, {\n src: attributes,\n });\n } else if (is.array(attributes)) {\n attributes.forEach(attribute => {\n insertElement(type, this.media, attribute);\n });\n }\n },\n\n // Update source\n // Sources are not checked for support so be careful\n change(input) {\n if (!getDeep(input, 'sources.length')) {\n this.debug.warn('Invalid source format');\n return;\n }\n\n // Cancel current network requests\n html5.cancelRequests.call(this);\n\n // Destroy instance and re-setup\n this.destroy.call(\n this,\n () => {\n // Reset quality options\n this.options.quality = [];\n\n // Remove elements\n removeElement(this.media);\n this.media = null;\n\n // Reset class name\n if (is.element(this.elements.container)) {\n this.elements.container.removeAttribute('class');\n }\n\n // Set the type and provider\n const { sources, type } = input;\n const [{ provider = providers.html5, src }] = sources;\n const tagName = provider === 'html5' ? type : 'div';\n const attributes = provider === 'html5' ? {} : { src };\n\n Object.assign(this, {\n provider,\n type,\n // Check for support\n supported: support.check(type, provider, this.config.playsinline),\n // Create new element\n media: createElement(tagName, attributes),\n });\n\n // Inject the new element\n this.elements.container.appendChild(this.media);\n\n // Autoplay the new source?\n if (is.boolean(input.autoplay)) {\n this.config.autoplay = input.autoplay;\n }\n\n // Set attributes for audio and video\n if (this.isHTML5) {\n if (this.config.crossorigin) {\n this.media.setAttribute('crossorigin', '');\n }\n if (this.config.autoplay) {\n this.media.setAttribute('autoplay', '');\n }\n if (!is.empty(input.poster)) {\n this.poster = input.poster;\n }\n if (this.config.loop.active) {\n this.media.setAttribute('loop', '');\n }\n if (this.config.muted) {\n this.media.setAttribute('muted', '');\n }\n if (this.config.playsinline) {\n this.media.setAttribute('playsinline', '');\n }\n }\n\n // Restore class hook\n ui.addStyleHook.call(this);\n\n // Set new sources for html5\n if (this.isHTML5) {\n source.insertElements.call(this, 'source', sources);\n }\n\n // Set video title\n this.config.title = input.title;\n\n // Set up from scratch\n media.setup.call(this);\n\n // HTML5 stuff\n if (this.isHTML5) {\n // Setup captions\n if ('tracks' in input) {\n source.insertElements.call(this, 'track', input.tracks);\n }\n\n // Load HTML5 sources\n this.media.load();\n }\n\n // If HTML5 or embed but not fully supported, setupInterface and call ready now\n if (this.isHTML5 || (this.isEmbed && !this.supported.ui)) {\n // Setup interface\n ui.build.call(this);\n }\n\n // Update the fullscreen support\n this.fullscreen.update();\n },\n true,\n );\n },\n};\n\nexport default source;\n","// ==========================================================================\n// Plyr\n// plyr.js v3.3.15\n// https://github.com/sampotts/plyr\n// License: The MIT License (MIT)\n// ==========================================================================\n\nimport captions from './captions';\nimport defaults from './config/defaults';\nimport { getProviderByUrl, providers, types } from './config/types';\nimport Console from './console';\nimport controls from './controls';\nimport Fullscreen from './fullscreen';\nimport Listeners from './listeners';\nimport media from './media';\nimport Ads from './plugins/ads';\nimport source from './source';\nimport Storage from './storage';\nimport support from './support';\nimport ui from './ui';\nimport { closest } from './utils/arrays';\nimport { createElement, hasClass, removeElement, replaceElement, toggleClass, wrap } from './utils/elements';\nimport { off, on, once, triggerEvent, unbindListeners } from './utils/events';\nimport is from './utils/is';\nimport loadSprite from './utils/loadSprite';\nimport { cloneDeep, extend } from './utils/objects';\nimport { parseUrl } from './utils/urls';\n\n// Private properties\n// TODO: Use a WeakMap for private globals\n// const globals = new WeakMap();\n\n// Plyr instance\nclass Plyr {\n constructor(target, options) {\n this.timers = {};\n\n // State\n this.ready = false;\n this.loading = false;\n this.failed = false;\n\n // Touch device\n this.touch = support.touch;\n\n // Set the media element\n this.media = target;\n\n // String selector passed\n if (is.string(this.media)) {\n this.media = document.querySelectorAll(this.media);\n }\n\n // jQuery, NodeList or Array passed, use first element\n if ((window.jQuery && this.media instanceof jQuery) || is.nodeList(this.media) || is.array(this.media)) {\n // eslint-disable-next-line\n this.media = this.media[0];\n }\n\n // Set config\n this.config = extend(\n {},\n defaults,\n Plyr.defaults,\n options || {},\n (() => {\n try {\n return JSON.parse(this.media.getAttribute('data-plyr-config'));\n } catch (e) {\n return {};\n }\n })(),\n );\n\n // Elements cache\n this.elements = {\n container: null,\n captions: null,\n buttons: {},\n display: {},\n progress: {},\n inputs: {},\n settings: {\n popup: null,\n menu: null,\n panels: {},\n buttons: {},\n },\n };\n\n // Captions\n this.captions = {\n active: null,\n currentTrack: -1,\n meta: new WeakMap(),\n };\n\n // Fullscreen\n this.fullscreen = {\n active: false,\n };\n\n // Options\n this.options = {\n speed: [],\n quality: [],\n };\n\n // Debugging\n // TODO: move to globals\n this.debug = new Console(this.config.debug);\n\n // Log config options and support\n this.debug.log('Config', this.config);\n this.debug.log('Support', support);\n\n // We need an element to setup\n if (is.nullOrUndefined(this.media) || !is.element(this.media)) {\n this.debug.error('Setup failed: no suitable element passed');\n return;\n }\n\n // Bail if the element is initialized\n if (this.media.plyr) {\n this.debug.warn('Target already setup');\n return;\n }\n\n // Bail if not enabled\n if (!this.config.enabled) {\n this.debug.error('Setup failed: disabled by config');\n return;\n }\n\n // Bail if disabled or no basic support\n // You may want to disable certain UAs etc\n if (!support.check().api) {\n this.debug.error('Setup failed: no support');\n return;\n }\n\n // Cache original element state for .destroy()\n const clone = this.media.cloneNode(true);\n clone.autoplay = false;\n this.elements.original = clone;\n\n // Set media type based on tag or data attribute\n // Supported: video, audio, vimeo, youtube\n const type = this.media.tagName.toLowerCase();\n\n // Embed properties\n let iframe = null;\n let url = null;\n\n // Different setup based on type\n switch (type) {\n case 'div':\n // Find the frame\n iframe = this.media.querySelector('iframe');\n\n // <iframe> type\n if (is.element(iframe)) {\n // Detect provider\n url = parseUrl(iframe.getAttribute('src'));\n this.provider = getProviderByUrl(url.toString());\n\n // Rework elements\n this.elements.container = this.media;\n this.media = iframe;\n\n // Reset classname\n this.elements.container.className = '';\n\n // Get attributes from URL and set config\n if (url.searchParams.length) {\n const truthy = ['1', 'true'];\n\n if (truthy.includes(url.searchParams.get('autoplay'))) {\n this.config.autoplay = true;\n }\n if (truthy.includes(url.searchParams.get('loop'))) {\n this.config.loop.active = true;\n }\n\n // TODO: replace fullscreen.iosNative with this playsinline config option\n // YouTube requires the playsinline in the URL\n if (this.isYouTube) {\n this.config.playsinline = truthy.includes(url.searchParams.get('playsinline'));\n } else {\n this.config.playsinline = true;\n }\n }\n } else {\n // <div> with attributes\n this.provider = this.media.getAttribute(this.config.attributes.embed.provider);\n\n // Remove attribute\n this.media.removeAttribute(this.config.attributes.embed.provider);\n }\n\n // Unsupported or missing provider\n if (is.empty(this.provider) || !Object.keys(providers).includes(this.provider)) {\n this.debug.error('Setup failed: Invalid provider');\n return;\n }\n\n // Audio will come later for external providers\n this.type = types.video;\n\n break;\n\n case 'video':\n case 'audio':\n this.type = type;\n this.provider = providers.html5;\n\n // Get config from attributes\n if (this.media.hasAttribute('crossorigin')) {\n this.config.crossorigin = true;\n }\n if (this.media.hasAttribute('autoplay')) {\n this.config.autoplay = true;\n }\n if (this.media.hasAttribute('playsinline')) {\n this.config.playsinline = true;\n }\n if (this.media.hasAttribute('muted')) {\n this.config.muted = true;\n }\n if (this.media.hasAttribute('loop')) {\n this.config.loop.active = true;\n }\n\n break;\n\n default:\n this.debug.error('Setup failed: unsupported type');\n return;\n }\n\n // Check for support again but with type\n this.supported = support.check(this.type, this.provider, this.config.playsinline);\n\n // If no support for even API, bail\n if (!this.supported.api) {\n this.debug.error('Setup failed: no support');\n return;\n }\n\n this.eventListeners = [];\n\n // Create listeners\n this.listeners = new Listeners(this);\n\n // Setup local storage for user settings\n this.storage = new Storage(this);\n\n // Store reference\n this.media.plyr = this;\n\n // Wrap media\n if (!is.element(this.elements.container)) {\n this.elements.container = createElement('div');\n wrap(this.media, this.elements.container);\n }\n\n // Add style hook\n ui.addStyleHook.call(this);\n\n // Setup media\n media.setup.call(this);\n\n // Listen for events if debugging\n if (this.config.debug) {\n on.call(this, this.elements.container, this.config.events.join(' '), event => {\n this.debug.log(`event: ${event.type}`);\n });\n }\n\n // Setup interface\n // If embed but not fully supported, build interface now to avoid flash of controls\n if (this.isHTML5 || (this.isEmbed && !this.supported.ui)) {\n ui.build.call(this);\n }\n\n // Container listeners\n this.listeners.container();\n\n // Global listeners\n this.listeners.global();\n\n // Setup fullscreen\n this.fullscreen = new Fullscreen(this);\n\n // Setup ads if provided\n this.ads = new Ads(this);\n\n // Autoplay if required\n if (this.config.autoplay) {\n this.play();\n }\n }\n\n // ---------------------------------------\n // API\n // ---------------------------------------\n\n /**\n * Types and provider helpers\n */\n get isHTML5() {\n return Boolean(this.provider === providers.html5);\n }\n get isEmbed() {\n return Boolean(this.isYouTube || this.isVimeo);\n }\n get isYouTube() {\n return Boolean(this.provider === providers.youtube);\n }\n get isVimeo() {\n return Boolean(this.provider === providers.vimeo);\n }\n get isVideo() {\n return Boolean(this.type === types.video);\n }\n get isAudio() {\n return Boolean(this.type === types.audio);\n }\n\n /**\n * Play the media, or play the advertisement (if they are not blocked)\n */\n play() {\n if (!is.function(this.media.play)) {\n return null;\n }\n\n // Return the promise (for HTML5)\n return this.media.play();\n }\n\n /**\n * Pause the media\n */\n pause() {\n if (!this.playing || !is.function(this.media.pause)) {\n return;\n }\n\n this.media.pause();\n }\n\n /**\n * Get playing state\n */\n get playing() {\n return Boolean(this.ready && !this.paused && !this.ended);\n }\n\n /**\n * Get paused state\n */\n get paused() {\n return Boolean(this.media.paused);\n }\n\n /**\n * Get stopped state\n */\n get stopped() {\n return Boolean(this.paused && this.currentTime === 0);\n }\n\n /**\n * Get ended state\n */\n get ended() {\n return Boolean(this.media.ended);\n }\n\n /**\n * Toggle playback based on current status\n * @param {boolean} input\n */\n togglePlay(input) {\n // Toggle based on current state if nothing passed\n const toggle = is.boolean(input) ? input : !this.playing;\n\n if (toggle) {\n this.play();\n } else {\n this.pause();\n }\n }\n\n /**\n * Stop playback\n */\n stop() {\n if (this.isHTML5) {\n this.pause();\n this.restart();\n } else if (is.function(this.media.stop)) {\n this.media.stop();\n }\n }\n\n /**\n * Restart playback\n */\n restart() {\n this.currentTime = 0;\n }\n\n /**\n * Rewind\n * @param {number} seekTime - how far to rewind in seconds. Defaults to the config.seekTime\n */\n rewind(seekTime) {\n this.currentTime = this.currentTime - (is.number(seekTime) ? seekTime : this.config.seekTime);\n }\n\n /**\n * Fast forward\n * @param {number} seekTime - how far to fast forward in seconds. Defaults to the config.seekTime\n */\n forward(seekTime) {\n this.currentTime = this.currentTime + (is.number(seekTime) ? seekTime : this.config.seekTime);\n }\n\n /**\n * Seek to a time\n * @param {number} input - where to seek to in seconds. Defaults to 0 (the start)\n */\n set currentTime(input) {\n // Bail if media duration isn't available yet\n if (!this.duration) {\n return;\n }\n\n // Validate input\n const inputIsValid = is.number(input) && input > 0;\n\n // Set\n this.media.currentTime = inputIsValid ? Math.min(input, this.duration) : 0;\n\n // Logging\n this.debug.log(`Seeking to ${this.currentTime} seconds`);\n }\n\n /**\n * Get current time\n */\n get currentTime() {\n return Number(this.media.currentTime);\n }\n\n /**\n * Get buffered\n */\n get buffered() {\n const { buffered } = this.media;\n\n // YouTube / Vimeo return a float between 0-1\n if (is.number(buffered)) {\n return buffered;\n }\n\n // HTML5\n // TODO: Handle buffered chunks of the media\n // (i.e. seek to another section buffers only that section)\n if (buffered && buffered.length && this.duration > 0) {\n return buffered.end(0) / this.duration;\n }\n\n return 0;\n }\n\n /**\n * Get seeking status\n */\n get seeking() {\n return Boolean(this.media.seeking);\n }\n\n /**\n * Get the duration of the current media\n */\n get duration() {\n // Faux duration set via config\n const fauxDuration = parseFloat(this.config.duration);\n\n // Media duration can be NaN before the media has loaded\n const duration = (this.media || {}).duration || 0;\n\n // If config duration is funky, use regular duration\n return fauxDuration || duration;\n }\n\n /**\n * Set the player volume\n * @param {number} value - must be between 0 and 1. Defaults to the value from local storage and config.volume if not set in storage\n */\n set volume(value) {\n let volume = value;\n const max = 1;\n const min = 0;\n\n if (is.string(volume)) {\n volume = Number(volume);\n }\n\n // Load volume from storage if no value specified\n if (!is.number(volume)) {\n volume = this.storage.get('volume');\n }\n\n // Use config if all else fails\n if (!is.number(volume)) {\n ({ volume } = this.config);\n }\n\n // Maximum is volumeMax\n if (volume > max) {\n volume = max;\n }\n // Minimum is volumeMin\n if (volume < min) {\n volume = min;\n }\n\n // Update config\n this.config.volume = volume;\n\n // Set the player volume\n this.media.volume = volume;\n\n // If muted, and we're increasing volume manually, reset muted state\n if (!is.empty(value) && this.muted && volume > 0) {\n this.muted = false;\n }\n }\n\n /**\n * Get the current player volume\n */\n get volume() {\n return Number(this.media.volume);\n }\n\n /**\n * Increase volume\n * @param {boolean} step - How much to decrease by (between 0 and 1)\n */\n increaseVolume(step) {\n const volume = this.media.muted ? 0 : this.volume;\n this.volume = volume + (is.number(step) ? step : 1);\n }\n\n /**\n * Decrease volume\n * @param {boolean} step - How much to decrease by (between 0 and 1)\n */\n decreaseVolume(step) {\n const volume = this.media.muted ? 0 : this.volume;\n this.volume = volume - (is.number(step) ? step : 1);\n }\n\n /**\n * Set muted state\n * @param {boolean} mute\n */\n set muted(mute) {\n let toggle = mute;\n\n // Load muted state from storage\n if (!is.boolean(toggle)) {\n toggle = this.storage.get('muted');\n }\n\n // Use config if all else fails\n if (!is.boolean(toggle)) {\n toggle = this.config.muted;\n }\n\n // Update config\n this.config.muted = toggle;\n\n // Set mute on the player\n this.media.muted = toggle;\n }\n\n /**\n * Get current muted state\n */\n get muted() {\n return Boolean(this.media.muted);\n }\n\n /**\n * Check if the media has audio\n */\n get hasAudio() {\n // Assume yes for all non HTML5 (as we can't tell...)\n if (!this.isHTML5) {\n return true;\n }\n\n if (this.isAudio) {\n return true;\n }\n\n // Get audio tracks\n return (\n Boolean(this.media.mozHasAudio) ||\n Boolean(this.media.webkitAudioDecodedByteCount) ||\n Boolean(this.media.audioTracks && this.media.audioTracks.length)\n );\n }\n\n /**\n * Set playback speed\n * @param {number} speed - the speed of playback (0.5-2.0)\n */\n set speed(input) {\n let speed = null;\n\n if (is.number(input)) {\n speed = input;\n }\n\n if (!is.number(speed)) {\n speed = this.storage.get('speed');\n }\n\n if (!is.number(speed)) {\n speed = this.config.speed.selected;\n }\n\n // Set min/max\n if (speed < 0.1) {\n speed = 0.1;\n }\n if (speed > 2.0) {\n speed = 2.0;\n }\n\n if (!this.config.speed.options.includes(speed)) {\n this.debug.warn(`Unsupported speed (${speed})`);\n return;\n }\n\n // Update config\n this.config.speed.selected = speed;\n\n // Set media speed\n this.media.playbackRate = speed;\n }\n\n /**\n * Get current playback speed\n */\n get speed() {\n return Number(this.media.playbackRate);\n }\n\n /**\n * Set playback quality\n * Currently HTML5 & YouTube only\n * @param {number} input - Quality level\n */\n set quality(input) {\n const config = this.config.quality;\n const options = this.options.quality;\n\n if (!options.length) {\n return;\n }\n\n let quality = [\n !is.empty(input) && Number(input),\n this.storage.get('quality'),\n config.selected,\n config.default,\n ].find(is.number);\n\n if (!options.includes(quality)) {\n const value = closest(options, quality);\n this.debug.warn(`Unsupported quality option: ${quality}, using ${value} instead`);\n quality = value;\n }\n\n // Trigger request event\n triggerEvent.call(this, this.media, 'qualityrequested', false, { quality });\n\n // Update config\n config.selected = quality;\n\n // Set quality\n this.media.quality = quality;\n }\n\n /**\n * Get current quality level\n */\n get quality() {\n return this.media.quality;\n }\n\n /**\n * Toggle loop\n * TODO: Finish fancy new logic. Set the indicator on load as user may pass loop as config\n * @param {boolean} input - Whether to loop or not\n */\n set loop(input) {\n const toggle = is.boolean(input) ? input : this.config.loop.active;\n this.config.loop.active = toggle;\n this.media.loop = toggle;\n\n // Set default to be a true toggle\n /* const type = ['start', 'end', 'all', 'none', 'toggle'].includes(input) ? input : 'toggle';\n\n switch (type) {\n case 'start':\n if (this.config.loop.end && this.config.loop.end <= this.currentTime) {\n this.config.loop.end = null;\n }\n this.config.loop.start = this.currentTime;\n // this.config.loop.indicator.start = this.elements.display.played.value;\n break;\n\n case 'end':\n if (this.config.loop.start >= this.currentTime) {\n return this;\n }\n this.config.loop.end = this.currentTime;\n // this.config.loop.indicator.end = this.elements.display.played.value;\n break;\n\n case 'all':\n this.config.loop.start = 0;\n this.config.loop.end = this.duration - 2;\n this.config.loop.indicator.start = 0;\n this.config.loop.indicator.end = 100;\n break;\n\n case 'toggle':\n if (this.config.loop.active) {\n this.config.loop.start = 0;\n this.config.loop.end = null;\n } else {\n this.config.loop.start = 0;\n this.config.loop.end = this.duration - 2;\n }\n break;\n\n default:\n this.config.loop.start = 0;\n this.config.loop.end = null;\n break;\n } */\n }\n\n /**\n * Get current loop state\n */\n get loop() {\n return Boolean(this.media.loop);\n }\n\n /**\n * Set new media source\n * @param {object} input - The new source object (see docs)\n */\n set source(input) {\n source.change.call(this, input);\n }\n\n /**\n * Get current source\n */\n get source() {\n return this.media.currentSrc;\n }\n\n /**\n * Set the poster image for a video\n * @param {input} - the URL for the new poster image\n */\n set poster(input) {\n if (!this.isVideo) {\n this.debug.warn('Poster can only be set for video');\n return;\n }\n\n ui.setPoster.call(this, input, false).catch(() => {});\n }\n\n /**\n * Get the current poster image\n */\n get poster() {\n if (!this.isVideo) {\n return null;\n }\n\n return this.media.getAttribute('poster');\n }\n\n /**\n * Set the autoplay state\n * @param {boolean} input - Whether to autoplay or not\n */\n set autoplay(input) {\n const toggle = is.boolean(input) ? input : this.config.autoplay;\n this.config.autoplay = toggle;\n }\n\n /**\n * Get the current autoplay state\n */\n get autoplay() {\n return Boolean(this.config.autoplay);\n }\n\n /**\n * Toggle captions\n * @param {boolean} input - Whether to enable captions\n */\n toggleCaptions(input) {\n captions.toggle.call(this, input, false);\n }\n\n /**\n * Set the caption track by index\n * @param {number} - Caption index\n */\n set currentTrack(input) {\n captions.set.call(this, input, false);\n }\n\n /**\n * Get the current caption track index (-1 if disabled)\n */\n get currentTrack() {\n const { toggled, currentTrack } = this.captions;\n return toggled ? currentTrack : -1;\n }\n\n /**\n * Set the wanted language for captions\n * Since tracks can be added later it won't update the actual caption track until there is a matching track\n * @param {string} - Two character ISO language code (e.g. EN, FR, PT, etc)\n */\n set language(input) {\n captions.setLanguage.call(this, input, false);\n }\n\n /**\n * Get the current track's language\n */\n get language() {\n return (captions.getCurrentTrack.call(this) || {}).language;\n }\n\n /**\n * Toggle picture-in-picture playback on WebKit/MacOS\n * TODO: update player with state, support, enabled\n * TODO: detect outside changes\n */\n set pip(input) {\n const states = {\n pip: 'picture-in-picture',\n inline: 'inline',\n };\n\n // Bail if no support\n if (!support.pip) {\n return;\n }\n\n // Toggle based on current state if not passed\n const toggle = is.boolean(input) ? input : this.pip === states.inline;\n\n // Toggle based on current state\n this.media.webkitSetPresentationMode(toggle ? states.pip : states.inline);\n }\n\n /**\n * Get the current picture-in-picture state\n */\n get pip() {\n if (!support.pip) {\n return null;\n }\n\n return this.media.webkitPresentationMode;\n }\n\n /**\n * Trigger the airplay dialog\n * TODO: update player with state, support, enabled\n */\n airplay() {\n // Show dialog if supported\n if (support.airplay) {\n this.media.webkitShowPlaybackTargetPicker();\n }\n }\n\n /**\n * Toggle the player controls\n * @param {boolean} [toggle] - Whether to show the controls\n */\n toggleControls(toggle) {\n // Don't toggle if missing UI support or if it's audio\n if (this.supported.ui && !this.isAudio) {\n // Get state before change\n const isHidden = hasClass(this.elements.container, this.config.classNames.hideControls);\n\n // Negate the argument if not undefined since adding the class to hides the controls\n const force = typeof toggle === 'undefined' ? undefined : !toggle;\n\n // Apply and get updated state\n const hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force);\n\n // Close menu\n if (hiding && this.config.controls.includes('settings') && !is.empty(this.config.settings)) {\n controls.toggleMenu.call(this, false);\n }\n // Trigger event on change\n if (hiding !== isHidden) {\n const eventName = hiding ? 'controlshidden' : 'controlsshown';\n triggerEvent.call(this, this.media, eventName);\n }\n return !hiding;\n }\n return false;\n }\n\n /**\n * Add event listeners\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n */\n on(event, callback) {\n on.call(this, this.elements.container, event, callback);\n }\n /**\n * Add event listeners once\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n */\n once(event, callback) {\n once.call(this, this.elements.container, event, callback);\n }\n /**\n * Remove event listeners\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n */\n off(event, callback) {\n off(this.elements.container, event, callback);\n }\n\n /**\n * Destroy an instance\n * Event listeners are removed when elements are removed\n * http://stackoverflow.com/questions/12528049/if-a-dom-element-is-removed-are-its-listeners-also-removed-from-memory\n * @param {function} callback - Callback for when destroy is complete\n * @param {boolean} soft - Whether it's a soft destroy (for source changes etc)\n */\n destroy(callback, soft = false) {\n if (!this.ready) {\n return;\n }\n\n const done = () => {\n // Reset overflow (incase destroyed while in fullscreen)\n document.body.style.overflow = '';\n\n // GC for embed\n this.embed = null;\n\n // If it's a soft destroy, make minimal changes\n if (soft) {\n if (Object.keys(this.elements).length) {\n // Remove elements\n removeElement(this.elements.buttons.play);\n removeElement(this.elements.captions);\n removeElement(this.elements.controls);\n removeElement(this.elements.wrapper);\n\n // Clear for GC\n this.elements.buttons.play = null;\n this.elements.captions = null;\n this.elements.controls = null;\n this.elements.wrapper = null;\n }\n\n // Callback\n if (is.function(callback)) {\n callback();\n }\n } else {\n // Unbind listeners\n unbindListeners.call(this);\n\n // Replace the container with the original element provided\n replaceElement(this.elements.original, this.elements.container);\n\n // Event\n triggerEvent.call(this, this.elements.original, 'destroyed', true);\n\n // Callback\n if (is.function(callback)) {\n callback.call(this.elements.original);\n }\n\n // Reset state\n this.ready = false;\n\n // Clear for garbage collection\n setTimeout(() => {\n this.elements = null;\n this.media = null;\n }, 200);\n }\n };\n\n // Stop playback\n this.stop();\n\n // Provider specific stuff\n if (this.isHTML5) {\n // Clear timeout\n clearTimeout(this.timers.loading);\n\n // Restore native video controls\n ui.toggleNativeControls.call(this, true);\n\n // Clean up\n done();\n } else if (this.isYouTube) {\n // Clear timers\n clearInterval(this.timers.buffering);\n clearInterval(this.timers.playing);\n\n // Destroy YouTube API\n if (this.embed !== null && is.function(this.embed.destroy)) {\n this.embed.destroy();\n }\n\n // Clean up\n done();\n } else if (this.isVimeo) {\n // Destroy Vimeo API\n // then clean up (wait, to prevent postmessage errors)\n if (this.embed !== null) {\n this.embed.unload().then(done);\n }\n\n // Vimeo does not always return\n setTimeout(done, 200);\n }\n }\n\n /**\n * Check for support for a mime type (HTML5 only)\n * @param {string} type - Mime type\n */\n supports(type) {\n return support.mime.call(this, type);\n }\n\n /**\n * Check for support\n * @param {string} type - Player type (audio/video)\n * @param {string} provider - Provider (html5/youtube/vimeo)\n * @param {bool} inline - Where player has `playsinline` sttribute\n */\n static supported(type, provider, inline) {\n return support.check(type, provider, inline);\n }\n\n /**\n * Load an SVG sprite into the page\n * @param {string} url - URL for the SVG sprite\n * @param {string} [id] - Unique ID\n */\n static loadSprite(url, id) {\n return loadSprite(url, id);\n }\n\n /**\n * Setup multiple instances\n * @param {*} selector\n * @param {object} options\n */\n static setup(selector, options = {}) {\n let targets = null;\n\n if (is.string(selector)) {\n targets = Array.from(document.querySelectorAll(selector));\n } else if (is.nodeList(selector)) {\n targets = Array.from(selector);\n } else if (is.array(selector)) {\n targets = selector.filter(is.element);\n }\n\n if (is.empty(targets)) {\n return null;\n }\n\n return targets.map(t => new Plyr(t, options));\n }\n}\n\nPlyr.defaults = cloneDeep(defaults);\n\nexport default Plyr;\n"]}
\ No newline at end of file +{"version":3,"sources":["src/js/utils/is.js","src/js/utils/events.js","src/js/utils/elements.js","src/js/utils/animation.js","src/js/utils/browser.js","src/js/support.js","src/js/html5.js","src/js/utils/objects.js","src/js/utils/strings.js","src/js/i18n.js","src/js/utils/arrays.js","src/js/storage.js","src/js/utils/fetch.js","src/js/utils/loadSprite.js","src/js/utils/time.js","src/js/controls.js","src/js/utils/urls.js","src/js/captions.js","src/js/config/defaults.js","src/js/config/types.js","src/js/console.js","src/js/fullscreen.js","src/js/utils/loadImage.js","src/js/ui.js","src/js/listeners.js","node_modules/loadjs/dist/loadjs.umd.js","src/js/utils/loadScript.js","src/js/plugins/vimeo.js","src/js/plugins/youtube.js","src/js/media.js","src/js/plugins/ads.js","src/js/source.js","src/js/plyr.js"],"names":["getConstructor","input","constructor","instanceOf","Boolean","is","object","Object","number","Number","isNaN","string","String","boolean","function","Function","array","nullOrUndefined","Array","isArray","weakMap","WeakMap","nodeList","NodeList","element","Element","textNode","Text","event","Event","cue","window","TextTrackCue","VTTCue","track","TextTrack","kind","url","test","empty","length","keys","supportsPassiveListeners","supported","options","defineProperty","get","addEventListener","removeEventListener","e","toggleListener","callback","toggle","passive","capture","events","split","forEach","eventListeners","push","type","on","call","off","once","onceCallback","args","apply","triggerEvent","bubbles","detail","CustomEvent","assign","plyr","dispatchEvent","unbindListeners","item","ready","Promise","setTimeout","resolve","elements","container","then","wrap","wrapper","targets","from","reverse","index","child","cloneNode","parent","parentNode","sibling","nextSibling","appendChild","insertBefore","setAttributes","attributes","entries","filter","value","key","setAttribute","createElement","text","document","innerText","insertAfter","target","insertElement","removeElement","removeChild","emptyElement","childNodes","lastChild","replaceElement","newChild","oldChild","replaceChild","getAttributesFromSelector","sel","existingAttributes","existing","selector","s","trim","className","replace","stripped","parts","start","charAt","class","id","toggleHidden","hidden","hide","hasAttribute","removeAttribute","toggleClass","force","method","classList","contains","hasClass","matches","prototype","match","querySelectorAll","includes","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","getElements","getElement","querySelector","getFocusElement","focused","activeElement","body","trapFocus","focusable","first","last","trap","keyCode","shiftKey","focus","preventDefault","transitionEndEvent","WebkitTransition","MozTransition","OTransition","transition","find","style","undefined","repaint","offsetHeight","browser","isIE","documentMode","isWebkit","documentElement","navigator","userAgent","isIPhone","platform","isIos","defaultCodecs","support","audio","video","check","provider","playsinline","canPlayInline","api","ui","rangeInput","pip","webkitSetPresentationMode","airplay","WebKitPlaybackTargetAvailabilityEvent","mime","inputType","mediaType","isHTML5","media","canPlayType","err","textTracks","range","touch","transitions","reducedMotion","matchMedia","html5","getSources","sources","source","getAttribute","getQualityOptions","map","extend","player","set","currentTime","playing","src","onLoadedMetaData","load","play","quality","cancelRequests","config","blankVideo","debug","log","cloneDeep","JSON","parse","stringify","getDeep","path","reduce","obj","shift","generateId","prefix","Math","floor","random","format","toString","i","getPercentage","current","max","toFixed","replaceAll","RegExp","toTitleCase","toUpperCase","substr","toLowerCase","toPascalCase","toCamelCase","slice","stripHTML","fragment","createDocumentFragment","innerHTML","firstChild","getHTML","i18n","seekTime","title","dedupe","indexOf","closest","prev","curr","abs","Storage","enabled","storage","store","localStorage","getItem","json","setItem","removeItem","fetch","responseType","reject","request","XMLHttpRequest","responseText","response","Error","status","open","send","loadSprite","hasId","isCached","exists","getElementById","update","data","insertAdjacentElement","useStorage","cached","content","result","catch","getHours","parseInt","getMinutes","getSeconds","formatTime","time","displayHours","inverted","hours","mins","secs","controls","getIconUrl","URL","iconUrl","location","cors","host","svg4everybody","findElements","selectors","buttons","pause","restart","rewind","fastForward","mute","settings","captions","fullscreen","progress","inputs","seek","volume","display","buffer","duration","seekTooltip","classNames","tooltip","error","warn","toggleNativeControls","createIcon","namespace","iconPath","iconPrefix","icon","createElementNS","role","use","setAttributeNS","createLabel","attr","universals","join","createBadge","badge","menu","createButton","buttonType","button","label","labelPressed","iconPressed","control","controlPressed","enumerable","pressed","createRange","min","step","autocomplete","updateRangeFill","createProgress","suffixKey","played","suffix","createTime","createMenuItem","list","checked","children","node","forceHours","updateTimeDisplay","updateVolume","setRange","muted","updateProgress","setProgress","getElementsByTagName","nodeValue","buffered","percent","setProperty","updateSeekTooltip","tooltips","clientRect","getBoundingClientRect","visible","width","pageX","left","parseFloat","timeUpdate","invert","invertTime","seeking","durationUpdate","hasDuration","displayDuration","paused","toggleMenuButton","setting","setQualityMenu","panels","console","checkMenu","getBadge","sort","a","b","sorting","getLabel","updateSetting","pane","currentTrack","default","setCaptionsMenu","tracks","getTracks","toggled","language","unshift","bind","setSpeedMenu","speed","isVimeo","values","some","toggleMenu","popup","show","isMenuItem","isButton","stopPropagation","getMenuSize","tab","clone","position","opacity","scrollWidth","height","scrollHeight","showMenuPanel","size","restore","propertyName","firstItem","create","inner","home","menuItem","flex","back","inject","props","seektime","insertAdjacentHTML","labels","parseUrl","safe","parser","href","buildUrlParams","params","URLSearchParams","setup","isVideo","isYouTube","hostname","protocol","createObjectURL","blob","languages","userLanguage","active","trackEvents","meta","currentTrackNode","languageExists","mode","updateCues","setLanguage","activeClass","findTrack","embed","enableTextTrack","has","sortIsDefault","sorted","every","getCurrentTrack","cues","activeCues","getCueAsHTML","cueText","changed","caption","defaults","autoplay","autopause","toggleInvert","ratio","clickToPlay","hideControls","resetOnEnd","disableContextMenu","loop","selected","keyboard","global","fallback","iosNative","seekLabel","unmute","enableCaptions","disableCaptions","enterFullscreen","exitFullscreen","frameTitle","menuBack","normal","end","all","reset","disabled","advertisement","qualityBadge","urls","vimeo","sdk","iframe","youtube","googleIMA","listeners","editable","embedContainer","poster","posterEnabled","ads","stopped","loading","hover","isTouch","uiSupported","noTransition","tabFocus","google","publisherId","providers","types","getProviderByUrl","noop","Console","onChange","toggleFallback","scrollPosition","x","scrollX","y","scrollY","scrollTo","overflow","Fullscreen","property","native","webkitEnterFullscreen","requestFullscreen","webkitExitFullscreen","cancelFullScreen","action","enter","exit","fullscreenElement","fullscreenEnabled","webkitFullscreenEnabled","mozFullScreenEnabled","msFullscreenEnabled","prefixes","pre","loadImage","minWidth","image","Image","handler","onload","onerror","naturalWidth","addStyleHook","build","checkPlaying","setTitle","setPoster","isEmbed","togglePoster","enable","backgroundImage","backgroundSize","toggleControls","checkLoading","clearTimeout","timers","Listeners","lastKey","handleKey","firstTouch","code","which","repeat","altKey","ctrlKey","metaKey","seekByKey","togglePlay","increaseVolume","decreaseVolume","forward","toggleCaptions","delay","hasAudio","initialized","managerPromise","isAudio","ended","proxyEvents","concat","inputEvent","proxy","defaultHandler","customHandlerKey","customHandler","hasCustomHandler","returned","showHomeTab","currentTarget","eventType","done","seekTo","webkitDirectionInvertedFromDevice","direction","deltaY","deltaX","define","this","loadScript","loadjs","success","parseId","regex","$2","getAspectRatio","getRatio","w","h","assurePlaybackState","hasPlayed","setAspectRatio","Vimeo","padding","paddingBottom","offset","transform","byline","portrait","transparent","gesture","thumbnail_large","pathname","Player","disableTextTrack","stop","restorePause","setVolume","setCurrentTime","setPlaybackRate","name","setLoop","currentSrc","getVideoUrl","getVideoWidth","getVideoHeight","dimensions","setAutopause","state","getVideoTitle","getCurrentTime","getDuration","getTextTracks","strippedCues","getPaused","frame","seconds","mapQualityUnit","qualities","hd2160","hd1440","hd1080","hd720","large","medium","small","tiny","entry","mapQualityUnits","levels","level","YT","onYouTubeReadyCallbacks","onYouTubeIframeAPIReady","getTitle","videoId","getVideoData","items","snippet","currentId","startsWith","posterSrc","playerVars","rel","showinfo","iv_load_policy","modestbranding","disablekb","widget_referrer","cc_load_policy","cc_lang_pref","onError","message","onPlaybackQualityChange","onPlaybackRateChange","instance","playbackRate","getPlaybackRate","onReady","playVideo","pauseVideo","stopVideo","getPlaybackQuality","setPlaybackQuality","getAvailablePlaybackRates","clearInterval","buffering","setInterval","getVideoLoadedFraction","lastBuffered","onStateChange","seeked","getAvailableQualityLevels","unMute","Ads","displayContainer","manager","loader","cuePoints","safetyTimer","countdownTimer","ima","trigger","startSafetyTimer","clearSafetyTimer","setupIMA","setVpaidMode","ImaSdkSettings","VpaidMode","ENABLED","setLocale","AdDisplayContainer","requestAds","AdsLoader","AdsManagerLoadedEvent","Type","ADS_MANAGER_LOADED","onAdsManagerLoaded","AdErrorEvent","AD_ERROR","onAdError","AdsRequest","adTagUrl","tagUrl","linearAdSlotWidth","offsetWidth","linearAdSlotHeight","nonLinearAdSlotWidth","nonLinearAdSlotHeight","forceNonLinearFullSlot","setAdWillPlayMuted","getRemainingTime","AdsRenderingSettings","restoreCustomPlaybackStateOnAdBreakComplete","enablePreloading","getAdsManager","getCuePoints","cuePoint","seekElement","cuePercentage","AdEvent","onAdEvent","ad","getAd","LOADED","pollCountdown","isLinear","ALL_ADS_COMPLETED","loadAds","CONTENT_PAUSE_REQUESTED","pauseContent","CONTENT_RESUME_REQUESTED","resumeContent","STARTED","MIDPOINT","COMPLETE","IMPRESSION","CLICK","cancel","contentComplete","seekedTime","discardAdBreak","splice","resize","ViewMode","NORMAL","initialize","init","adError","zIndex","destroy","handlers","AV_PUBLISHERID","AV_CHANNELID","AV_URL","cb","Date","now","AV_WIDTH","AV_HEIGHT","AV_CDIM2","base","insertElements","attribute","change","tagName","crossorigin","Plyr","failed","jQuery","original","searchParams","truthy","webkitShowPlaybackTargetPicker","isHidden","hiding","eventName","soft","unload","inputIsValid","fauxDuration","mozHasAudio","webkitAudioDecodedByteCount","audioTracks","states","inline","webkitPresentationMode","t"],"mappings":"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","file":"plyr.js","sourcesContent":["// ==========================================================================\n// Type checking utils\n// ==========================================================================\n\nconst getConstructor = input => (input !== null && typeof input !== 'undefined' ? input.constructor : null);\n\nconst instanceOf = (input, constructor) => Boolean(input && constructor && input instanceof constructor);\n\nconst is = {\n object(input) {\n return getConstructor(input) === Object;\n },\n number(input) {\n return getConstructor(input) === Number && !Number.isNaN(input);\n },\n string(input) {\n return getConstructor(input) === String;\n },\n boolean(input) {\n return getConstructor(input) === Boolean;\n },\n function(input) {\n return getConstructor(input) === Function;\n },\n array(input) {\n return !is.nullOrUndefined(input) && Array.isArray(input);\n },\n weakMap(input) {\n return instanceOf(input, WeakMap);\n },\n nodeList(input) {\n return instanceOf(input, NodeList);\n },\n element(input) {\n return instanceOf(input, Element);\n },\n textNode(input) {\n return getConstructor(input) === Text;\n },\n event(input) {\n return instanceOf(input, Event);\n },\n cue(input) {\n return instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue);\n },\n track(input) {\n return instanceOf(input, TextTrack) || (!is.nullOrUndefined(input) && is.string(input.kind));\n },\n url(input) {\n return (\n !is.nullOrUndefined(input) &&\n /(ftp|http|https):\\/\\/(\\w+:{0,1}\\w*@)?(\\S+)(:[0-9]+)?(\\/|\\/([\\w#!:.?+=&%@!\\-/]))?/.test(input)\n );\n },\n nullOrUndefined(input) {\n return input === null || typeof input === 'undefined';\n },\n empty(input) {\n return (\n is.nullOrUndefined(input) ||\n ((is.string(input) || is.array(input) || is.nodeList(input)) && !input.length) ||\n (is.object(input) && !Object.keys(input).length)\n );\n },\n};\n\nexport default is;\n","// ==========================================================================\n// Event utils\n// ==========================================================================\n\nimport is from './is';\n\n// Check for passive event listener support\n// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md\n// https://www.youtube.com/watch?v=NPM6172J22g\nconst supportsPassiveListeners = (() => {\n // Test via a getter in the options object to see if the passive property is accessed\n let supported = false;\n try {\n const options = Object.defineProperty({}, 'passive', {\n get() {\n supported = true;\n return null;\n },\n });\n window.addEventListener('test', null, options);\n window.removeEventListener('test', null, options);\n } catch (e) {\n // Do nothing\n }\n\n return supported;\n})();\n\n// Toggle event listener\nexport function toggleListener(element, event, callback, toggle = false, passive = true, capture = false) {\n // Bail if no element, event, or callback\n if (!element || !('addEventListener' in element) || is.empty(event) || !is.function(callback)) {\n return;\n }\n\n // Allow multiple events\n const events = event.split(' ');\n\n // Build options\n // Default to just the capture boolean for browsers with no passive listener support\n let options = capture;\n\n // If passive events listeners are supported\n if (supportsPassiveListeners) {\n options = {\n // Whether the listener can be passive (i.e. default never prevented)\n passive,\n // Whether the listener is a capturing listener or not\n capture,\n };\n }\n\n // If a single node is passed, bind the event listener\n events.forEach(type => {\n if (this && this.eventListeners && toggle) {\n // Cache event listener\n this.eventListeners.push({ element, type, callback, options });\n }\n\n element[toggle ? 'addEventListener' : 'removeEventListener'](type, callback, options);\n });\n}\n\n// Bind event handler\nexport function on(element, events = '', callback, passive = true, capture = false) {\n toggleListener.call(this, element, events, callback, true, passive, capture);\n}\n\n// Unbind event handler\nexport function off(element, events = '', callback, passive = true, capture = false) {\n toggleListener.call(this, element, events, callback, false, passive, capture);\n}\n\n// Bind once-only event handler\nexport function once(element, events = '', callback, passive = true, capture = false) {\n function onceCallback(...args) {\n off(element, events, onceCallback, passive, capture);\n callback.apply(this, args);\n }\n\n toggleListener.call(this, element, events, onceCallback, true, passive, capture);\n}\n\n// Trigger event\nexport function triggerEvent(element, type = '', bubbles = false, detail = {}) {\n // Bail if no element\n if (!is.element(element) || is.empty(type)) {\n return;\n }\n\n // Create and dispatch the event\n const event = new CustomEvent(type, {\n bubbles,\n detail: Object.assign({}, detail, {\n plyr: this,\n }),\n });\n\n // Dispatch the event\n element.dispatchEvent(event);\n}\n\n// Unbind all cached event listeners\nexport function unbindListeners() {\n if (this && this.eventListeners) {\n this.eventListeners.forEach(item => {\n const { element, type, callback, options } = item;\n element.removeEventListener(type, callback, options);\n });\n\n this.eventListeners = [];\n }\n}\n\n// Run method when / if player is ready\nexport function ready() {\n return new Promise(\n resolve => (this.ready ? setTimeout(resolve, 0) : on.call(this, this.elements.container, 'ready', resolve)),\n ).then(() => {});\n}\n","// ==========================================================================\n// Element utils\n// ==========================================================================\n\nimport { toggleListener } from './events';\nimport is from './is';\n\n// Wrap an element\nexport function wrap(elements, wrapper) {\n // Convert `elements` to an array, if necessary.\n const targets = elements.length ? elements : [elements];\n\n // Loops backwards to prevent having to clone the wrapper on the\n // first element (see `child` below).\n Array.from(targets)\n .reverse()\n .forEach((element, index) => {\n const child = index > 0 ? wrapper.cloneNode(true) : wrapper;\n\n // Cache the current parent and sibling.\n const parent = element.parentNode;\n const sibling = element.nextSibling;\n\n // Wrap the element (is automatically removed from its current\n // parent).\n child.appendChild(element);\n\n // If the element had a sibling, insert the wrapper before\n // the sibling to maintain the HTML structure; otherwise, just\n // append it to the parent.\n if (sibling) {\n parent.insertBefore(child, sibling);\n } else {\n parent.appendChild(child);\n }\n });\n}\n\n// Set attributes\nexport function setAttributes(element, attributes) {\n if (!is.element(element) || is.empty(attributes)) {\n return;\n }\n\n // Assume null and undefined attributes should be left out,\n // Setting them would otherwise convert them to \"null\" and \"undefined\"\n Object.entries(attributes)\n .filter(([, value]) => !is.nullOrUndefined(value))\n .forEach(([key, value]) => element.setAttribute(key, value));\n}\n\n// Create a DocumentFragment\nexport function createElement(type, attributes, text) {\n // Create a new <element>\n const element = document.createElement(type);\n\n // Set all passed attributes\n if (is.object(attributes)) {\n setAttributes(element, attributes);\n }\n\n // Add text node\n if (is.string(text)) {\n element.innerText = text;\n }\n\n // Return built element\n return element;\n}\n\n// Inaert an element after another\nexport function insertAfter(element, target) {\n if (!is.element(element) || !is.element(target)) {\n return;\n }\n\n target.parentNode.insertBefore(element, target.nextSibling);\n}\n\n// Insert a DocumentFragment\nexport function insertElement(type, parent, attributes, text) {\n if (!is.element(parent)) {\n return;\n }\n\n parent.appendChild(createElement(type, attributes, text));\n}\n\n// Remove element(s)\nexport function removeElement(element) {\n if (is.nodeList(element) || is.array(element)) {\n Array.from(element).forEach(removeElement);\n return;\n }\n\n if (!is.element(element) || !is.element(element.parentNode)) {\n return;\n }\n\n element.parentNode.removeChild(element);\n}\n\n// Remove all child elements\nexport function emptyElement(element) {\n if (!is.element(element)) {\n return;\n }\n\n let { length } = element.childNodes;\n\n while (length > 0) {\n element.removeChild(element.lastChild);\n length -= 1;\n }\n}\n\n// Replace element\nexport function replaceElement(newChild, oldChild) {\n if (!is.element(oldChild) || !is.element(oldChild.parentNode) || !is.element(newChild)) {\n return null;\n }\n\n oldChild.parentNode.replaceChild(newChild, oldChild);\n\n return newChild;\n}\n\n// Get an attribute object from a string selector\nexport function getAttributesFromSelector(sel, existingAttributes) {\n // For example:\n // '.test' to { class: 'test' }\n // '#test' to { id: 'test' }\n // '[data-test=\"test\"]' to { 'data-test': 'test' }\n\n if (!is.string(sel) || is.empty(sel)) {\n return {};\n }\n\n const attributes = {};\n const existing = existingAttributes;\n\n sel.split(',').forEach(s => {\n // Remove whitespace\n const selector = s.trim();\n const className = selector.replace('.', '');\n const stripped = selector.replace(/[[\\]]/g, '');\n\n // Get the parts and value\n const parts = stripped.split('=');\n const key = parts[0];\n const value = parts.length > 1 ? parts[1].replace(/[\"']/g, '') : '';\n\n // Get the first character\n const start = selector.charAt(0);\n\n switch (start) {\n case '.':\n // Add to existing classname\n if (is.object(existing) && is.string(existing.class)) {\n existing.class += ` ${className}`;\n }\n\n attributes.class = className;\n break;\n\n case '#':\n // ID selector\n attributes.id = selector.replace('#', '');\n break;\n\n case '[':\n // Attribute selector\n attributes[key] = value;\n\n break;\n\n default:\n break;\n }\n });\n\n return attributes;\n}\n\n// Toggle hidden\nexport function toggleHidden(element, hidden) {\n if (!is.element(element)) {\n return;\n }\n\n let hide = hidden;\n\n if (!is.boolean(hide)) {\n hide = !element.hasAttribute('hidden');\n }\n\n if (hide) {\n element.setAttribute('hidden', '');\n } else {\n element.removeAttribute('hidden');\n }\n}\n\n// Mirror Element.classList.toggle, with IE compatibility for \"force\" argument\nexport function toggleClass(element, className, force) {\n if (is.element(element)) {\n let method = 'toggle';\n if (typeof force !== 'undefined') {\n method = force ? 'add' : 'remove';\n }\n\n element.classList[method](className);\n return element.classList.contains(className);\n }\n\n return null;\n}\n\n// Has class name\nexport function hasClass(element, className) {\n return is.element(element) && element.classList.contains(className);\n}\n\n// Element matches selector\nexport function matches(element, selector) {\n const prototype = { Element };\n\n function match() {\n return Array.from(document.querySelectorAll(selector)).includes(this);\n }\n\n const matches =\n prototype.matches ||\n prototype.webkitMatchesSelector ||\n prototype.mozMatchesSelector ||\n prototype.msMatchesSelector ||\n match;\n\n return matches.call(element, selector);\n}\n\n// Find all elements\nexport function getElements(selector) {\n return this.elements.container.querySelectorAll(selector);\n}\n\n// Find a single element\nexport function getElement(selector) {\n return this.elements.container.querySelector(selector);\n}\n\n// Get the focused element\nexport function getFocusElement() {\n let focused = document.activeElement;\n\n if (!focused || focused === document.body) {\n focused = null;\n } else {\n focused = document.querySelector(':focus');\n }\n\n return focused;\n}\n\n// Trap focus inside container\nexport function trapFocus(element = null, toggle = false) {\n if (!is.element(element)) {\n return;\n }\n\n const focusable = getElements.call(this, 'button:not(:disabled), input:not(:disabled), [tabindex]');\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n const trap = event => {\n // Bail if not tab key or not fullscreen\n if (event.key !== 'Tab' || event.keyCode !== 9) {\n return;\n }\n\n // Get the current focused element\n const focused = getFocusElement();\n\n if (focused === last && !event.shiftKey) {\n // Move focus to first element that can be tabbed if Shift isn't used\n first.focus();\n event.preventDefault();\n } else if (focused === first && event.shiftKey) {\n // Move focus to last element that can be tabbed if Shift is used\n last.focus();\n event.preventDefault();\n }\n };\n\n toggleListener.call(this, this.elements.container, 'keydown', trap, toggle, false);\n}\n","// ==========================================================================\n// Animation utils\n// ==========================================================================\n\nimport { toggleHidden } from './elements';\nimport is from './is';\n\nexport const transitionEndEvent = (() => {\n const element = document.createElement('span');\n\n const events = {\n WebkitTransition: 'webkitTransitionEnd',\n MozTransition: 'transitionend',\n OTransition: 'oTransitionEnd otransitionend',\n transition: 'transitionend',\n };\n\n const type = Object.keys(events).find(event => element.style[event] !== undefined);\n\n return is.string(type) ? events[type] : false;\n})();\n\n// Force repaint of element\nexport function repaint(element) {\n setTimeout(() => {\n toggleHidden(element, true);\n element.offsetHeight; // eslint-disable-line\n toggleHidden(element, false);\n }, 0);\n}\n","// ==========================================================================\n// Browser sniffing\n// Unfortunately, due to mixed support, UA sniffing is required\n// ==========================================================================\n\nconst browser = {\n isIE: /* @cc_on!@ */ false || !!document.documentMode,\n isWebkit: 'WebkitAppearance' in document.documentElement.style && !/Edge/.test(navigator.userAgent),\n isIPhone: /(iPhone|iPod)/gi.test(navigator.platform),\n isIos: /(iPad|iPhone|iPod)/gi.test(navigator.platform),\n};\n\nexport default browser;\n","// ==========================================================================\n// Plyr support checks\n// ==========================================================================\n\nimport { transitionEndEvent } from './utils/animation';\nimport browser from './utils/browser';\nimport { createElement } from './utils/elements';\nimport is from './utils/is';\n\n// Default codecs for checking mimetype support\nconst defaultCodecs = {\n 'audio/ogg': 'vorbis',\n 'audio/wav': '1',\n 'video/webm': 'vp8, vorbis',\n 'video/mp4': 'avc1.42E01E, mp4a.40.2',\n 'video/ogg': 'theora',\n};\n\n// Check for feature support\nconst support = {\n // Basic support\n audio: 'canPlayType' in document.createElement('audio'),\n video: 'canPlayType' in document.createElement('video'),\n\n // Check for support\n // Basic functionality vs full UI\n check(type, provider, playsinline) {\n const canPlayInline = browser.isIPhone && playsinline && support.playsinline;\n const api = support[type] || provider !== 'html5';\n const ui = api && support.rangeInput && (type !== 'video' || !browser.isIPhone || canPlayInline);\n\n return {\n api,\n ui,\n };\n },\n\n // Picture-in-picture support\n // Safari only currently\n pip: (() => !browser.isIPhone && is.function(createElement('video').webkitSetPresentationMode))(),\n\n // Airplay support\n // Safari only currently\n airplay: is.function(window.WebKitPlaybackTargetAvailabilityEvent),\n\n // Inline playback support\n // https://webkit.org/blog/6784/new-video-policies-for-ios/\n playsinline: 'playsInline' in document.createElement('video'),\n\n // Check for mime type support against a player instance\n // Credits: http://diveintohtml5.info/everything.html\n // Related: http://www.leanbackplayer.com/test/h5mt.html\n mime(inputType) {\n const [mediaType] = inputType.split('/');\n if (!this.isHTML5 || mediaType !== this.type) {\n return false;\n }\n\n let type;\n if (inputType && inputType.includes('codecs=')) {\n // Use input directly\n type = inputType;\n } else if (inputType === 'audio/mpeg') {\n // Skip codec\n type = 'audio/mpeg;';\n } else if (inputType in defaultCodecs) {\n // Use codec\n type = `${inputType}; codecs=\"${defaultCodecs[inputType]}\"`;\n }\n\n try {\n return Boolean(type && this.media.canPlayType(type).replace(/no/, ''));\n } catch (err) {\n return false;\n }\n },\n\n // Check for textTracks support\n textTracks: 'textTracks' in document.createElement('video'),\n\n // <input type=\"range\"> Sliders\n rangeInput: (() => {\n const range = document.createElement('input');\n range.type = 'range';\n return range.type === 'range';\n })(),\n\n // Touch\n // NOTE: Remember a device can be mouse + touch enabled so we check on first touch event\n touch: 'ontouchstart' in document.documentElement,\n\n // Detect transitions support\n transitions: transitionEndEvent !== false,\n\n // Reduced motion iOS & MacOS setting\n // https://webkit.org/blog/7551/responsive-design-for-motion/\n reducedMotion: 'matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches,\n};\n\nexport default support;\n","// ==========================================================================\n// Plyr HTML5 helpers\n// ==========================================================================\n\nimport support from './support';\nimport { removeElement } from './utils/elements';\nimport { triggerEvent } from './utils/events';\n\nconst html5 = {\n getSources() {\n if (!this.isHTML5) {\n return [];\n }\n\n const sources = Array.from(this.media.querySelectorAll('source'));\n\n // Filter out unsupported sources\n return sources.filter(source => support.mime.call(this, source.getAttribute('type')));\n },\n\n // Get quality levels\n getQualityOptions() {\n // Get sizes from <source> elements\n return html5.getSources\n .call(this)\n .map(source => Number(source.getAttribute('size')))\n .filter(Boolean);\n },\n\n extend() {\n if (!this.isHTML5) {\n return;\n }\n\n const player = this;\n\n // Quality\n Object.defineProperty(player.media, 'quality', {\n get() {\n // Get sources\n const sources = html5.getSources.call(player);\n const [source] = sources.filter(source => source.getAttribute('src') === player.source);\n\n // Return size, if match is found\n return source && Number(source.getAttribute('size'));\n },\n set(input) {\n // Get sources\n const sources = html5.getSources.call(player);\n\n // Get first match for requested size\n const source = sources.find(source => Number(source.getAttribute('size')) === input);\n\n // No matching source found\n if (!source) {\n return;\n }\n\n // Get current state\n const { currentTime, playing } = player;\n\n // Set new source\n player.media.src = source.getAttribute('src');\n\n // Restore time\n const onLoadedMetaData = () => {\n player.currentTime = currentTime;\n };\n player.once('loadedmetadata', onLoadedMetaData);\n\n // Load new source\n player.media.load();\n\n // Resume playing\n if (playing) {\n player.play();\n }\n\n // Trigger change event\n triggerEvent.call(player, player.media, 'qualitychange', false, {\n quality: input,\n });\n },\n });\n },\n\n // Cancel current network requests\n // See https://github.com/sampotts/plyr/issues/174\n cancelRequests() {\n if (!this.isHTML5) {\n return;\n }\n\n // Remove child sources\n removeElement(html5.getSources.call(this));\n\n // Set blank video src attribute\n // This is to prevent a MEDIA_ERR_SRC_NOT_SUPPORTED error\n // Info: http://stackoverflow.com/questions/32231579/how-to-properly-dispose-of-an-html5-video-and-close-socket-or-connection\n this.media.setAttribute('src', this.config.blankVideo);\n\n // Load the new empty source\n // This will cancel existing requests\n // See https://github.com/sampotts/plyr/issues/174\n this.media.load();\n\n // Debugging\n this.debug.log('Cancelled network requests');\n },\n};\n\nexport default html5;\n","// ==========================================================================\n// Object utils\n// ==========================================================================\n\nimport is from './is';\n\n// Clone nested objects\nexport function cloneDeep(object) {\n return JSON.parse(JSON.stringify(object));\n}\n\n// Get a nested value in an object\nexport function getDeep(object, path) {\n return path.split('.').reduce((obj, key) => obj && obj[key], object);\n}\n\n// Deep extend destination object with N more objects\nexport function extend(target = {}, ...sources) {\n if (!sources.length) {\n return target;\n }\n\n const source = sources.shift();\n\n if (!is.object(source)) {\n return target;\n }\n\n Object.keys(source).forEach(key => {\n if (is.object(source[key])) {\n if (!Object.keys(target).includes(key)) {\n Object.assign(target, { [key]: {} });\n }\n\n extend(target[key], source[key]);\n } else {\n Object.assign(target, { [key]: source[key] });\n }\n });\n\n return extend(target, ...sources);\n}\n","// ==========================================================================\n// String utils\n// ==========================================================================\n\nimport is from './is';\n\n// Generate a random ID\nexport function generateId(prefix) {\n return `${prefix}-${Math.floor(Math.random() * 10000)}`;\n}\n\n// Format string\nexport function format(input, ...args) {\n if (is.empty(input)) {\n return input;\n }\n\n return input.toString().replace(/{(\\d+)}/g, (match, i) => args[i].toString());\n}\n\n// Get percentage\nexport function getPercentage(current, max) {\n if (current === 0 || max === 0 || Number.isNaN(current) || Number.isNaN(max)) {\n return 0;\n }\n\n return (current / max * 100).toFixed(2);\n}\n\n// Replace all occurances of a string in a string\nexport function replaceAll(input = '', find = '', replace = '') {\n return input.replace(\n new RegExp(find.toString().replace(/([.*+?^=!:${}()|[\\]/\\\\])/g, '\\\\$1'), 'g'),\n replace.toString(),\n );\n}\n\n// Convert to title case\nexport function toTitleCase(input = '') {\n return input.toString().replace(/\\w\\S*/g, text => text.charAt(0).toUpperCase() + text.substr(1).toLowerCase());\n}\n\n// Convert string to pascalCase\nexport function toPascalCase(input = '') {\n let string = input.toString();\n\n // Convert kebab case\n string = replaceAll(string, '-', ' ');\n\n // Convert snake case\n string = replaceAll(string, '_', ' ');\n\n // Convert to title case\n string = toTitleCase(string);\n\n // Convert to pascal case\n return replaceAll(string, ' ', '');\n}\n\n// Convert string to pascalCase\nexport function toCamelCase(input = '') {\n let string = input.toString();\n\n // Convert to pascal case\n string = toPascalCase(string);\n\n // Convert first character to lowercase\n return string.charAt(0).toLowerCase() + string.slice(1);\n}\n\n// Remove HTML from a string\nexport function stripHTML(source) {\n const fragment = document.createDocumentFragment();\n const element = document.createElement('div');\n fragment.appendChild(element);\n element.innerHTML = source;\n return fragment.firstChild.innerText;\n}\n\n// Like outerHTML, but also works for DocumentFragment\nexport function getHTML(element) {\n const wrapper = document.createElement('div');\n wrapper.appendChild(element);\n return wrapper.innerHTML;\n}\n","// ==========================================================================\n// Plyr internationalization\n// ==========================================================================\n\nimport is from './utils/is';\nimport { getDeep } from './utils/objects';\nimport { replaceAll } from './utils/strings';\n\nconst i18n = {\n get(key = '', config = {}) {\n if (is.empty(key) || is.empty(config)) {\n return '';\n }\n\n let string = getDeep(config.i18n, key);\n\n if (is.empty(string)) {\n return '';\n }\n\n const replace = {\n '{seektime}': config.seekTime,\n '{title}': config.title,\n };\n\n Object.entries(replace).forEach(([key, value]) => {\n string = replaceAll(string, key, value);\n });\n\n return string;\n },\n};\n\nexport default i18n;\n","// ==========================================================================\n// Array utils\n// ==========================================================================\n\nimport is from './is';\n\n// Remove duplicates in an array\nexport function dedupe(array) {\n if (!is.array(array)) {\n return array;\n }\n\n return array.filter((item, index) => array.indexOf(item) === index);\n}\n\n// Get the closest value in an array\nexport function closest(array, value) {\n if (!is.array(array) || !array.length) {\n return null;\n }\n\n return array.reduce((prev, curr) => (Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev));\n}\n","// ==========================================================================\n// Plyr storage\n// ==========================================================================\n\nimport is from './utils/is';\nimport { extend } from './utils/objects';\n\nclass Storage {\n constructor(player) {\n this.enabled = player.config.storage.enabled;\n this.key = player.config.storage.key;\n }\n\n // Check for actual support (see if we can use it)\n static get supported() {\n try {\n if (!('localStorage' in window)) {\n return false;\n }\n\n const test = '___test';\n\n // Try to use it (it might be disabled, e.g. user is in private mode)\n // see: https://github.com/sampotts/plyr/issues/131\n window.localStorage.setItem(test, test);\n window.localStorage.removeItem(test);\n\n return true;\n } catch (e) {\n return false;\n }\n }\n\n get(key) {\n if (!Storage.supported || !this.enabled) {\n return null;\n }\n\n const store = window.localStorage.getItem(this.key);\n\n if (is.empty(store)) {\n return null;\n }\n\n const json = JSON.parse(store);\n\n return is.string(key) && key.length ? json[key] : json;\n }\n\n set(object) {\n // Bail if we don't have localStorage support or it's disabled\n if (!Storage.supported || !this.enabled) {\n return;\n }\n\n // Can only store objectst\n if (!is.object(object)) {\n return;\n }\n\n // Get current storage\n let storage = this.get();\n\n // Default to empty object\n if (is.empty(storage)) {\n storage = {};\n }\n\n // Update the working copy of the values\n extend(storage, object);\n\n // Update storage\n window.localStorage.setItem(this.key, JSON.stringify(storage));\n }\n}\n\nexport default Storage;\n","// ==========================================================================\n// Fetch wrapper\n// Using XHR to avoid issues with older browsers\n// ==========================================================================\n\nexport default function fetch(url, responseType = 'text') {\n return new Promise((resolve, reject) => {\n try {\n const request = new XMLHttpRequest();\n\n // Check for CORS support\n if (!('withCredentials' in request)) {\n return;\n }\n\n request.addEventListener('load', () => {\n if (responseType === 'text') {\n try {\n resolve(JSON.parse(request.responseText));\n } catch (e) {\n resolve(request.responseText);\n }\n } else {\n resolve(request.response);\n }\n });\n\n request.addEventListener('error', () => {\n throw new Error(request.status);\n });\n\n request.open('GET', url, true);\n\n // Set the required response type\n request.responseType = responseType;\n\n request.send();\n } catch (e) {\n reject(e);\n }\n });\n}\n","// ==========================================================================\n// Sprite loader\n// ==========================================================================\n\nimport Storage from './../storage';\nimport fetch from './fetch';\nimport is from './is';\n\n// Load an external SVG sprite\nexport default function loadSprite(url, id) {\n if (!is.string(url)) {\n return;\n }\n\n const prefix = 'cache';\n const hasId = is.string(id);\n let isCached = false;\n\n const exists = () => document.getElementById(id) !== null;\n\n const update = (container, data) => {\n container.innerHTML = data;\n\n // Check again incase of race condition\n if (hasId && exists()) {\n return;\n }\n\n // Inject the SVG to the body\n document.body.insertAdjacentElement('afterbegin', container);\n };\n\n // Only load once if ID set\n if (!hasId || !exists()) {\n const useStorage = Storage.supported;\n\n // Create container\n const container = document.createElement('div');\n container.setAttribute('hidden', '');\n\n if (hasId) {\n container.setAttribute('id', id);\n }\n\n // Check in cache\n if (useStorage) {\n const cached = window.localStorage.getItem(`${prefix}-${id}`);\n isCached = cached !== null;\n\n if (isCached) {\n const data = JSON.parse(cached);\n update(container, data.content);\n }\n }\n\n // Get the sprite\n fetch(url)\n .then(result => {\n if (is.empty(result)) {\n return;\n }\n\n if (useStorage) {\n window.localStorage.setItem(\n `${prefix}-${id}`,\n JSON.stringify({\n content: result,\n }),\n );\n }\n\n update(container, result);\n })\n .catch(() => {});\n }\n}\n","// ==========================================================================\n// Time utils\n// ==========================================================================\n\nimport is from './is';\n\n// Time helpers\nexport const getHours = value => parseInt((value / 60 / 60) % 60, 10);\nexport const getMinutes = value => parseInt((value / 60) % 60, 10);\nexport const getSeconds = value => parseInt(value % 60, 10);\n\n// Format time to UI friendly string\nexport function formatTime(time = 0, displayHours = false, inverted = false) {\n // Bail if the value isn't a number\n if (!is.number(time)) {\n return formatTime(null, displayHours, inverted);\n }\n\n // Format time component to add leading zero\n const format = value => `0${value}`.slice(-2);\n\n // Breakdown to hours, mins, secs\n let hours = getHours(time);\n const mins = getMinutes(time);\n const secs = getSeconds(time);\n\n // Do we need to display hours?\n if (displayHours || hours > 0) {\n hours = `${hours}:`;\n } else {\n hours = '';\n }\n\n // Render\n return `${inverted && time > 0 ? '-' : ''}${hours}${format(mins)}:${format(secs)}`;\n}\n","// ==========================================================================\n// Plyr controls\n// ==========================================================================\n\nimport captions from './captions';\nimport html5 from './html5';\nimport i18n from './i18n';\nimport support from './support';\nimport { repaint, transitionEndEvent } from './utils/animation';\nimport { dedupe } from './utils/arrays';\nimport browser from './utils/browser';\nimport { createElement, emptyElement, getAttributesFromSelector, getElement, getElements, hasClass, matches, removeElement, setAttributes, toggleClass, toggleHidden } from './utils/elements';\nimport { off, on } from './utils/events';\nimport is from './utils/is';\nimport loadSprite from './utils/loadSprite';\nimport { extend } from './utils/objects';\nimport { getPercentage, replaceAll, toCamelCase, toTitleCase } from './utils/strings';\nimport { formatTime, getHours } from './utils/time';\n\n// TODO: Don't export a massive object - break down and create class\nconst controls = {\n // Get icon URL\n getIconUrl() {\n const url = new URL(this.config.iconUrl, window.location);\n const cors = url.host !== window.location.host || (browser.isIE && !window.svg4everybody);\n\n return {\n url: this.config.iconUrl,\n cors,\n };\n },\n\n // Find the UI controls\n findElements() {\n try {\n this.elements.controls = getElement.call(this, this.config.selectors.controls.wrapper);\n\n // Buttons\n this.elements.buttons = {\n play: getElements.call(this, this.config.selectors.buttons.play),\n pause: getElement.call(this, this.config.selectors.buttons.pause),\n restart: getElement.call(this, this.config.selectors.buttons.restart),\n rewind: getElement.call(this, this.config.selectors.buttons.rewind),\n fastForward: getElement.call(this, this.config.selectors.buttons.fastForward),\n mute: getElement.call(this, this.config.selectors.buttons.mute),\n pip: getElement.call(this, this.config.selectors.buttons.pip),\n airplay: getElement.call(this, this.config.selectors.buttons.airplay),\n settings: getElement.call(this, this.config.selectors.buttons.settings),\n captions: getElement.call(this, this.config.selectors.buttons.captions),\n fullscreen: getElement.call(this, this.config.selectors.buttons.fullscreen),\n };\n\n // Progress\n this.elements.progress = getElement.call(this, this.config.selectors.progress);\n\n // Inputs\n this.elements.inputs = {\n seek: getElement.call(this, this.config.selectors.inputs.seek),\n volume: getElement.call(this, this.config.selectors.inputs.volume),\n };\n\n // Display\n this.elements.display = {\n buffer: getElement.call(this, this.config.selectors.display.buffer),\n currentTime: getElement.call(this, this.config.selectors.display.currentTime),\n duration: getElement.call(this, this.config.selectors.display.duration),\n };\n\n // Seek tooltip\n if (is.element(this.elements.progress)) {\n this.elements.display.seekTooltip = this.elements.progress.querySelector(\n `.${this.config.classNames.tooltip}`,\n );\n }\n\n return true;\n } catch (error) {\n // Log it\n this.debug.warn('It looks like there is a problem with your custom controls HTML', error);\n\n // Restore native video controls\n this.toggleNativeControls(true);\n\n return false;\n }\n },\n\n // Create <svg> icon\n createIcon(type, attributes) {\n const namespace = 'http://www.w3.org/2000/svg';\n const iconUrl = controls.getIconUrl.call(this);\n const iconPath = `${!iconUrl.cors ? iconUrl.url : ''}#${this.config.iconPrefix}`;\n\n // Create <svg>\n const icon = document.createElementNS(namespace, 'svg');\n setAttributes(\n icon,\n extend(attributes, {\n role: 'presentation',\n focusable: 'false',\n }),\n );\n\n // Create the <use> to reference sprite\n const use = document.createElementNS(namespace, 'use');\n const path = `${iconPath}-${type}`;\n\n // Set `href` attributes\n // https://github.com/sampotts/plyr/issues/460\n // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href\n if ('href' in use) {\n use.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);\n } else {\n use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', path);\n }\n\n // Add <use> to <svg>\n icon.appendChild(use);\n\n return icon;\n },\n\n // Create hidden text label\n createLabel(type, attr = {}) {\n // Skip i18n for abbreviations and brand names\n const universals = {\n pip: 'PIP',\n airplay: 'AirPlay',\n };\n const text = universals[type] || i18n.get(type, this.config);\n\n const attributes = Object.assign({}, attr, {\n class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' '),\n });\n return createElement('span', attributes, text);\n },\n\n // Create a badge\n createBadge(text) {\n if (is.empty(text)) {\n return null;\n }\n\n const badge = createElement('span', {\n class: this.config.classNames.menu.value,\n });\n\n badge.appendChild(\n createElement(\n 'span',\n {\n class: this.config.classNames.menu.badge,\n },\n text,\n ),\n );\n\n return badge;\n },\n\n // Create a <button>\n createButton(buttonType, attr) {\n const button = createElement('button');\n const attributes = Object.assign({}, attr);\n let type = toCamelCase(buttonType);\n\n let toggle = false;\n let label;\n let icon;\n let labelPressed;\n let iconPressed;\n\n if (!('type' in attributes)) {\n attributes.type = 'button';\n }\n\n if ('class' in attributes) {\n if (attributes.class.includes(this.config.classNames.control)) {\n attributes.class += ` ${this.config.classNames.control}`;\n }\n } else {\n attributes.class = this.config.classNames.control;\n }\n\n // Large play button\n switch (buttonType) {\n case 'play':\n toggle = true;\n label = 'play';\n labelPressed = 'pause';\n icon = 'play';\n iconPressed = 'pause';\n break;\n\n case 'mute':\n toggle = true;\n label = 'mute';\n labelPressed = 'unmute';\n icon = 'volume';\n iconPressed = 'muted';\n break;\n\n case 'captions':\n toggle = true;\n label = 'enableCaptions';\n labelPressed = 'disableCaptions';\n icon = 'captions-off';\n iconPressed = 'captions-on';\n break;\n\n case 'fullscreen':\n toggle = true;\n label = 'enterFullscreen';\n labelPressed = 'exitFullscreen';\n icon = 'enter-fullscreen';\n iconPressed = 'exit-fullscreen';\n break;\n\n case 'play-large':\n attributes.class += ` ${this.config.classNames.control}--overlaid`;\n type = 'play';\n label = 'play';\n icon = 'play';\n break;\n\n default:\n label = type;\n icon = buttonType;\n }\n\n // Setup toggle icon and labels\n if (toggle) {\n // Icon\n button.appendChild(controls.createIcon.call(this, iconPressed, { class: 'icon--pressed' }));\n button.appendChild(controls.createIcon.call(this, icon, { class: 'icon--not-pressed' }));\n\n // Label/Tooltip\n button.appendChild(controls.createLabel.call(this, labelPressed, { class: 'label--pressed' }));\n button.appendChild(controls.createLabel.call(this, label, { class: 'label--not-pressed' }));\n } else {\n button.appendChild(controls.createIcon.call(this, icon));\n button.appendChild(controls.createLabel.call(this, label));\n }\n\n // Merge attributes\n extend(attributes, getAttributesFromSelector(this.config.selectors.buttons[type], attributes));\n\n setAttributes(button, attributes);\n\n // We have multiple play buttons\n if (type === 'play') {\n if (!is.array(this.elements.buttons[type])) {\n this.elements.buttons[type] = [];\n }\n\n this.elements.buttons[type].push(button);\n } else {\n this.elements.buttons[type] = button;\n }\n\n // Toggle classname when pressed property is set\n const className = this.config.classNames.controlPressed;\n Object.defineProperty(button, 'pressed', {\n enumerable: true,\n get() {\n return hasClass(button, className);\n },\n set(pressed = false) {\n toggleClass(button, className, pressed);\n },\n });\n\n return button;\n },\n\n // Create an <input type='range'>\n createRange(type, attributes) {\n // Seek input\n const input = createElement(\n 'input',\n extend(\n getAttributesFromSelector(this.config.selectors.inputs[type]),\n {\n type: 'range',\n min: 0,\n max: 100,\n step: 0.01,\n value: 0,\n autocomplete: 'off',\n // A11y fixes for https://github.com/sampotts/plyr/issues/905\n role: 'slider',\n 'aria-label': i18n.get(type, this.config),\n 'aria-valuemin': 0,\n 'aria-valuemax': 100,\n 'aria-valuenow': 0,\n },\n attributes,\n ),\n );\n\n this.elements.inputs[type] = input;\n\n // Set the fill for webkit now\n controls.updateRangeFill.call(this, input);\n\n return input;\n },\n\n // Create a <progress>\n createProgress(type, attributes) {\n const progress = createElement(\n 'progress',\n extend(\n getAttributesFromSelector(this.config.selectors.display[type]),\n {\n min: 0,\n max: 100,\n value: 0,\n role: 'presentation',\n 'aria-hidden': true,\n },\n attributes,\n ),\n );\n\n // Create the label inside\n if (type !== 'volume') {\n progress.appendChild(createElement('span', null, '0'));\n\n const suffixKey = {\n played: 'played',\n buffer: 'buffered',\n }[type];\n const suffix = suffixKey ? i18n.get(suffixKey, this.config) : '';\n\n progress.innerText = `% ${suffix.toLowerCase()}`;\n }\n\n this.elements.display[type] = progress;\n\n return progress;\n },\n\n // Create time display\n createTime(type) {\n const attributes = getAttributesFromSelector(this.config.selectors.display[type]);\n\n const container = createElement(\n 'div',\n extend(attributes, {\n class: `${this.config.classNames.display.time} ${attributes.class ? attributes.class : ''}`.trim(),\n 'aria-label': i18n.get(type, this.config),\n }),\n '00:00',\n );\n\n // Reference for updates\n this.elements.display[type] = container;\n\n return container;\n },\n\n // Create a settings menu item\n createMenuItem({ value, list, type, title, badge = null, checked = false }) {\n const attributes = getAttributesFromSelector(this.config.selectors.inputs[type]);\n\n const item = createElement(\n 'button',\n extend(attributes, {\n type: 'button',\n role: 'menuitemradio',\n class: `${this.config.classNames.control} ${attributes.class ? attributes.class : ''}`.trim(),\n value,\n 'aria-checked': checked,\n })\n );\n\n // We have to set as HTML incase of special characters\n item.innerHTML = title;\n\n if (is.element(badge)) {\n item.appendChild(badge);\n }\n\n Object.defineProperty(item, 'checked', {\n enumerable: true,\n get() {\n return item.getAttribute('aria-checked') === 'true';\n },\n set(checked) {\n // Ensure exclusivity\n if (checked) {\n Array.from(item.parentNode.children)\n .filter(node => matches(node, '[role=\"menuitemradio\"]'))\n .forEach(node => node.setAttribute('aria-checked', 'false'));\n }\n\n item.setAttribute('aria-checked', checked ? 'true' : 'false');\n },\n });\n\n list.appendChild(item);\n },\n\n // Format a time for display\n formatTime(time = 0, inverted = false) {\n // Bail if the value isn't a number\n if (!is.number(time)) {\n return time;\n }\n\n // Always display hours if duration is over an hour\n const forceHours = getHours(this.duration) > 0;\n\n return formatTime(time, forceHours, inverted);\n },\n\n // Update the displayed time\n updateTimeDisplay(target = null, time = 0, inverted = false) {\n // Bail if there's no element to display or the value isn't a number\n if (!is.element(target) || !is.number(time)) {\n return;\n }\n\n // eslint-disable-next-line no-param-reassign\n target.innerText = controls.formatTime(time, inverted);\n },\n\n // Update volume UI and storage\n updateVolume() {\n if (!this.supported.ui) {\n return;\n }\n\n // Update range\n if (is.element(this.elements.inputs.volume)) {\n controls.setRange.call(this, this.elements.inputs.volume, this.muted ? 0 : this.volume);\n }\n\n // Update mute state\n if (is.element(this.elements.buttons.mute)) {\n this.elements.buttons.mute.pressed = this.muted || this.volume === 0;\n }\n },\n\n // Update seek value and lower fill\n setRange(target, value = 0) {\n if (!is.element(target)) {\n return;\n }\n\n // eslint-disable-next-line\n target.value = value;\n\n // Webkit range fill\n controls.updateRangeFill.call(this, target);\n },\n\n // Update <progress> elements\n updateProgress(event) {\n if (!this.supported.ui || !is.event(event)) {\n return;\n }\n\n let value = 0;\n\n const setProgress = (target, input) => {\n const value = is.number(input) ? input : 0;\n const progress = is.element(target) ? target : this.elements.display.buffer;\n\n // Update value and label\n if (is.element(progress)) {\n progress.value = value;\n\n // Update text label inside\n const label = progress.getElementsByTagName('span')[0];\n if (is.element(label)) {\n label.childNodes[0].nodeValue = value;\n }\n }\n };\n\n if (event) {\n switch (event.type) {\n // Video playing\n case 'timeupdate':\n case 'seeking':\n case 'seeked':\n value = getPercentage(this.currentTime, this.duration);\n\n // Set seek range value only if it's a 'natural' time event\n if (event.type === 'timeupdate') {\n controls.setRange.call(this, this.elements.inputs.seek, value);\n }\n\n break;\n\n // Check buffer status\n case 'playing':\n case 'progress':\n setProgress(this.elements.display.buffer, this.buffered * 100);\n\n break;\n\n default:\n break;\n }\n }\n },\n\n // Webkit polyfill for lower fill range\n updateRangeFill(target) {\n // Get range from event if event passed\n const range = is.event(target) ? target.target : target;\n\n // Needs to be a valid <input type='range'>\n if (!is.element(range) || range.getAttribute('type') !== 'range') {\n return;\n }\n\n // Set aria values for https://github.com/sampotts/plyr/issues/905\n if (matches(range, this.config.selectors.inputs.seek)) {\n range.setAttribute('aria-valuenow', this.currentTime);\n const currentTime = controls.formatTime(this.currentTime);\n const duration = controls.formatTime(this.duration);\n const format = i18n.get('seekLabel', this.config);\n range.setAttribute(\n 'aria-valuetext',\n format.replace('{currentTime}', currentTime).replace('{duration}', duration),\n );\n } else if (matches(range, this.config.selectors.inputs.volume)) {\n const percent = range.value * 100;\n range.setAttribute('aria-valuenow', percent);\n range.setAttribute('aria-valuetext', `${percent}%`);\n } else {\n range.setAttribute('aria-valuenow', range.value);\n }\n\n // WebKit only\n if (!browser.isWebkit) {\n return;\n }\n\n // Set CSS custom property\n range.style.setProperty('--value', `${range.value / range.max * 100}%`);\n },\n\n // Update hover tooltip for seeking\n updateSeekTooltip(event) {\n // Bail if setting not true\n if (\n !this.config.tooltips.seek ||\n !is.element(this.elements.inputs.seek) ||\n !is.element(this.elements.display.seekTooltip) ||\n this.duration === 0\n ) {\n return;\n }\n\n // Calculate percentage\n let percent = 0;\n const clientRect = this.elements.progress.getBoundingClientRect();\n const visible = `${this.config.classNames.tooltip}--visible`;\n\n const toggle = toggle => {\n toggleClass(this.elements.display.seekTooltip, visible, toggle);\n };\n\n // Hide on touch\n if (this.touch) {\n toggle(false);\n return;\n }\n\n // Determine percentage, if already visible\n if (is.event(event)) {\n percent = 100 / clientRect.width * (event.pageX - clientRect.left);\n } else if (hasClass(this.elements.display.seekTooltip, visible)) {\n percent = parseFloat(this.elements.display.seekTooltip.style.left, 10);\n } else {\n return;\n }\n\n // Set bounds\n if (percent < 0) {\n percent = 0;\n } else if (percent > 100) {\n percent = 100;\n }\n\n // Display the time a click would seek to\n controls.updateTimeDisplay.call(this, this.elements.display.seekTooltip, this.duration / 100 * percent);\n\n // Set position\n this.elements.display.seekTooltip.style.left = `${percent}%`;\n\n // Show/hide the tooltip\n // If the event is a moues in/out and percentage is inside bounds\n if (is.event(event) && ['mouseenter', 'mouseleave'].includes(event.type)) {\n toggle(event.type === 'mouseenter');\n }\n },\n\n // Handle time change event\n timeUpdate(event) {\n // Only invert if only one time element is displayed and used for both duration and currentTime\n const invert = !is.element(this.elements.display.duration) && this.config.invertTime;\n\n // Duration\n controls.updateTimeDisplay.call(\n this,\n this.elements.display.currentTime,\n invert ? this.duration - this.currentTime : this.currentTime,\n invert,\n );\n\n // Ignore updates while seeking\n if (event && event.type === 'timeupdate' && this.media.seeking) {\n return;\n }\n\n // Playing progress\n controls.updateProgress.call(this, event);\n },\n\n // Show the duration on metadataloaded or durationchange events\n durationUpdate() {\n // Bail if no UI or durationchange event triggered after playing/seek when invertTime is false\n if (!this.supported.ui || (!this.config.invertTime && this.currentTime)) {\n return;\n }\n\n // Update ARIA values\n if (is.element(this.elements.inputs.seek)) {\n this.elements.inputs.seek.setAttribute('aria-valuemax', this.duration);\n }\n\n // If there's a spot to display duration\n const hasDuration = is.element(this.elements.display.duration);\n\n // If there's only one time display, display duration there\n if (!hasDuration && this.config.displayDuration && this.paused) {\n controls.updateTimeDisplay.call(this, this.elements.display.currentTime, this.duration);\n }\n\n // If there's a duration element, update content\n if (hasDuration) {\n controls.updateTimeDisplay.call(this, this.elements.display.duration, this.duration);\n }\n\n // Update the tooltip (if visible)\n controls.updateSeekTooltip.call(this);\n },\n\n // Hide/show a tab\n toggleMenuButton(setting, toggle) {\n toggleHidden(this.elements.settings.buttons[setting], !toggle);\n },\n\n // Set the quality menu\n setQualityMenu(options) {\n // Menu required\n if (!is.element(this.elements.settings.panels.quality)) {\n console.warn('Not an element');\n return;\n }\n\n const type = 'quality';\n const list = this.elements.settings.panels.quality.querySelector('[role=\"menu\"]');\n\n // Set options if passed and filter based on uniqueness and config\n if (is.array(options)) {\n this.options.quality = dedupe(options).filter(quality => this.config.quality.options.includes(quality));\n }\n\n // Toggle the pane and tab\n console.warn(this.options.quality);\n const toggle = !is.empty(this.options.quality) && this.options.quality.length > 1;\n controls.toggleMenuButton.call(this, type, toggle);\n\n // Check if we need to toggle the parent\n controls.checkMenu.call(this);\n\n // If we're hiding, nothing more to do\n if (!toggle) {\n return;\n }\n\n // Empty the menu\n emptyElement(list);\n\n // Get the badge HTML for HD, 4K etc\n const getBadge = quality => {\n const label = i18n.get(`qualityBadge.${quality}`, this.config);\n\n if (!label.length) {\n return null;\n }\n\n return controls.createBadge.call(this, label);\n };\n\n // Sort options by the config and then render options\n this.options.quality\n .sort((a, b) => {\n const sorting = this.config.quality.options;\n return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;\n })\n .forEach(quality => {\n controls.createMenuItem.call(this, {\n value: quality,\n list,\n type,\n title: controls.getLabel.call(this, 'quality', quality),\n badge: getBadge(quality),\n });\n });\n\n controls.updateSetting.call(this, type, list);\n },\n\n // Translate a value into a nice label\n getLabel(setting, value) {\n switch (setting) {\n case 'speed':\n return value === 1 ? i18n.get('normal', this.config) : `${value}×`;\n\n case 'quality':\n if (is.number(value)) {\n const label = i18n.get(`qualityLabel.${value}`, this.config);\n\n if (!label.length) {\n return `${value}p`;\n }\n\n return label;\n }\n\n return toTitleCase(value);\n\n case 'captions':\n return captions.getLabel.call(this);\n\n default:\n return null;\n }\n },\n\n // Update the selected setting\n updateSetting(setting, container, input) {\n const pane = this.elements.settings.panels[setting];\n let value = null;\n let list = container;\n\n if (setting === 'captions') {\n value = this.currentTrack;\n } else {\n value = !is.empty(input) ? input : this[setting];\n\n // Get default\n if (is.empty(value)) {\n value = this.config[setting].default;\n }\n\n // Unsupported value\n if (!is.empty(this.options[setting]) && !this.options[setting].includes(value)) {\n this.debug.warn(`Unsupported value of '${value}' for ${setting}`);\n return;\n }\n\n // Disabled value\n if (!this.config[setting].options.includes(value)) {\n this.debug.warn(`Disabled value of '${value}' for ${setting}`);\n return;\n }\n }\n\n // Get the list if we need to\n if (!is.element(list)) {\n list = pane && pane.querySelector('[role=\"menu\"]');\n }\n\n // If there's no list it means it's not been rendered...\n if (!is.element(list)) {\n return;\n }\n\n // Update the label\n const label = this.elements.settings.buttons[setting].querySelector(`.${this.config.classNames.menu.value}`);\n label.innerHTML = controls.getLabel.call(this, setting, value);\n\n // Find the radio option and check it\n const target = list && list.querySelector(`[value=\"${value}\"]`);\n\n if (is.element(target)) {\n target.checked = true;\n }\n },\n\n // Set the looping options\n /* setLoopMenu() {\n // Menu required\n if (!is.element(this.elements.settings.panels.loop)) {\n return;\n }\n\n const options = ['start', 'end', 'all', 'reset'];\n const list = this.elements.settings.panels.loop.querySelector('[role=\"menu\"]');\n\n // Show the pane and tab\n toggleHidden(this.elements.settings.buttons.loop, false);\n toggleHidden(this.elements.settings.panels.loop, false);\n\n // Toggle the pane and tab\n const toggle = !is.empty(this.loop.options);\n controls.toggleMenuButton.call(this, 'loop', toggle);\n\n // Empty the menu\n emptyElement(list);\n\n options.forEach(option => {\n const item = createElement('li');\n\n const button = createElement(\n 'button',\n extend(getAttributesFromSelector(this.config.selectors.buttons.loop), {\n type: 'button',\n class: this.config.classNames.control,\n 'data-plyr-loop-action': option,\n }),\n i18n.get(option, this.config)\n );\n\n if (['start', 'end'].includes(option)) {\n const badge = controls.createBadge.call(this, '00:00');\n button.appendChild(badge);\n }\n\n item.appendChild(button);\n list.appendChild(item);\n });\n }, */\n\n // Get current selected caption language\n // TODO: rework this to user the getter in the API?\n\n // Set a list of available captions languages\n setCaptionsMenu() {\n // TODO: Captions or language? Currently it's mixed\n const type = 'captions';\n const list = this.elements.settings.panels.captions.querySelector('[role=\"menu\"]');\n const tracks = captions.getTracks.call(this);\n\n // Toggle the pane and tab\n controls.toggleMenuButton.call(this, type, tracks.length);\n\n // Empty the menu\n emptyElement(list);\n\n // Check if we need to toggle the parent\n controls.checkMenu.call(this);\n\n // If there's no captions, bail\n if (!tracks.length) {\n return;\n }\n\n // Generate options data\n const options = tracks.map((track, value) => ({\n value,\n checked: this.captions.toggled && this.currentTrack === value,\n title: captions.getLabel.call(this, track),\n badge: track.language && controls.createBadge.call(this, track.language.toUpperCase()),\n list,\n type: 'language',\n }));\n\n // Add the \"Disabled\" option to turn off captions\n options.unshift({\n value: -1,\n checked: !this.captions.toggled,\n title: i18n.get('disabled', this.config),\n list,\n type: 'language',\n });\n\n // Generate options\n options.forEach(controls.createMenuItem.bind(this));\n\n controls.updateSetting.call(this, type, list);\n },\n\n // Set a list of available captions languages\n setSpeedMenu(options) {\n // Do nothing if not selected\n if (!this.config.controls.includes('settings') || !this.config.settings.includes('speed')) {\n return;\n }\n\n // Menu required\n if (!is.element(this.elements.settings.panels.speed)) {\n return;\n }\n\n const type = 'speed';\n\n // Set the speed options\n if (is.array(options)) {\n this.options.speed = options;\n } else if (this.isHTML5 || this.isVimeo) {\n this.options.speed = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];\n }\n\n // Set options if passed and filter based on config\n this.options.speed = this.options.speed.filter(speed => this.config.speed.options.includes(speed));\n\n // Toggle the pane and tab\n const toggle = !is.empty(this.options.speed) && this.options.speed.length > 1;\n controls.toggleMenuButton.call(this, type, toggle);\n\n // Check if we need to toggle the parent\n controls.checkMenu.call(this);\n\n // If we're hiding, nothing more to do\n if (!toggle) {\n return;\n }\n\n // Get the list to populate\n const list = this.elements.settings.panels.speed.querySelector('[role=\"menu\"]');\n\n // Empty the menu\n emptyElement(list);\n\n // Create items\n this.options.speed.forEach(speed => {\n controls.createMenuItem.call(this, {\n value: speed,\n list,\n type,\n title: controls.getLabel.call(this, 'speed', speed),\n });\n });\n\n controls.updateSetting.call(this, type, list);\n },\n\n // Check if we need to hide/show the settings menu\n checkMenu() {\n const { buttons } = this.elements.settings;\n const visible = !is.empty(buttons) && Object.values(buttons).some(button => !button.hidden);\n\n toggleHidden(this.elements.settings.menu, !visible);\n },\n\n // Show/hide menu\n toggleMenu(event) {\n const { popup } = this.elements.settings;\n const button = this.elements.buttons.settings;\n\n // Menu and button are required\n if (!is.element(popup) || !is.element(button)) {\n return;\n }\n\n const show = is.boolean(event) ? event : is.element(popup) && popup.hasAttribute('hidden');\n\n if (is.event(event)) {\n const isMenuItem = is.element(popup) && popup.contains(event.target);\n const isButton = event.target === this.elements.buttons.settings;\n\n // If the click was inside the form or if the click\n // wasn't the button or menu item and we're trying to\n // show the menu (a doc click shouldn't show the menu)\n if (isMenuItem || (!isMenuItem && !isButton && show)) {\n return;\n }\n\n // Prevent the toggle being caught by the doc listener\n if (isButton) {\n event.stopPropagation();\n }\n }\n\n // Set form and button attributes\n if (is.element(button)) {\n button.setAttribute('aria-expanded', show);\n }\n\n if (is.element(popup)) {\n toggleHidden(popup, !show);\n toggleClass(this.elements.container, this.config.classNames.menu.open, show);\n\n if (show) {\n popup.removeAttribute('tabindex');\n } else {\n popup.setAttribute('tabindex', -1);\n }\n }\n },\n\n // Get the natural size of a menu panel\n getMenuSize(tab) {\n const clone = tab.cloneNode(true);\n clone.style.position = 'absolute';\n clone.style.opacity = 0;\n clone.removeAttribute('hidden');\n\n // Append to parent so we get the \"real\" size\n tab.parentNode.appendChild(clone);\n\n // Get the sizes before we remove\n const width = clone.scrollWidth;\n const height = clone.scrollHeight;\n\n // Remove from the DOM\n removeElement(clone);\n\n return {\n width,\n height,\n };\n },\n\n // Show a panel in the menu\n showMenuPanel(type = '') {\n const target = document.getElementById(`plyr-settings-${this.id}-${type}`);\n\n // Nothing to show, bail\n if (!is.element(target)) {\n return;\n }\n\n // Hide all other panels\n const container = target.parentNode;\n const current = Array.from(container.children).find(node => !node.hidden);\n\n // If we can do fancy animations, we'll animate the height/width\n if (support.transitions && !support.reducedMotion) {\n // Set the current width as a base\n container.style.width = `${current.scrollWidth}px`;\n container.style.height = `${current.scrollHeight}px`;\n\n // Get potential sizes\n const size = controls.getMenuSize.call(this, target);\n\n // Restore auto height/width\n const restore = event => {\n // We're only bothered about height and width on the container\n if (event.target !== container || !['width', 'height'].includes(event.propertyName)) {\n return;\n }\n\n // Revert back to auto\n container.style.width = '';\n container.style.height = '';\n\n // Only listen once\n off.call(this, container, transitionEndEvent, restore);\n };\n\n // Listen for the transition finishing and restore auto height/width\n on.call(this, container, transitionEndEvent, restore);\n\n // Set dimensions to target\n container.style.width = `${size.width}px`;\n container.style.height = `${size.height}px`;\n }\n\n // Set attributes on current tab\n toggleHidden(current, true);\n // current.setAttribute('tabindex', -1);\n\n // Set attributes on target\n toggleHidden(target, false);\n\n // Focus the first item\n const firstItem = target.querySelector('[role^=\"menuitem\"]');\n if (firstItem) {\n firstItem.focus();\n }\n },\n\n // Build the default HTML\n // TODO: Set order based on order in the config.controls array?\n create(data) {\n // Do nothing if we want no controls\n if (is.empty(this.config.controls)) {\n return null;\n }\n\n // Create the container\n const container = createElement('div', getAttributesFromSelector(this.config.selectors.controls.wrapper));\n\n // Restart button\n if (this.config.controls.includes('restart')) {\n container.appendChild(controls.createButton.call(this, 'restart'));\n }\n\n // Rewind button\n if (this.config.controls.includes('rewind')) {\n container.appendChild(controls.createButton.call(this, 'rewind'));\n }\n\n // Play/Pause button\n if (this.config.controls.includes('play')) {\n container.appendChild(controls.createButton.call(this, 'play'));\n }\n\n // Fast forward button\n if (this.config.controls.includes('fast-forward')) {\n container.appendChild(controls.createButton.call(this, 'fast-forward'));\n }\n\n // Progress\n if (this.config.controls.includes('progress')) {\n const progress = createElement('div', getAttributesFromSelector(this.config.selectors.progress));\n\n // Seek range slider\n progress.appendChild(\n controls.createRange.call(this, 'seek', {\n id: `plyr-seek-${data.id}`,\n }),\n );\n\n // Buffer progress\n progress.appendChild(controls.createProgress.call(this, 'buffer'));\n\n // TODO: Add loop display indicator\n\n // Seek tooltip\n if (this.config.tooltips.seek) {\n const tooltip = createElement(\n 'span',\n {\n class: this.config.classNames.tooltip,\n },\n '00:00',\n );\n\n progress.appendChild(tooltip);\n this.elements.display.seekTooltip = tooltip;\n }\n\n this.elements.progress = progress;\n container.appendChild(this.elements.progress);\n }\n\n // Media current time display\n if (this.config.controls.includes('current-time')) {\n container.appendChild(controls.createTime.call(this, 'currentTime'));\n }\n\n // Media duration display\n if (this.config.controls.includes('duration')) {\n container.appendChild(controls.createTime.call(this, 'duration'));\n }\n\n // Toggle mute button\n if (this.config.controls.includes('mute')) {\n container.appendChild(controls.createButton.call(this, 'mute'));\n }\n\n // Volume range control\n if (this.config.controls.includes('volume')) {\n const volume = createElement('div', {\n class: 'plyr__volume',\n });\n\n // Set the attributes\n const attributes = {\n max: 1,\n step: 0.05,\n value: this.config.volume,\n };\n\n // Create the volume range slider\n volume.appendChild(\n controls.createRange.call(\n this,\n 'volume',\n extend(attributes, {\n id: `plyr-volume-${data.id}`,\n }),\n ),\n );\n\n this.elements.volume = volume;\n\n container.appendChild(volume);\n }\n\n // Toggle captions button\n if (this.config.controls.includes('captions')) {\n container.appendChild(controls.createButton.call(this, 'captions'));\n }\n\n // Settings button / menu\n if (this.config.controls.includes('settings') && !is.empty(this.config.settings)) {\n const control = createElement('div', {\n class: 'plyr__menu',\n hidden: '',\n });\n\n control.appendChild(\n controls.createButton.call(this, 'settings', {\n id: `plyr-settings-toggle-${data.id}`,\n 'aria-haspopup': true,\n 'aria-controls': `plyr-settings-${data.id}`,\n 'aria-expanded': false,\n }),\n );\n\n const popup = createElement('div', {\n class: 'plyr__menu__container',\n id: `plyr-settings-${data.id}`,\n hidden: '',\n 'aria-labelled-by': `plyr-settings-toggle-${data.id}`,\n });\n\n const inner = createElement('div');\n\n const home = createElement('div', {\n id: `plyr-settings-${data.id}-home`,\n });\n\n // Create the menu\n const menu = createElement('div', {\n role: 'menu',\n });\n\n // Build the menu items\n this.config.settings.forEach(type => {\n const menuItem = createElement(\n 'button',\n extend(getAttributesFromSelector(this.config.selectors.buttons.settings), {\n type: 'button',\n class: `${this.config.classNames.control} ${this.config.classNames.control}--forward`,\n role: 'menuitem',\n 'aria-haspopup': true,\n }),\n );\n\n const flex = createElement('span', null, i18n.get(type, this.config));\n\n const value = createElement('span', {\n class: this.config.classNames.menu.value,\n });\n\n // Speed contains HTML entities\n value.innerHTML = data[type];\n\n flex.appendChild(value);\n menuItem.appendChild(flex);\n menu.appendChild(menuItem);\n\n // Build the panes\n const pane = createElement('div', {\n id: `plyr-settings-${data.id}-${type}`,\n hidden: '',\n });\n\n // Back button\n const back = createElement(\n 'button',\n {\n type: 'button',\n class: `${this.config.classNames.control} ${this.config.classNames.control}--back`,\n },\n i18n.get(type, this.config),\n );\n back.addEventListener('click', () => {\n controls.showMenuPanel.call(this, 'home');\n });\n pane.appendChild(back);\n\n // Menu\n pane.appendChild(\n createElement('div', {\n role: 'menu',\n }),\n );\n\n inner.appendChild(pane);\n\n menuItem.addEventListener('click', () => {\n controls.showMenuPanel.call(this, type);\n });\n\n this.elements.settings.buttons[type] = menuItem;\n this.elements.settings.panels[type] = pane;\n });\n\n home.appendChild(menu);\n inner.appendChild(home);\n\n popup.appendChild(inner);\n control.appendChild(popup);\n container.appendChild(control);\n\n this.elements.settings.popup = popup;\n this.elements.settings.menu = control;\n }\n\n // Picture in picture button\n if (this.config.controls.includes('pip') && support.pip) {\n container.appendChild(controls.createButton.call(this, 'pip'));\n }\n\n // Airplay button\n if (this.config.controls.includes('airplay') && support.airplay) {\n container.appendChild(controls.createButton.call(this, 'airplay'));\n }\n\n // Toggle fullscreen button\n if (this.config.controls.includes('fullscreen')) {\n container.appendChild(controls.createButton.call(this, 'fullscreen'));\n }\n\n // Larger overlaid play button\n if (this.config.controls.includes('play-large')) {\n this.elements.container.appendChild(controls.createButton.call(this, 'play-large'));\n }\n\n this.elements.controls = container;\n\n if (this.isHTML5) {\n controls.setQualityMenu.call(this, html5.getQualityOptions.call(this));\n }\n\n controls.setSpeedMenu.call(this);\n\n return container;\n },\n\n // Insert controls\n inject() {\n // Sprite\n if (this.config.loadSprite) {\n const icon = controls.getIconUrl.call(this);\n\n // Only load external sprite using AJAX\n if (icon.cors) {\n loadSprite(icon.url, 'sprite-plyr');\n }\n }\n\n // Create a unique ID\n this.id = Math.floor(Math.random() * 10000);\n\n // Null by default\n let container = null;\n this.elements.controls = null;\n\n // Set template properties\n const props = {\n id: this.id,\n seektime: this.config.seekTime,\n title: this.config.title,\n };\n let update = true;\n\n if (is.string(this.config.controls) || is.element(this.config.controls)) {\n // String or HTMLElement passed as the option\n container = this.config.controls;\n } else if (is.function(this.config.controls)) {\n // A custom function to build controls\n // The function can return a HTMLElement or String\n container = this.config.controls.call(this, props);\n } else {\n // Create controls\n container = controls.create.call(this, {\n id: this.id,\n seektime: this.config.seekTime,\n speed: this.speed,\n quality: this.quality,\n captions: captions.getLabel.call(this),\n // TODO: Looping\n // loop: 'None',\n });\n update = false;\n }\n\n // Replace props with their value\n const replace = input => {\n let result = input;\n\n Object.entries(props).forEach(([key, value]) => {\n result = replaceAll(result, `{${key}}`, value);\n });\n\n return result;\n };\n\n // Update markup\n if (update) {\n if (is.string(this.config.controls)) {\n container = replace(container);\n } else if (is.element(container)) {\n container.innerHTML = replace(container.innerHTML);\n }\n }\n\n // Controls container\n let target;\n\n // Inject to custom location\n if (is.string(this.config.selectors.controls.container)) {\n target = document.querySelector(this.config.selectors.controls.container);\n }\n\n // Inject into the container by default\n if (!is.element(target)) {\n target = this.elements.container;\n }\n\n // Inject controls HTML\n if (is.element(container)) {\n target.appendChild(container);\n } else if (container) {\n target.insertAdjacentHTML('beforeend', container);\n }\n\n // Find the elements if need be\n if (!is.element(this.elements.controls)) {\n controls.findElements.call(this);\n }\n\n // Edge sometimes doesn't finish the paint so force a redraw\n if (window.navigator.userAgent.includes('Edge')) {\n repaint(target);\n }\n\n // Setup tooltips\n if (this.config.tooltips.controls) {\n const { classNames, selectors } = this.config;\n const selector = `${selectors.controls.wrapper} ${selectors.labels} .${classNames.hidden}`;\n const labels = getElements.call(this, selector);\n\n Array.from(labels).forEach(label => {\n toggleClass(label, this.config.classNames.hidden, false);\n toggleClass(label, this.config.classNames.tooltip, true);\n });\n }\n },\n};\n\nexport default controls;\n","// ==========================================================================\n// URL utils\n// ==========================================================================\n\nimport is from './is';\n\n/**\n * Parse a string to a URL object\n * @param {string} input - the URL to be parsed\n * @param {boolean} safe - failsafe parsing\n */\nexport function parseUrl(input, safe = true) {\n let url = input;\n\n if (safe) {\n const parser = document.createElement('a');\n parser.href = url;\n url = parser.href;\n }\n\n try {\n return new URL(url);\n } catch (e) {\n return null;\n }\n}\n\n// Convert object to URLSearchParams\nexport function buildUrlParams(input) {\n const params = new URLSearchParams();\n\n if (is.object(input)) {\n Object.entries(input).forEach(([key, value]) => {\n params.set(key, value);\n });\n }\n\n return params;\n}\n","// ==========================================================================\n// Plyr Captions\n// TODO: Create as class\n// ==========================================================================\n\nimport controls from './controls';\nimport i18n from './i18n';\nimport support from './support';\nimport { dedupe } from './utils/arrays';\nimport browser from './utils/browser';\nimport {\n createElement,\n emptyElement,\n getAttributesFromSelector,\n insertAfter,\n removeElement,\n toggleClass,\n} from './utils/elements';\nimport { on, triggerEvent } from './utils/events';\nimport fetch from './utils/fetch';\nimport is from './utils/is';\nimport { getHTML } from './utils/strings';\nimport { parseUrl } from './utils/urls';\n\nconst captions = {\n // Setup captions\n setup() {\n // Requires UI support\n if (!this.supported.ui) {\n return;\n }\n\n // Only Vimeo and HTML5 video supported at this point\n if (!this.isVideo || this.isYouTube || (this.isHTML5 && !support.textTracks)) {\n // Clear menu and hide\n if (\n is.array(this.config.controls) &&\n this.config.controls.includes('settings') &&\n this.config.settings.includes('captions')\n ) {\n controls.setCaptionsMenu.call(this);\n }\n\n return;\n }\n\n // Inject the container\n if (!is.element(this.elements.captions)) {\n this.elements.captions = createElement('div', getAttributesFromSelector(this.config.selectors.captions));\n\n insertAfter(this.elements.captions, this.elements.wrapper);\n }\n\n // Fix IE captions if CORS is used\n // Fetch captions and inject as blobs instead (data URIs not supported!)\n if (browser.isIE && window.URL) {\n const elements = this.media.querySelectorAll('track');\n\n Array.from(elements).forEach(track => {\n const src = track.getAttribute('src');\n const url = parseUrl(src);\n\n if (\n url !== null &&\n url.hostname !== window.location.href.hostname &&\n ['http:', 'https:'].includes(url.protocol)\n ) {\n fetch(src, 'blob')\n .then(blob => {\n track.setAttribute('src', window.URL.createObjectURL(blob));\n })\n .catch(() => {\n removeElement(track);\n });\n }\n });\n }\n\n // Get and set initial data\n // The \"preferred\" options are not realized unless / until the wanted language has a match\n // * languages: Array of user's browser languages.\n // * language: The language preferred by user settings or config\n // * active: The state preferred by user settings or config\n // * toggled: The real captions state\n\n const languages = dedupe(\n Array.from(navigator.languages || navigator.userLanguage).map(language => language.split('-')[0]),\n );\n\n let language = (this.storage.get('language') || this.config.captions.language || 'auto').toLowerCase();\n\n // Use first browser language when language is 'auto'\n if (language === 'auto') {\n [language] = languages;\n }\n\n let active = this.storage.get('captions');\n if (!is.boolean(active)) {\n ({ active } = this.config.captions);\n }\n\n Object.assign(this.captions, {\n toggled: false,\n active,\n language,\n languages,\n });\n\n // Watch changes to textTracks and update captions menu\n if (this.isHTML5) {\n const trackEvents = this.config.captions.update ? 'addtrack removetrack' : 'removetrack';\n on.call(this, this.media.textTracks, trackEvents, captions.update.bind(this));\n }\n\n // Update available languages in list next tick (the event must not be triggered before the listeners)\n setTimeout(captions.update.bind(this), 0);\n },\n\n // Update available language options in settings based on tracks\n update() {\n const tracks = captions.getTracks.call(this, true);\n // Get the wanted language\n const { active, language, meta, currentTrackNode } = this.captions;\n const languageExists = Boolean(tracks.find(track => track.language === language));\n\n // Handle tracks (add event listener and \"pseudo\"-default)\n if (this.isHTML5 && this.isVideo) {\n tracks.filter(track => !meta.get(track)).forEach(track => {\n this.debug.log('Track added', track);\n // Attempt to store if the original dom element was \"default\"\n meta.set(track, {\n default: track.mode === 'showing',\n });\n\n // Turn off native caption rendering to avoid double captions\n track.mode = 'hidden';\n\n // Add event listener for cue changes\n on.call(this, track, 'cuechange', () => captions.updateCues.call(this));\n });\n }\n\n // Update language first time it matches, or if the previous matching track was removed\n if ((languageExists && this.language !== language) || !tracks.includes(currentTrackNode)) {\n captions.setLanguage.call(this, language);\n captions.toggle.call(this, active && languageExists);\n }\n\n // Enable or disable captions based on track length\n toggleClass(this.elements.container, this.config.classNames.captions.enabled, !is.empty(tracks));\n\n // Update available languages in list\n if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) {\n controls.setCaptionsMenu.call(this);\n }\n },\n\n // Toggle captions display\n // Used internally for the toggleCaptions method, with the passive option forced to false\n toggle(input, passive = true) {\n // If there's no full support\n if (!this.supported.ui) {\n return;\n }\n\n const { toggled } = this.captions; // Current state\n const activeClass = this.config.classNames.captions.active;\n\n // Get the next state\n // If the method is called without parameter, toggle based on current value\n const active = is.nullOrUndefined(input) ? !toggled : input;\n\n // Update state and trigger event\n if (active !== toggled) {\n // When passive, don't override user preferences\n if (!passive) {\n this.captions.active = active;\n this.storage.set({ captions: active });\n }\n\n // Force language if the call isn't passive and there is no matching language to toggle to\n if (!this.language && active && !passive) {\n const tracks = captions.getTracks.call(this);\n const track = captions.findTrack.call(this, [this.captions.language, ...this.captions.languages], true);\n\n // Override user preferences to avoid switching languages if a matching track is added\n this.captions.language = track.language;\n\n // Set caption, but don't store in localStorage as user preference\n captions.set.call(this, tracks.indexOf(track));\n return;\n }\n\n // Toggle state\n this.elements.buttons.captions.pressed = active;\n\n // Add class hook\n toggleClass(this.elements.container, activeClass, active);\n\n this.captions.toggled = active;\n\n // Update settings menu\n controls.updateSetting.call(this, 'captions');\n\n // Trigger event (not used internally)\n triggerEvent.call(this, this.media, active ? 'captionsenabled' : 'captionsdisabled');\n }\n },\n\n // Set captions by track index\n // Used internally for the currentTrack setter with the passive option forced to false\n set(index, passive = true) {\n const tracks = captions.getTracks.call(this);\n\n // Disable captions if setting to -1\n if (index === -1) {\n captions.toggle.call(this, false, passive);\n return;\n }\n\n if (!is.number(index)) {\n this.debug.warn('Invalid caption argument', index);\n return;\n }\n\n if (!(index in tracks)) {\n this.debug.warn('Track not found', index);\n return;\n }\n\n if (this.captions.currentTrack !== index) {\n this.captions.currentTrack = index;\n const track = tracks[index];\n const { language } = track || {};\n\n // Store reference to node for invalidation on remove\n this.captions.currentTrackNode = track;\n\n // Update settings menu\n controls.updateSetting.call(this, 'captions');\n\n // When passive, don't override user preferences\n if (!passive) {\n this.captions.language = language;\n this.storage.set({ language });\n }\n\n // Handle Vimeo captions\n if (this.isVimeo) {\n this.embed.enableTextTrack(language);\n }\n\n // Trigger event\n triggerEvent.call(this, this.media, 'languagechange');\n }\n\n // Show captions\n captions.toggle.call(this, true, passive);\n\n if (this.isHTML5 && this.isVideo) {\n // If we change the active track while a cue is already displayed we need to update it\n captions.updateCues.call(this);\n }\n },\n\n // Set captions by language\n // Used internally for the language setter with the passive option forced to false\n setLanguage(input, passive = true) {\n if (!is.string(input)) {\n this.debug.warn('Invalid language argument', input);\n return;\n }\n // Normalize\n const language = input.toLowerCase();\n this.captions.language = language;\n\n // Set currentTrack\n const tracks = captions.getTracks.call(this);\n const track = captions.findTrack.call(this, [language]);\n captions.set.call(this, tracks.indexOf(track), passive);\n },\n\n // Get current valid caption tracks\n // If update is false it will also ignore tracks without metadata\n // This is used to \"freeze\" the language options when captions.update is false\n getTracks(update = false) {\n // Handle media or textTracks missing or null\n const tracks = Array.from((this.media || {}).textTracks || []);\n // For HTML5, use cache instead of current tracks when it exists (if captions.update is false)\n // Filter out removed tracks and tracks that aren't captions/subtitles (for example metadata)\n return tracks\n .filter(track => !this.isHTML5 || update || this.captions.meta.has(track))\n .filter(track => ['captions', 'subtitles'].includes(track.kind));\n },\n\n // Match tracks based on languages and get the first\n findTrack(languages, force = false) {\n const tracks = captions.getTracks.call(this);\n const sortIsDefault = track => Number((this.captions.meta.get(track) || {}).default);\n const sorted = Array.from(tracks).sort((a, b) => sortIsDefault(b) - sortIsDefault(a));\n let track;\n languages.every(language => {\n track = sorted.find(track => track.language === language);\n return !track; // Break iteration if there is a match\n });\n // If no match is found but is required, get first\n return track || (force ? sorted[0] : undefined);\n },\n\n // Get the current track\n getCurrentTrack() {\n return captions.getTracks.call(this)[this.currentTrack];\n },\n\n // Get UI label for track\n getLabel(track) {\n let currentTrack = track;\n\n if (!is.track(currentTrack) && support.textTracks && this.captions.toggled) {\n currentTrack = captions.getCurrentTrack.call(this);\n }\n\n if (is.track(currentTrack)) {\n if (!is.empty(currentTrack.label)) {\n return currentTrack.label;\n }\n\n if (!is.empty(currentTrack.language)) {\n return track.language.toUpperCase();\n }\n\n return i18n.get('enabled', this.config);\n }\n\n return i18n.get('disabled', this.config);\n },\n\n // Update captions using current track's active cues\n // Also optional array argument in case there isn't any track (ex: vimeo)\n updateCues(input) {\n // Requires UI\n if (!this.supported.ui) {\n return;\n }\n\n if (!is.element(this.elements.captions)) {\n this.debug.warn('No captions element to render to');\n return;\n }\n\n // Only accept array or empty input\n if (!is.nullOrUndefined(input) && !Array.isArray(input)) {\n this.debug.warn('updateCues: Invalid input', input);\n return;\n }\n\n let cues = input;\n\n // Get cues from track\n if (!cues) {\n const track = captions.getCurrentTrack.call(this);\n cues = Array.from((track || {}).activeCues || [])\n .map(cue => cue.getCueAsHTML())\n .map(getHTML);\n }\n\n // Set new caption text\n const content = cues.map(cueText => cueText.trim()).join('\\n');\n const changed = content !== this.elements.captions.innerHTML;\n\n if (changed) {\n // Empty the container and create a new child element\n emptyElement(this.elements.captions);\n const caption = createElement('span', getAttributesFromSelector(this.config.selectors.caption));\n caption.innerHTML = content;\n this.elements.captions.appendChild(caption);\n\n // Trigger event\n triggerEvent.call(this, this.media, 'cuechange');\n }\n },\n};\n\nexport default captions;\n","// ==========================================================================\n// Plyr default config\n// ==========================================================================\n\nconst defaults = {\n // Disable\n enabled: true,\n\n // Custom media title\n title: '',\n\n // Logging to console\n debug: false,\n\n // Auto play (if supported)\n autoplay: false,\n\n // Only allow one media playing at once (vimeo only)\n autopause: true,\n\n // Allow inline playback on iOS (this effects YouTube/Vimeo - HTML5 requires the attribute present)\n // TODO: Remove iosNative fullscreen option in favour of this (logic needs work)\n playsinline: true,\n\n // Default time to skip when rewind/fast forward\n seekTime: 10,\n\n // Default volume\n volume: 1,\n muted: false,\n\n // Pass a custom duration\n duration: null,\n\n // Display the media duration on load in the current time position\n // If you have opted to display both duration and currentTime, this is ignored\n displayDuration: true,\n\n // Invert the current time to be a countdown\n invertTime: true,\n\n // Clicking the currentTime inverts it's value to show time left rather than elapsed\n toggleInvert: true,\n\n // Aspect ratio (for embeds)\n ratio: '16:9',\n\n // Click video container to play/pause\n clickToPlay: true,\n\n // Auto hide the controls\n hideControls: true,\n\n // Reset to start when playback ended\n resetOnEnd: false,\n\n // Disable the standard context menu\n disableContextMenu: true,\n\n // Sprite (for icons)\n loadSprite: true,\n iconPrefix: 'plyr',\n iconUrl: 'https://cdn.plyr.io/3.3.12/plyr.svg',\n\n // Blank video (used to prevent errors on source change)\n blankVideo: 'https://cdn.plyr.io/static/blank.mp4',\n\n // Quality default\n quality: {\n default: 576,\n options: [\n 4320,\n 2880,\n 2160,\n 1440,\n 1080,\n 720,\n 576,\n 480,\n 360,\n 240,\n 'default', // YouTube's \"auto\"\n ],\n },\n\n // Set loops\n loop: {\n active: false,\n // start: null,\n // end: null,\n },\n\n // Speed default and options to display\n speed: {\n selected: 1,\n options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],\n },\n\n // Keyboard shortcut settings\n keyboard: {\n focused: true,\n global: false,\n },\n\n // Display tooltips\n tooltips: {\n controls: false,\n seek: true,\n },\n\n // Captions settings\n captions: {\n active: false,\n language: 'auto',\n // Listen to new tracks added after Plyr is initialized.\n // This is needed for streaming captions, but may result in unselectable options\n update: false,\n },\n\n // Fullscreen settings\n fullscreen: {\n enabled: true, // Allow fullscreen?\n fallback: true, // Fallback for vintage browsers\n iosNative: false, // Use the native fullscreen in iOS (disables custom controls)\n },\n\n // Local storage\n storage: {\n enabled: true,\n key: 'plyr',\n },\n\n // Default controls\n controls: [\n 'play-large',\n // 'restart',\n // 'rewind',\n 'play',\n // 'fast-forward',\n 'progress',\n 'current-time',\n 'mute',\n 'volume',\n 'captions',\n 'settings',\n 'pip',\n 'airplay',\n 'fullscreen',\n ],\n settings: ['captions', 'quality', 'speed'],\n\n // Localisation\n i18n: {\n restart: 'Restart',\n rewind: 'Rewind {seektime}s',\n play: 'Play',\n pause: 'Pause',\n fastForward: 'Forward {seektime}s',\n seek: 'Seek',\n seekLabel: '{currentTime} of {duration}',\n played: 'Played',\n buffered: 'Buffered',\n currentTime: 'Current time',\n duration: 'Duration',\n volume: 'Volume',\n mute: 'Mute',\n unmute: 'Unmute',\n enableCaptions: 'Enable captions',\n disableCaptions: 'Disable captions',\n enterFullscreen: 'Enter fullscreen',\n exitFullscreen: 'Exit fullscreen',\n frameTitle: 'Player for {title}',\n captions: 'Captions',\n settings: 'Settings',\n menuBack: 'Go back to previous menu',\n speed: 'Speed',\n normal: 'Normal',\n quality: 'Quality',\n loop: 'Loop',\n start: 'Start',\n end: 'End',\n all: 'All',\n reset: 'Reset',\n disabled: 'Disabled',\n enabled: 'Enabled',\n advertisement: 'Ad',\n qualityBadge: {\n 2160: '4K',\n 1440: 'HD',\n 1080: 'HD',\n 720: 'HD',\n 576: 'SD',\n 480: 'SD',\n },\n },\n\n // URLs\n urls: {\n vimeo: {\n sdk: 'https://player.vimeo.com/api/player.js',\n iframe: 'https://player.vimeo.com/video/{0}?{1}',\n api: 'https://vimeo.com/api/v2/video/{0}.json',\n },\n youtube: {\n sdk: 'https://www.youtube.com/iframe_api',\n api:\n 'https://www.googleapis.com/youtube/v3/videos?id={0}&key={1}&fields=items(snippet(title))&part=snippet',\n },\n googleIMA: {\n sdk: 'https://imasdk.googleapis.com/js/sdkloader/ima3.js',\n },\n },\n\n // Custom control listeners\n listeners: {\n seek: null,\n play: null,\n pause: null,\n restart: null,\n rewind: null,\n fastForward: null,\n mute: null,\n volume: null,\n captions: null,\n fullscreen: null,\n pip: null,\n airplay: null,\n speed: null,\n quality: null,\n loop: null,\n language: null,\n },\n\n // Events to watch and bubble\n events: [\n // Events to watch on HTML5 media elements and bubble\n // https://developer.mozilla.org/en/docs/Web/Guide/Events/Media_events\n 'ended',\n 'progress',\n 'stalled',\n 'playing',\n 'waiting',\n 'canplay',\n 'canplaythrough',\n 'loadstart',\n 'loadeddata',\n 'loadedmetadata',\n 'timeupdate',\n 'volumechange',\n 'play',\n 'pause',\n 'error',\n 'seeking',\n 'seeked',\n 'emptied',\n 'ratechange',\n 'cuechange',\n\n // Custom events\n 'enterfullscreen',\n 'exitfullscreen',\n 'captionsenabled',\n 'captionsdisabled',\n 'languagechange',\n 'controlshidden',\n 'controlsshown',\n 'ready',\n\n // YouTube\n 'statechange',\n 'qualitychange',\n 'qualityrequested',\n\n // Ads\n 'adsloaded',\n 'adscontentpause',\n 'adscontentresume',\n 'adstarted',\n 'adsmidpoint',\n 'adscomplete',\n 'adsallcomplete',\n 'adsimpression',\n 'adsclick',\n ],\n\n // Selectors\n // Change these to match your template if using custom HTML\n selectors: {\n editable: 'input, textarea, select, [contenteditable]',\n container: '.plyr',\n controls: {\n container: null,\n wrapper: '.plyr__controls',\n },\n labels: '[data-plyr]',\n buttons: {\n play: '[data-plyr=\"play\"]',\n pause: '[data-plyr=\"pause\"]',\n restart: '[data-plyr=\"restart\"]',\n rewind: '[data-plyr=\"rewind\"]',\n fastForward: '[data-plyr=\"fast-forward\"]',\n mute: '[data-plyr=\"mute\"]',\n captions: '[data-plyr=\"captions\"]',\n fullscreen: '[data-plyr=\"fullscreen\"]',\n pip: '[data-plyr=\"pip\"]',\n airplay: '[data-plyr=\"airplay\"]',\n settings: '[data-plyr=\"settings\"]',\n loop: '[data-plyr=\"loop\"]',\n },\n inputs: {\n seek: '[data-plyr=\"seek\"]',\n volume: '[data-plyr=\"volume\"]',\n speed: '[data-plyr=\"speed\"]',\n language: '[data-plyr=\"language\"]',\n quality: '[data-plyr=\"quality\"]',\n },\n display: {\n currentTime: '.plyr__time--current',\n duration: '.plyr__time--duration',\n buffer: '.plyr__progress__buffer',\n loop: '.plyr__progress__loop', // Used later\n volume: '.plyr__volume--display',\n },\n progress: '.plyr__progress',\n captions: '.plyr__captions',\n caption: '.plyr__caption',\n menu: {\n quality: '.js-plyr__menu__list--quality',\n },\n },\n\n // Class hooks added to the player in different states\n classNames: {\n type: 'plyr--{0}',\n provider: 'plyr--{0}',\n video: 'plyr__video-wrapper',\n embed: 'plyr__video-embed',\n embedContainer: 'plyr__video-embed__container',\n poster: 'plyr__poster',\n posterEnabled: 'plyr__poster-enabled',\n ads: 'plyr__ads',\n control: 'plyr__control',\n controlPressed: 'plyr__control--pressed',\n playing: 'plyr--playing',\n paused: 'plyr--paused',\n stopped: 'plyr--stopped',\n loading: 'plyr--loading',\n hover: 'plyr--hover',\n tooltip: 'plyr__tooltip',\n cues: 'plyr__cues',\n hidden: 'plyr__sr-only',\n hideControls: 'plyr--hide-controls',\n isIos: 'plyr--is-ios',\n isTouch: 'plyr--is-touch',\n uiSupported: 'plyr--full-ui',\n noTransition: 'plyr--no-transition',\n display: {\n time: 'plyr__time',\n },\n menu: {\n value: 'plyr__menu__value',\n badge: 'plyr__badge',\n open: 'plyr--menu-open',\n },\n captions: {\n enabled: 'plyr--captions-enabled',\n active: 'plyr--captions-active',\n },\n fullscreen: {\n enabled: 'plyr--fullscreen-enabled',\n fallback: 'plyr--fullscreen-fallback',\n },\n pip: {\n supported: 'plyr--pip-supported',\n active: 'plyr--pip-active',\n },\n airplay: {\n supported: 'plyr--airplay-supported',\n active: 'plyr--airplay-active',\n },\n tabFocus: 'plyr__tab-focus',\n },\n\n // Embed attributes\n attributes: {\n embed: {\n provider: 'data-plyr-provider',\n id: 'data-plyr-embed-id',\n },\n },\n\n // API keys\n keys: {\n google: null,\n },\n\n // Advertisements plugin\n // Register for an account here: http://vi.ai/publisher-video-monetization/?aid=plyrio\n ads: {\n enabled: false,\n publisherId: '',\n },\n};\n\nexport default defaults;\n","// ==========================================================================\n// Plyr supported types and providers\n// ==========================================================================\n\nexport const providers = {\n html5: 'html5',\n youtube: 'youtube',\n vimeo: 'vimeo',\n};\n\nexport const types = {\n audio: 'audio',\n video: 'video',\n};\n\n/**\n * Get provider by URL\n * @param {string} url\n */\nexport function getProviderByUrl(url) {\n // YouTube\n if (/^(https?:\\/\\/)?(www\\.)?(youtube\\.com|youtu\\.?be)\\/.+$/.test(url)) {\n return providers.youtube;\n }\n\n // Vimeo\n if (/^https?:\\/\\/player.vimeo.com\\/video\\/\\d{0,9}(?=\\b|\\/)/.test(url)) {\n return providers.vimeo;\n }\n\n return null;\n}\n\nexport default { providers, types };\n","// ==========================================================================\n// Console wrapper\n// ==========================================================================\n\nconst noop = () => {};\n\nexport default class Console {\n constructor(enabled = false) {\n this.enabled = window.console && enabled;\n\n if (this.enabled) {\n this.log('Debugging enabled');\n }\n }\n\n get log() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.log, console) : noop;\n }\n get warn() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.warn, console) : noop;\n }\n get error() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.error, console) : noop;\n }\n}\n","// ==========================================================================\n// Fullscreen wrapper\n// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API#prefixing\n// ==========================================================================\n\nimport browser from './utils/browser';\nimport { hasClass, toggleClass, trapFocus } from './utils/elements';\nimport { on, triggerEvent } from './utils/events';\nimport is from './utils/is';\n\nfunction onChange() {\n if (!this.enabled) {\n return;\n }\n\n // Update toggle button\n const button = this.player.elements.buttons.fullscreen;\n if (is.element(button)) {\n button.pressed = this.active;\n }\n\n // Trigger an event\n triggerEvent.call(this.player, this.target, this.active ? 'enterfullscreen' : 'exitfullscreen', true);\n\n // Trap focus in container\n if (!browser.isIos) {\n trapFocus.call(this.player, this.target, this.active);\n }\n}\n\nfunction toggleFallback(toggle = false) {\n // Store or restore scroll position\n if (toggle) {\n this.scrollPosition = {\n x: window.scrollX || 0,\n y: window.scrollY || 0,\n };\n } else {\n window.scrollTo(this.scrollPosition.x, this.scrollPosition.y);\n }\n\n // Toggle scroll\n document.body.style.overflow = toggle ? 'hidden' : '';\n\n // Toggle class hook\n toggleClass(this.target, this.player.config.classNames.fullscreen.fallback, toggle);\n\n // Toggle button and fire events\n onChange.call(this);\n}\n\nclass Fullscreen {\n constructor(player) {\n // Keep reference to parent\n this.player = player;\n\n // Get prefix\n this.prefix = Fullscreen.prefix;\n this.property = Fullscreen.property;\n\n // Scroll position\n this.scrollPosition = { x: 0, y: 0 };\n\n // Register event listeners\n // Handle event (incase user presses escape etc)\n on.call(\n this.player,\n document,\n this.prefix === 'ms' ? 'MSFullscreenChange' : `${this.prefix}fullscreenchange`,\n () => {\n // TODO: Filter for target??\n onChange.call(this);\n },\n );\n\n // Fullscreen toggle on double click\n on.call(this.player, this.player.elements.container, 'dblclick', event => {\n // Ignore double click in controls\n if (is.element(this.player.elements.controls) && this.player.elements.controls.contains(event.target)) {\n return;\n }\n\n this.toggle();\n });\n\n // Update the UI\n this.update();\n }\n\n // Determine if native supported\n static get native() {\n return !!(\n document.fullscreenEnabled ||\n document.webkitFullscreenEnabled ||\n document.mozFullScreenEnabled ||\n document.msFullscreenEnabled\n );\n }\n\n // Get the prefix for handlers\n static get prefix() {\n // No prefix\n if (is.function(document.exitFullscreen)) {\n return '';\n }\n\n // Check for fullscreen support by vendor prefix\n let value = '';\n const prefixes = ['webkit', 'moz', 'ms'];\n\n prefixes.some(pre => {\n if (is.function(document[`${pre}ExitFullscreen`]) || is.function(document[`${pre}CancelFullScreen`])) {\n value = pre;\n return true;\n }\n\n return false;\n });\n\n return value;\n }\n\n static get property() {\n return this.prefix === 'moz' ? 'FullScreen' : 'Fullscreen';\n }\n\n // Determine if fullscreen is enabled\n get enabled() {\n return (\n (Fullscreen.native || this.player.config.fullscreen.fallback) &&\n this.player.config.fullscreen.enabled &&\n this.player.supported.ui &&\n this.player.isVideo\n );\n }\n\n // Get active state\n get active() {\n if (!this.enabled) {\n return false;\n }\n\n // Fallback using classname\n if (!Fullscreen.native) {\n return hasClass(this.target, this.player.config.classNames.fullscreen.fallback);\n }\n\n const element = !this.prefix ? document.fullscreenElement : document[`${this.prefix}${this.property}Element`];\n\n return element === this.target;\n }\n\n // Get target element\n get target() {\n return browser.isIos && this.player.config.fullscreen.iosNative\n ? this.player.media\n : this.player.elements.container;\n }\n\n // Update UI\n update() {\n if (this.enabled) {\n this.player.debug.log(`${Fullscreen.native ? 'Native' : 'Fallback'} fullscreen enabled`);\n } else {\n this.player.debug.log('Fullscreen not supported and fallback disabled');\n }\n\n // Add styling hook to show button\n toggleClass(this.player.elements.container, this.player.config.classNames.fullscreen.enabled, this.enabled);\n }\n\n // Make an element fullscreen\n enter() {\n if (!this.enabled) {\n return;\n }\n\n // iOS native fullscreen doesn't need the request step\n if (browser.isIos && this.player.config.fullscreen.iosNative) {\n if (this.player.playing) {\n this.target.webkitEnterFullscreen();\n }\n } else if (!Fullscreen.native) {\n toggleFallback.call(this, true);\n } else if (!this.prefix) {\n this.target.requestFullscreen();\n } else if (!is.empty(this.prefix)) {\n this.target[`${this.prefix}Request${this.property}`]();\n }\n }\n\n // Bail from fullscreen\n exit() {\n if (!this.enabled) {\n return;\n }\n\n // iOS native fullscreen\n if (browser.isIos && this.player.config.fullscreen.iosNative) {\n this.target.webkitExitFullscreen();\n this.player.play();\n } else if (!Fullscreen.native) {\n toggleFallback.call(this, false);\n } else if (!this.prefix) {\n (document.cancelFullScreen || document.exitFullscreen).call(document);\n } else if (!is.empty(this.prefix)) {\n const action = this.prefix === 'moz' ? 'Cancel' : 'Exit';\n document[`${this.prefix}${action}${this.property}`]();\n }\n }\n\n // Toggle state\n toggle() {\n if (!this.active) {\n this.enter();\n } else {\n this.exit();\n }\n }\n}\n\nexport default Fullscreen;\n","// ==========================================================================\n// Load image avoiding xhr/fetch CORS issues\n// Server status can't be obtained this way unfortunately, so this uses \"naturalWidth\" to determine if the image has loaded\n// By default it checks if it is at least 1px, but you can add a second argument to change this\n// ==========================================================================\n\nexport default function loadImage(src, minWidth = 1) {\n return new Promise((resolve, reject) => {\n const image = new Image();\n\n const handler = () => {\n delete image.onload;\n delete image.onerror;\n (image.naturalWidth >= minWidth ? resolve : reject)(image);\n };\n\n Object.assign(image, { onload: handler, onerror: handler, src });\n });\n}\n","// ==========================================================================\n// Plyr UI\n// ==========================================================================\n\nimport captions from './captions';\nimport controls from './controls';\nimport i18n from './i18n';\nimport support from './support';\nimport browser from './utils/browser';\nimport { getElement, toggleClass } from './utils/elements';\nimport { ready, triggerEvent } from './utils/events';\nimport is from './utils/is';\nimport loadImage from './utils/loadImage';\n\nconst ui = {\n addStyleHook() {\n toggleClass(this.elements.container, this.config.selectors.container.replace('.', ''), true);\n toggleClass(this.elements.container, this.config.classNames.uiSupported, this.supported.ui);\n },\n\n // Toggle native HTML5 media controls\n toggleNativeControls(toggle = false) {\n if (toggle && this.isHTML5) {\n this.media.setAttribute('controls', '');\n } else {\n this.media.removeAttribute('controls');\n }\n },\n\n // Setup the UI\n build() {\n // Re-attach media element listeners\n // TODO: Use event bubbling?\n this.listeners.media();\n\n // Don't setup interface if no support\n if (!this.supported.ui) {\n this.debug.warn(`Basic support only for ${this.provider} ${this.type}`);\n\n // Restore native controls\n ui.toggleNativeControls.call(this, true);\n\n // Bail\n return;\n }\n\n // Inject custom controls if not present\n if (!is.element(this.elements.controls)) {\n // Inject custom controls\n controls.inject.call(this);\n\n // Re-attach control listeners\n this.listeners.controls();\n }\n\n // Remove native controls\n ui.toggleNativeControls.call(this);\n\n // Setup captions for HTML5\n if (this.isHTML5) {\n captions.setup.call(this);\n }\n\n // Reset volume\n this.volume = null;\n\n // Reset mute state\n this.muted = null;\n\n // Reset speed\n this.speed = null;\n\n // Reset loop state\n this.loop = null;\n\n // Reset quality setting\n this.quality = null;\n\n // Reset volume display\n controls.updateVolume.call(this);\n\n // Reset time display\n controls.timeUpdate.call(this);\n\n // Update the UI\n ui.checkPlaying.call(this);\n\n // Check for picture-in-picture support\n toggleClass(\n this.elements.container,\n this.config.classNames.pip.supported,\n support.pip && this.isHTML5 && this.isVideo,\n );\n\n // Check for airplay support\n toggleClass(this.elements.container, this.config.classNames.airplay.supported, support.airplay && this.isHTML5);\n\n // Add iOS class\n toggleClass(this.elements.container, this.config.classNames.isIos, browser.isIos);\n\n // Add touch class\n toggleClass(this.elements.container, this.config.classNames.isTouch, this.touch);\n\n // Ready for API calls\n this.ready = true;\n\n // Ready event at end of execution stack\n setTimeout(() => {\n triggerEvent.call(this, this.media, 'ready');\n }, 0);\n\n // Set the title\n ui.setTitle.call(this);\n\n // Assure the poster image is set, if the property was added before the element was created\n if (this.poster) {\n ui.setPoster.call(this, this.poster, false).catch(() => {});\n }\n\n // Manually set the duration if user has overridden it.\n // The event listeners for it doesn't get called if preload is disabled (#701)\n if (this.config.duration) {\n controls.durationUpdate.call(this);\n }\n },\n\n // Setup aria attribute for play and iframe title\n setTitle() {\n // Find the current text\n let label = i18n.get('play', this.config);\n\n // If there's a media title set, use that for the label\n if (is.string(this.config.title) && !is.empty(this.config.title)) {\n label += `, ${this.config.title}`;\n }\n\n // If there's a play button, set label\n Array.from(this.elements.buttons.play || []).forEach(button => {\n button.setAttribute('aria-label', label);\n });\n\n // Set iframe title\n // https://github.com/sampotts/plyr/issues/124\n if (this.isEmbed) {\n const iframe = getElement.call(this, 'iframe');\n\n if (!is.element(iframe)) {\n return;\n }\n\n // Default to media type\n const title = !is.empty(this.config.title) ? this.config.title : 'video';\n const format = i18n.get('frameTitle', this.config);\n\n iframe.setAttribute('title', format.replace('{title}', title));\n }\n },\n\n // Toggle poster\n togglePoster(enable) {\n toggleClass(this.elements.container, this.config.classNames.posterEnabled, enable);\n },\n\n // Set the poster image (async)\n // Used internally for the poster setter, with the passive option forced to false\n setPoster(poster, passive = true) {\n // Don't override if call is passive\n if (passive && this.poster) {\n return Promise.reject(new Error('Poster already set'));\n }\n\n // Set property synchronously to respect the call order\n this.media.setAttribute('poster', poster);\n\n // Wait until ui is ready\n return (\n ready\n .call(this)\n // Load image\n .then(() => loadImage(poster))\n .catch(err => {\n // Hide poster on error unless it's been set by another call\n if (poster === this.poster) {\n ui.togglePoster.call(this, false);\n }\n // Rethrow\n throw err;\n })\n .then(() => {\n // Prevent race conditions\n if (poster !== this.poster) {\n throw new Error('setPoster cancelled by later call to setPoster');\n }\n })\n .then(() => {\n Object.assign(this.elements.poster.style, {\n backgroundImage: `url('${poster}')`,\n // Reset backgroundSize as well (since it can be set to \"cover\" for padded thumbnails for youtube)\n backgroundSize: '',\n });\n ui.togglePoster.call(this, true);\n return poster;\n })\n );\n },\n\n // Check playing state\n checkPlaying(event) {\n // Class hooks\n toggleClass(this.elements.container, this.config.classNames.playing, this.playing);\n toggleClass(this.elements.container, this.config.classNames.paused, this.paused);\n toggleClass(this.elements.container, this.config.classNames.stopped, this.stopped);\n\n // Set state\n Array.from(this.elements.buttons.play || []).forEach(target => {\n target.pressed = this.playing;\n });\n\n // Only update controls on non timeupdate events\n if (is.event(event) && event.type === 'timeupdate') {\n return;\n }\n\n // Toggle controls\n ui.toggleControls.call(this);\n },\n\n // Check if media is loading\n checkLoading(event) {\n this.loading = ['stalled', 'waiting'].includes(event.type);\n\n // Clear timer\n clearTimeout(this.timers.loading);\n\n // Timer to prevent flicker when seeking\n this.timers.loading = setTimeout(() => {\n // Update progress bar loading class state\n toggleClass(this.elements.container, this.config.classNames.loading, this.loading);\n\n // Update controls visibility\n ui.toggleControls.call(this);\n }, this.loading ? 250 : 0);\n },\n\n // Toggle controls based on state and `force` argument\n toggleControls(force) {\n const { controls } = this.elements;\n\n if (controls && this.config.hideControls) {\n // Show controls if force, loading, paused, or button interaction, otherwise hide\n this.toggleControls(Boolean(force || this.loading || this.paused || controls.pressed || controls.hover));\n }\n },\n};\n\nexport default ui;\n","// ==========================================================================\n// Plyr Event Listeners\n// ==========================================================================\n\nimport controls from './controls';\nimport ui from './ui';\nimport browser from './utils/browser';\nimport { getElement, getElements, getFocusElement, matches, toggleClass, toggleHidden } from './utils/elements';\nimport { on, once, toggleListener, triggerEvent } from './utils/events';\nimport is from './utils/is';\n\nclass Listeners {\n constructor(player) {\n this.player = player;\n this.lastKey = null;\n\n this.handleKey = this.handleKey.bind(this);\n this.toggleMenu = this.toggleMenu.bind(this);\n this.firstTouch = this.firstTouch.bind(this);\n }\n\n // Handle key presses\n handleKey(event) {\n const code = event.keyCode ? event.keyCode : event.which;\n const pressed = event.type === 'keydown';\n const repeat = pressed && code === this.lastKey;\n\n // Bail if a modifier key is set\n if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {\n return;\n }\n\n // If the event is bubbled from the media element\n // Firefox doesn't get the keycode for whatever reason\n if (!is.number(code)) {\n return;\n }\n\n // Seek by the number keys\n const seekByKey = () => {\n // Divide the max duration into 10th's and times by the number value\n this.player.currentTime = this.player.duration / 10 * (code - 48);\n };\n\n // Handle the key on keydown\n // Reset on keyup\n if (pressed) {\n // Which keycodes should we prevent default\n const preventDefault = [32, 37, 38, 39, 40, 48, 49, 50, 51, 52, 53, 54, 56, 57, 67, 70, 73, 75, 76, 77, 79];\n\n // Check focused element\n // and if the focused element is not editable (e.g. text input)\n // and any that accept key input http://webaim.org/techniques/keyboard/\n const focused = getFocusElement();\n if (\n is.element(focused) &&\n (focused !== this.player.elements.inputs.seek &&\n matches(focused, this.player.config.selectors.editable))\n ) {\n return;\n }\n\n // If the code is found prevent default (e.g. prevent scrolling for arrows)\n if (preventDefault.includes(code)) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n switch (code) {\n case 48:\n case 49:\n case 50:\n case 51:\n case 52:\n case 53:\n case 54:\n case 55:\n case 56:\n case 57:\n // 0-9\n if (!repeat) {\n seekByKey();\n }\n break;\n\n case 32:\n case 75:\n // Space and K key\n if (!repeat) {\n this.player.togglePlay();\n }\n break;\n\n case 38:\n // Arrow up\n this.player.increaseVolume(0.1);\n break;\n\n case 40:\n // Arrow down\n this.player.decreaseVolume(0.1);\n break;\n\n case 77:\n // M key\n if (!repeat) {\n this.player.muted = !this.player.muted;\n }\n break;\n\n case 39:\n // Arrow forward\n this.player.forward();\n break;\n\n case 37:\n // Arrow back\n this.player.rewind();\n break;\n\n case 70:\n // F key\n this.player.fullscreen.toggle();\n break;\n\n case 67:\n // C key\n if (!repeat) {\n this.player.toggleCaptions();\n }\n break;\n\n case 76:\n // L key\n this.player.loop = !this.player.loop;\n break;\n\n /* case 73:\n this.setLoop('start');\n break;\n\n case 76:\n this.setLoop();\n break;\n\n case 79:\n this.setLoop('end');\n break; */\n\n default:\n break;\n }\n\n // Escape is handle natively when in full screen\n // So we only need to worry about non native\n if (!this.player.fullscreen.enabled && this.player.fullscreen.active && code === 27) {\n this.player.fullscreen.toggle();\n }\n\n // Store last code for next cycle\n this.lastKey = code;\n } else {\n this.lastKey = null;\n }\n }\n\n // Toggle menu\n toggleMenu(event) {\n controls.toggleMenu.call(this.player, event);\n }\n\n // Device is touch enabled\n firstTouch() {\n this.player.touch = true;\n\n // Add touch class\n toggleClass(this.player.elements.container, this.player.config.classNames.isTouch, true);\n }\n\n // Global window & document listeners\n global(toggle = true) {\n // Keyboard shortcuts\n if (this.player.config.keyboard.global) {\n toggleListener.call(this.player, window, 'keydown keyup', this.handleKey, toggle, false);\n }\n\n // Click anywhere closes menu\n toggleListener.call(this.player, document.body, 'click', this.toggleMenu, toggle);\n\n // Detect touch by events\n once.call(this.player, document.body, 'touchstart', this.firstTouch);\n }\n\n // Container listeners\n container() {\n // Keyboard shortcuts\n if (!this.player.config.keyboard.global && this.player.config.keyboard.focused) {\n on.call(this.player, this.player.elements.container, 'keydown keyup', this.handleKey, false);\n }\n\n // Detect tab focus\n // Remove class on blur/focusout\n on.call(this.player, this.player.elements.container, 'focusout', event => {\n toggleClass(event.target, this.player.config.classNames.tabFocus, false);\n });\n // Add classname to tabbed elements\n on.call(this.player, this.player.elements.container, 'keydown', event => {\n if (event.keyCode !== 9) {\n return;\n }\n\n // Delay the adding of classname until the focus has changed\n // This event fires before the focusin event\n setTimeout(() => {\n toggleClass(getFocusElement(), this.player.config.classNames.tabFocus, true);\n }, 0);\n });\n\n // Toggle controls on mouse events and entering fullscreen\n on.call(\n this.player,\n this.player.elements.container,\n 'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen',\n event => {\n const { controls } = this.player.elements;\n\n // Remove button states for fullscreen\n if (event.type === 'enterfullscreen') {\n controls.pressed = false;\n controls.hover = false;\n }\n\n // Show, then hide after a timeout unless another control event occurs\n const show = ['touchstart', 'touchmove', 'mousemove'].includes(event.type);\n\n let delay = 0;\n\n if (show) {\n ui.toggleControls.call(this.player, true);\n // Use longer timeout for touch devices\n delay = this.player.touch ? 3000 : 2000;\n }\n\n // Clear timer\n clearTimeout(this.player.timers.controls);\n // Timer to prevent flicker when seeking\n this.player.timers.controls = setTimeout(() => ui.toggleControls.call(this.player, false), delay);\n },\n );\n }\n\n // Listen for media events\n media() {\n // Time change on media\n on.call(this.player, this.player.media, 'timeupdate seeking seeked', event =>\n controls.timeUpdate.call(this.player, event),\n );\n\n // Display duration\n on.call(this.player, this.player.media, 'durationchange loadeddata loadedmetadata', event =>\n controls.durationUpdate.call(this.player, event),\n );\n\n // Check for audio tracks on load\n // We can't use `loadedmetadata` as it doesn't seem to have audio tracks at that point\n on.call(this.player, this.player.media, 'canplay', () => {\n toggleHidden(this.player.elements.volume, !this.player.hasAudio);\n toggleHidden(this.player.elements.buttons.mute, !this.player.hasAudio);\n });\n\n // Handle the media finishing\n on.call(this.player, this.player.media, 'ended', () => {\n // Show poster on end\n if (this.player.isHTML5 && this.player.isVideo && this.player.config.resetOnEnd) {\n // Restart\n this.player.restart();\n }\n });\n\n // Check for buffer progress\n on.call(this.player, this.player.media, 'progress playing seeking seeked', event =>\n controls.updateProgress.call(this.player, event),\n );\n\n // Handle volume changes\n on.call(this.player, this.player.media, 'volumechange', event =>\n controls.updateVolume.call(this.player, event),\n );\n\n // Handle play/pause\n on.call(this.player, this.player.media, 'playing play pause ended emptied timeupdate', event =>\n ui.checkPlaying.call(this.player, event),\n );\n\n // Loading state\n on.call(this.player, this.player.media, 'waiting canplay seeked playing', event =>\n ui.checkLoading.call(this.player, event),\n );\n\n // If autoplay, then load advertisement if required\n // TODO: Show some sort of loading state while the ad manager loads else there's a delay before ad shows\n on.call(this.player, this.player.media, 'playing', () => {\n if (!this.player.ads) {\n return;\n }\n\n // If ads are enabled, wait for them first\n if (this.player.ads.enabled && !this.player.ads.initialized) {\n // Wait for manager response\n this.player.ads.managerPromise.then(() => this.player.ads.play()).catch(() => this.player.play());\n }\n });\n\n // Click video\n if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) {\n // Re-fetch the wrapper\n const wrapper = getElement.call(this.player, `.${this.player.config.classNames.video}`);\n\n // Bail if there's no wrapper (this should never happen)\n if (!is.element(wrapper)) {\n return;\n }\n\n // On click play, pause ore restart\n on.call(this.player, wrapper, 'click', () => {\n // Touch devices will just show controls (if we're hiding controls)\n if (this.player.config.hideControls && this.player.touch && !this.player.paused) {\n return;\n }\n\n if (this.player.paused) {\n this.player.play();\n } else if (this.player.ended) {\n this.player.restart();\n this.player.play();\n } else {\n this.player.pause();\n }\n });\n }\n\n // Disable right click\n if (this.player.supported.ui && this.player.config.disableContextMenu) {\n on.call(\n this.player,\n this.player.elements.wrapper,\n 'contextmenu',\n event => {\n event.preventDefault();\n },\n false,\n );\n }\n\n // Volume change\n on.call(this.player, this.player.media, 'volumechange', () => {\n // Save to storage\n this.player.storage.set({ volume: this.player.volume, muted: this.player.muted });\n });\n\n // Speed change\n on.call(this.player, this.player.media, 'ratechange', () => {\n // Update UI\n controls.updateSetting.call(this.player, 'speed');\n\n // Save to storage\n this.player.storage.set({ speed: this.player.speed });\n });\n\n // Quality request\n on.call(this.player, this.player.media, 'qualityrequested', event => {\n // Save to storage\n this.player.storage.set({ quality: event.detail.quality });\n });\n\n // Quality change\n on.call(this.player, this.player.media, 'qualitychange', event => {\n // Update UI\n controls.updateSetting.call(this.player, 'quality', null, event.detail.quality);\n });\n\n // Proxy events to container\n // Bubble up key events for Edge\n const proxyEvents = this.player.config.events.concat(['keyup', 'keydown']).join(' ');\n on.call(this.player, this.player.media, proxyEvents, event => {\n let { detail = {} } = event;\n\n // Get error details from media\n if (event.type === 'error') {\n detail = this.player.media.error;\n }\n\n triggerEvent.call(this.player, this.player.elements.container, event.type, true, detail);\n });\n }\n\n // Listen for control events\n controls() {\n // IE doesn't support input event, so we fallback to change\n const inputEvent = browser.isIE ? 'change' : 'input';\n\n // Run default and custom handlers\n const proxy = (event, defaultHandler, customHandlerKey) => {\n const customHandler = this.player.config.listeners[customHandlerKey];\n const hasCustomHandler = is.function(customHandler);\n let returned = true;\n\n // Execute custom handler\n if (hasCustomHandler) {\n returned = customHandler.call(this.player, event);\n }\n\n // Only call default handler if not prevented in custom handler\n if (returned && is.function(defaultHandler)) {\n defaultHandler.call(this.player, event);\n }\n };\n\n // Trigger custom and default handlers\n const bind = (element, type, defaultHandler, customHandlerKey, passive = true) => {\n const customHandler = this.player.config.listeners[customHandlerKey];\n const hasCustomHandler = is.function(customHandler);\n\n on.call(\n this.player,\n element,\n type,\n event => proxy(event, defaultHandler, customHandlerKey),\n passive && !hasCustomHandler,\n );\n };\n\n // Play/pause toggle\n Array.from(this.player.elements.buttons.play).forEach(button => {\n bind(button, 'click', this.player.togglePlay, 'play');\n });\n\n // Pause\n bind(this.player.elements.buttons.restart, 'click', this.player.restart, 'restart');\n\n // Rewind\n bind(this.player.elements.buttons.rewind, 'click', this.player.rewind, 'rewind');\n\n // Rewind\n bind(this.player.elements.buttons.fastForward, 'click', this.player.forward, 'fastForward');\n\n // Mute toggle\n bind(\n this.player.elements.buttons.mute,\n 'click',\n () => {\n this.player.muted = !this.player.muted;\n },\n 'mute',\n );\n\n // Captions toggle\n bind(this.player.elements.buttons.captions, 'click', () => this.player.toggleCaptions());\n\n // Fullscreen toggle\n bind(\n this.player.elements.buttons.fullscreen,\n 'click',\n () => {\n this.player.fullscreen.toggle();\n },\n 'fullscreen',\n );\n\n // Picture-in-Picture\n bind(\n this.player.elements.buttons.pip,\n 'click',\n () => {\n this.player.pip = 'toggle';\n },\n 'pip',\n );\n\n // Airplay\n bind(this.player.elements.buttons.airplay, 'click', this.player.airplay, 'airplay');\n\n // Settings menu\n bind(this.player.elements.buttons.settings, 'click', event => {\n controls.toggleMenu.call(this.player, event);\n });\n\n // Settings menu\n bind(this.player.elements.settings.popup, 'click', event => {\n event.stopPropagation();\n\n // Go back to home tab on click\n const showHomeTab = () => {\n controls.showMenuPanel.call(this.player, 'home');\n };\n\n // Settings menu items - use event delegation as items are added/removed\n if (matches(event.target, this.player.config.selectors.inputs.language)) {\n proxy(\n event,\n () => {\n this.player.currentTrack = Number(event.target.value);\n showHomeTab();\n },\n 'language',\n );\n } else if (matches(event.target, this.player.config.selectors.inputs.quality)) {\n proxy(\n event,\n () => {\n this.player.quality = event.target.value;\n showHomeTab();\n },\n 'quality',\n );\n } else if (matches(event.target, this.player.config.selectors.inputs.speed)) {\n proxy(\n event,\n () => {\n this.player.speed = parseFloat(event.target.value);\n showHomeTab();\n },\n 'speed',\n );\n }\n });\n\n // Set range input alternative \"value\", which matches the tooltip time (#954)\n bind(this.player.elements.inputs.seek, 'mousedown mousemove', event => {\n const clientRect = this.player.elements.progress.getBoundingClientRect();\n const percent = 100 / clientRect.width * (event.pageX - clientRect.left);\n event.currentTarget.setAttribute('seek-value', percent);\n });\n\n // Pause while seeking\n bind(this.player.elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', event => {\n const seek = event.currentTarget;\n\n const code = event.keyCode ? event.keyCode : event.which;\n const eventType = event.type;\n\n if ((eventType === 'keydown' || eventType === 'keyup') && (code !== 39 && code !== 37)) {\n return;\n }\n // Was playing before?\n const play = seek.hasAttribute('play-on-seeked');\n\n // Done seeking\n const done = ['mouseup', 'touchend', 'keyup'].includes(event.type);\n\n // If we're done seeking and it was playing, resume playback\n if (play && done) {\n seek.removeAttribute('play-on-seeked');\n this.player.play();\n } else if (!done && this.player.playing) {\n seek.setAttribute('play-on-seeked', '');\n this.player.pause();\n }\n });\n\n // Seek\n bind(\n this.player.elements.inputs.seek,\n inputEvent,\n event => {\n const seek = event.currentTarget;\n\n // If it exists, use seek-value instead of \"value\" for consistency with tooltip time (#954)\n let seekTo = seek.getAttribute('seek-value');\n\n if (is.empty(seekTo)) {\n seekTo = seek.value;\n }\n\n seek.removeAttribute('seek-value');\n\n this.player.currentTime = seekTo / seek.max * this.player.duration;\n },\n 'seek',\n );\n\n // Current time invert\n // Only if one time element is used for both currentTime and duration\n if (this.player.config.toggleInvert && !is.element(this.player.elements.display.duration)) {\n bind(this.player.elements.display.currentTime, 'click', () => {\n // Do nothing if we're at the start\n if (this.player.currentTime === 0) {\n return;\n }\n\n this.player.config.invertTime = !this.player.config.invertTime;\n\n controls.timeUpdate.call(this.player);\n });\n }\n\n // Volume\n bind(\n this.player.elements.inputs.volume,\n inputEvent,\n event => {\n this.player.volume = event.target.value;\n },\n 'volume',\n );\n\n // Polyfill for lower fill in <input type=\"range\"> for webkit\n if (browser.isWebkit) {\n Array.from(getElements.call(this.player, 'input[type=\"range\"]')).forEach(element => {\n bind(element, 'input', event => controls.updateRangeFill.call(this.player, event.target));\n });\n }\n\n // Seek tooltip\n bind(this.player.elements.progress, 'mouseenter mouseleave mousemove', event =>\n controls.updateSeekTooltip.call(this.player, event),\n );\n\n // Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)\n bind(this.player.elements.controls, 'mouseenter mouseleave', event => {\n this.player.elements.controls.hover = !this.player.touch && event.type === 'mouseenter';\n });\n\n // Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)\n bind(this.player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {\n this.player.elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);\n });\n\n // Focus in/out on controls\n bind(this.player.elements.controls, 'focusin focusout', event => {\n const { config, elements, timers } = this.player;\n\n // Skip transition to prevent focus from scrolling the parent element\n toggleClass(elements.controls, config.classNames.noTransition, event.type === 'focusin');\n\n // Toggle\n ui.toggleControls.call(this.player, event.type === 'focusin');\n\n // If focusin, hide again after delay\n if (event.type === 'focusin') {\n // Restore transition\n setTimeout(() => {\n toggleClass(elements.controls, config.classNames.noTransition, false);\n }, 0);\n\n // Delay a little more for keyboard users\n const delay = this.touch ? 3000 : 4000;\n\n // Clear timer\n clearTimeout(timers.controls);\n // Hide\n timers.controls = setTimeout(() => ui.toggleControls.call(this.player, false), delay);\n }\n });\n\n // Mouse wheel for volume\n bind(\n this.player.elements.inputs.volume,\n 'wheel',\n event => {\n // Detect \"natural\" scroll - suppored on OS X Safari only\n // Other browsers on OS X will be inverted until support improves\n const inverted = event.webkitDirectionInvertedFromDevice;\n const step = 1 / 50;\n let direction = 0;\n\n // Scroll down (or up on natural) to decrease\n if (event.deltaY < 0 || event.deltaX > 0) {\n if (inverted) {\n this.player.decreaseVolume(step);\n direction = -1;\n } else {\n this.player.increaseVolume(step);\n direction = 1;\n }\n }\n\n // Scroll up (or down on natural) to increase\n if (event.deltaY > 0 || event.deltaX < 0) {\n if (inverted) {\n this.player.increaseVolume(step);\n direction = 1;\n } else {\n this.player.decreaseVolume(step);\n direction = -1;\n }\n }\n\n // Don't break page scrolling at max and min\n if (\n (direction === 1 && this.player.media.volume < 1) ||\n (direction === -1 && this.player.media.volume > 0)\n ) {\n event.preventDefault();\n }\n },\n 'volume',\n false,\n );\n }\n}\n\nexport default Listeners;\n","(function(root, factory) {\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.loadjs = factory();\n }\n}(this, function() {\n/**\n * Global dependencies.\n * @global {Object} document - DOM\n */\n\nvar devnull = function() {},\n bundleIdCache = {},\n bundleResultCache = {},\n bundleCallbackQueue = {};\n\n\n/**\n * Subscribe to bundle load event.\n * @param {string[]} bundleIds - Bundle ids\n * @param {Function} callbackFn - The callback function\n */\nfunction subscribe(bundleIds, callbackFn) {\n // listify\n bundleIds = bundleIds.push ? bundleIds : [bundleIds];\n\n var depsNotFound = [],\n i = bundleIds.length,\n numWaiting = i,\n fn,\n bundleId,\n r,\n q;\n\n // define callback function\n fn = function (bundleId, pathsNotFound) {\n if (pathsNotFound.length) depsNotFound.push(bundleId);\n\n numWaiting--;\n if (!numWaiting) callbackFn(depsNotFound);\n };\n\n // register callback\n while (i--) {\n bundleId = bundleIds[i];\n\n // execute callback if in result cache\n r = bundleResultCache[bundleId];\n if (r) {\n fn(bundleId, r);\n continue;\n }\n\n // add to callback queue\n q = bundleCallbackQueue[bundleId] = bundleCallbackQueue[bundleId] || [];\n q.push(fn);\n }\n}\n\n\n/**\n * Publish bundle load event.\n * @param {string} bundleId - Bundle id\n * @param {string[]} pathsNotFound - List of files not found\n */\nfunction publish(bundleId, pathsNotFound) {\n // exit if id isn't defined\n if (!bundleId) return;\n\n var q = bundleCallbackQueue[bundleId];\n\n // cache result\n bundleResultCache[bundleId] = pathsNotFound;\n\n // exit if queue is empty\n if (!q) return;\n\n // empty callback queue\n while (q.length) {\n q[0](bundleId, pathsNotFound);\n q.splice(0, 1);\n }\n}\n\n\n/**\n * Execute callbacks.\n * @param {Object or Function} args - The callback args\n * @param {string[]} depsNotFound - List of dependencies not found\n */\nfunction executeCallbacks(args, depsNotFound) {\n // accept function as argument\n if (args.call) args = {success: args};\n\n // success and error callbacks\n if (depsNotFound.length) (args.error || devnull)(depsNotFound);\n else (args.success || devnull)(args);\n}\n\n\n/**\n * Load individual file.\n * @param {string} path - The file path\n * @param {Function} callbackFn - The callback function\n */\nfunction loadFile(path, callbackFn, args, numTries) {\n var doc = document,\n async = args.async,\n maxTries = (args.numRetries || 0) + 1,\n beforeCallbackFn = args.before || devnull,\n pathStripped = path.replace(/^(css|img)!/, ''),\n isCss,\n e;\n\n numTries = numTries || 0;\n\n if (/(^css!|\\.css$)/.test(path)) {\n isCss = true;\n\n // css\n e = doc.createElement('link');\n e.rel = 'stylesheet';\n e.href = pathStripped; //.replace(/^css!/, ''); // remove \"css!\" prefix\n } else if (/(^img!|\\.(png|gif|jpg|svg)$)/.test(path)) {\n // image\n e = doc.createElement('img');\n e.src = pathStripped; \n } else {\n // javascript\n e = doc.createElement('script');\n e.src = path;\n e.async = async === undefined ? true : async;\n }\n\n e.onload = e.onerror = e.onbeforeload = function (ev) {\n var result = ev.type[0];\n\n // Note: The following code isolates IE using `hideFocus` and treats empty\n // stylesheets as failures to get around lack of onerror support\n if (isCss && 'hideFocus' in e) {\n try {\n if (!e.sheet.cssText.length) result = 'e';\n } catch (x) {\n // sheets objects created from load errors don't allow access to\n // `cssText`\n result = 'e';\n }\n }\n\n // handle retries in case of load failure\n if (result == 'e') {\n // increment counter\n numTries += 1;\n\n // exit function and try again\n if (numTries < maxTries) {\n return loadFile(path, callbackFn, args, numTries);\n }\n }\n\n // execute callback\n callbackFn(path, result, ev.defaultPrevented);\n };\n\n // add to document (unless callback returns `false`)\n if (beforeCallbackFn(path, e) !== false) doc.head.appendChild(e);\n}\n\n\n/**\n * Load multiple files.\n * @param {string[]} paths - The file paths\n * @param {Function} callbackFn - The callback function\n */\nfunction loadFiles(paths, callbackFn, args) {\n // listify paths\n paths = paths.push ? paths : [paths];\n\n var numWaiting = paths.length,\n x = numWaiting,\n pathsNotFound = [],\n fn,\n i;\n\n // define callback function\n fn = function(path, result, defaultPrevented) {\n // handle error\n if (result == 'e') pathsNotFound.push(path);\n\n // handle beforeload event. If defaultPrevented then that means the load\n // will be blocked (ex. Ghostery/ABP on Safari)\n if (result == 'b') {\n if (defaultPrevented) pathsNotFound.push(path);\n else return;\n }\n\n numWaiting--;\n if (!numWaiting) callbackFn(pathsNotFound);\n };\n\n // load scripts\n for (i=0; i < x; i++) loadFile(paths[i], fn, args);\n}\n\n\n/**\n * Initiate script load and register bundle.\n * @param {(string|string[])} paths - The file paths\n * @param {(string|Function)} [arg1] - The bundleId or success callback\n * @param {Function} [arg2] - The success or error callback\n * @param {Function} [arg3] - The error callback\n */\nfunction loadjs(paths, arg1, arg2) {\n var bundleId,\n args;\n\n // bundleId (if string)\n if (arg1 && arg1.trim) bundleId = arg1;\n\n // args (default is {})\n args = (bundleId ? arg2 : arg1) || {};\n\n // throw error if bundle is already defined\n if (bundleId) {\n if (bundleId in bundleIdCache) {\n throw \"LoadJS\";\n } else {\n bundleIdCache[bundleId] = true;\n }\n }\n\n // load scripts\n loadFiles(paths, function (pathsNotFound) {\n // execute callbacks\n executeCallbacks(args, pathsNotFound);\n\n // publish bundle load event\n publish(bundleId, pathsNotFound);\n }, args);\n}\n\n\n/**\n * Execute callbacks when dependencies have been satisfied.\n * @param {(string|string[])} deps - List of bundle ids\n * @param {Object} args - success/error arguments\n */\nloadjs.ready = function ready(deps, args) {\n // subscribe to bundle load event\n subscribe(deps, function (depsNotFound) {\n // execute callbacks\n executeCallbacks(args, depsNotFound);\n });\n\n return loadjs;\n};\n\n\n/**\n * Manually satisfy bundle dependencies.\n * @param {string} bundleId - The bundle id\n */\nloadjs.done = function done(bundleId) {\n publish(bundleId, []);\n};\n\n\n/**\n * Reset loadjs dependencies statuses\n */\nloadjs.reset = function reset() {\n bundleIdCache = {};\n bundleResultCache = {};\n bundleCallbackQueue = {};\n};\n\n\n/**\n * Determine if bundle has already been defined\n * @param String} bundleId - The bundle id\n */\nloadjs.isDefined = function isDefined(bundleId) {\n return bundleId in bundleIdCache;\n};\n\n\n// export\nreturn loadjs;\n\n}));\n","// ==========================================================================\n// Load an external script\n// ==========================================================================\n\nimport loadjs from 'loadjs';\n\nexport default function loadScript(url) {\n return new Promise((resolve, reject) => {\n loadjs(url, {\n success: resolve,\n error: reject,\n });\n });\n}\n","// ==========================================================================\n// Vimeo plugin\n// ==========================================================================\n\nimport captions from './../captions';\nimport controls from './../controls';\nimport ui from './../ui';\nimport { createElement, replaceElement, toggleClass } from './../utils/elements';\nimport { triggerEvent } from './../utils/events';\nimport fetch from './../utils/fetch';\nimport is from './../utils/is';\nimport loadScript from './../utils/loadScript';\nimport { format, stripHTML } from './../utils/strings';\nimport { buildUrlParams } from './../utils/urls';\n\n// Parse Vimeo ID from URL\nfunction parseId(url) {\n if (is.empty(url)) {\n return null;\n }\n\n if (is.number(Number(url))) {\n return url;\n }\n\n const regex = /^.*(vimeo.com\\/|video\\/)(\\d+).*/;\n return url.match(regex) ? RegExp.$2 : url;\n}\n\n// Get aspect ratio for dimensions\nfunction getAspectRatio(width, height) {\n const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h));\n const ratio = getRatio(width, height);\n return `${width / ratio}:${height / ratio}`;\n}\n\n// Set playback state and trigger change (only on actual change)\nfunction assurePlaybackState(play) {\n if (play && !this.embed.hasPlayed) {\n this.embed.hasPlayed = true;\n }\n if (this.media.paused === play) {\n this.media.paused = !play;\n triggerEvent.call(this, this.media, play ? 'play' : 'pause');\n }\n}\n\nconst vimeo = {\n setup() {\n // Add embed class for responsive\n toggleClass(this.elements.wrapper, this.config.classNames.embed, true);\n\n // Set intial ratio\n vimeo.setAspectRatio.call(this);\n\n // Load the API if not already\n if (!is.object(window.Vimeo)) {\n loadScript(this.config.urls.vimeo.sdk)\n .then(() => {\n vimeo.ready.call(this);\n })\n .catch(error => {\n this.debug.warn('Vimeo API failed to load', error);\n });\n } else {\n vimeo.ready.call(this);\n }\n },\n\n // Set aspect ratio\n // For Vimeo we have an extra 300% height <div> to hide the standard controls and UI\n setAspectRatio(input) {\n const [x, y] = (is.string(input) ? input : this.config.ratio).split(':');\n const padding = 100 / x * y;\n this.elements.wrapper.style.paddingBottom = `${padding}%`;\n\n if (this.supported.ui) {\n const height = 240;\n const offset = (height - padding) / (height / 50);\n\n this.media.style.transform = `translateY(-${offset}%)`;\n }\n },\n\n // API Ready\n ready() {\n const player = this;\n\n // Get Vimeo params for the iframe\n const options = {\n loop: player.config.loop.active,\n autoplay: player.autoplay,\n // muted: player.muted,\n byline: false,\n portrait: false,\n title: false,\n speed: true,\n transparent: 0,\n gesture: 'media',\n playsinline: !this.config.fullscreen.iosNative,\n };\n const params = buildUrlParams(options);\n\n // Get the source URL or ID\n let source = player.media.getAttribute('src');\n\n // Get from <div> if needed\n if (is.empty(source)) {\n source = player.media.getAttribute(player.config.attributes.embed.id);\n }\n\n const id = parseId(source);\n\n // Build an iframe\n const iframe = createElement('iframe');\n const src = format(player.config.urls.vimeo.iframe, id, params);\n iframe.setAttribute('src', src);\n iframe.setAttribute('allowfullscreen', '');\n iframe.setAttribute('allowtransparency', '');\n iframe.setAttribute('allow', 'autoplay');\n\n // Get poster, if already set\n const { poster } = player;\n\n // Inject the package\n const wrapper = createElement('div', { poster, class: player.config.classNames.embedContainer });\n wrapper.appendChild(iframe);\n player.media = replaceElement(wrapper, player.media);\n\n // Get poster image\n fetch(format(player.config.urls.vimeo.api, id), 'json').then(response => {\n if (is.empty(response)) {\n return;\n }\n\n // Get the URL for thumbnail\n const url = new URL(response[0].thumbnail_large);\n\n // Get original image\n url.pathname = `${url.pathname.split('_')[0]}.jpg`;\n\n // Set and show poster\n ui.setPoster.call(player, url.href).catch(() => {});\n });\n\n // Setup instance\n // https://github.com/vimeo/player.js\n player.embed = new window.Vimeo.Player(iframe, {\n autopause: player.config.autopause,\n muted: player.muted,\n });\n\n player.media.paused = true;\n player.media.currentTime = 0;\n\n // Disable native text track rendering\n if (player.supported.ui) {\n player.embed.disableTextTrack();\n }\n\n // Create a faux HTML5 API using the Vimeo API\n player.media.play = () => {\n assurePlaybackState.call(player, true);\n return player.embed.play();\n };\n\n player.media.pause = () => {\n assurePlaybackState.call(player, false);\n return player.embed.pause();\n };\n\n player.media.stop = () => {\n player.pause();\n player.currentTime = 0;\n };\n\n // Seeking\n let { currentTime } = player.media;\n Object.defineProperty(player.media, 'currentTime', {\n get() {\n return currentTime;\n },\n set(time) {\n // Vimeo will automatically play on seek if the video hasn't been played before\n\n // Get current paused state and volume etc\n const { embed, media, paused, volume } = player;\n const restorePause = paused && !embed.hasPlayed;\n\n // Set seeking state and trigger event\n media.seeking = true;\n triggerEvent.call(player, media, 'seeking');\n\n // If paused, mute until seek is complete\n Promise.resolve(restorePause && embed.setVolume(0))\n // Seek\n .then(() => embed.setCurrentTime(time))\n // Restore paused\n .then(() => restorePause && embed.pause())\n // Restore volume\n .then(() => restorePause && embed.setVolume(volume))\n .catch(() => {\n // Do nothing\n });\n },\n });\n\n // Playback speed\n let speed = player.config.speed.selected;\n Object.defineProperty(player.media, 'playbackRate', {\n get() {\n return speed;\n },\n set(input) {\n player.embed\n .setPlaybackRate(input)\n .then(() => {\n speed = input;\n triggerEvent.call(player, player.media, 'ratechange');\n })\n .catch(error => {\n // Hide menu item (and menu if empty)\n if (error.name === 'Error') {\n controls.setSpeedMenu.call(player, []);\n }\n });\n },\n });\n\n // Volume\n let { volume } = player.config;\n Object.defineProperty(player.media, 'volume', {\n get() {\n return volume;\n },\n set(input) {\n player.embed.setVolume(input).then(() => {\n volume = input;\n triggerEvent.call(player, player.media, 'volumechange');\n });\n },\n });\n\n // Muted\n let { muted } = player.config;\n Object.defineProperty(player.media, 'muted', {\n get() {\n return muted;\n },\n set(input) {\n const toggle = is.boolean(input) ? input : false;\n\n player.embed.setVolume(toggle ? 0 : player.config.volume).then(() => {\n muted = toggle;\n triggerEvent.call(player, player.media, 'volumechange');\n });\n },\n });\n\n // Loop\n let { loop } = player.config;\n Object.defineProperty(player.media, 'loop', {\n get() {\n return loop;\n },\n set(input) {\n const toggle = is.boolean(input) ? input : player.config.loop.active;\n\n player.embed.setLoop(toggle).then(() => {\n loop = toggle;\n });\n },\n });\n\n // Source\n let currentSrc;\n player.embed\n .getVideoUrl()\n .then(value => {\n currentSrc = value;\n })\n .catch(error => {\n this.debug.warn(error);\n });\n\n Object.defineProperty(player.media, 'currentSrc', {\n get() {\n return currentSrc;\n },\n });\n\n // Ended\n Object.defineProperty(player.media, 'ended', {\n get() {\n return player.currentTime === player.duration;\n },\n });\n\n // Set aspect ratio based on video size\n Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then(dimensions => {\n const ratio = getAspectRatio(dimensions[0], dimensions[1]);\n vimeo.setAspectRatio.call(this, ratio);\n });\n\n // Set autopause\n player.embed.setAutopause(player.config.autopause).then(state => {\n player.config.autopause = state;\n });\n\n // Get title\n player.embed.getVideoTitle().then(title => {\n player.config.title = title;\n ui.setTitle.call(this);\n });\n\n // Get current time\n player.embed.getCurrentTime().then(value => {\n currentTime = value;\n triggerEvent.call(player, player.media, 'timeupdate');\n });\n\n // Get duration\n player.embed.getDuration().then(value => {\n player.media.duration = value;\n triggerEvent.call(player, player.media, 'durationchange');\n });\n\n // Get captions\n player.embed.getTextTracks().then(tracks => {\n player.media.textTracks = tracks;\n captions.setup.call(player);\n });\n\n player.embed.on('cuechange', ({ cues = [] }) => {\n const strippedCues = cues.map(cue => stripHTML(cue.text));\n captions.updateCues.call(player, strippedCues);\n });\n\n player.embed.on('loaded', () => {\n // Assure state and events are updated on autoplay\n player.embed.getPaused().then(paused => {\n assurePlaybackState.call(player, !paused);\n if (!paused) {\n triggerEvent.call(player, player.media, 'playing');\n }\n });\n\n if (is.element(player.embed.element) && player.supported.ui) {\n const frame = player.embed.element;\n\n // Fix keyboard focus issues\n // https://github.com/sampotts/plyr/issues/317\n frame.setAttribute('tabindex', -1);\n }\n });\n\n player.embed.on('play', () => {\n assurePlaybackState.call(player, true);\n triggerEvent.call(player, player.media, 'playing');\n });\n\n player.embed.on('pause', () => {\n assurePlaybackState.call(player, false);\n });\n\n player.embed.on('timeupdate', data => {\n player.media.seeking = false;\n currentTime = data.seconds;\n triggerEvent.call(player, player.media, 'timeupdate');\n });\n\n player.embed.on('progress', data => {\n player.media.buffered = data.percent;\n triggerEvent.call(player, player.media, 'progress');\n\n // Check all loaded\n if (parseInt(data.percent, 10) === 1) {\n triggerEvent.call(player, player.media, 'canplaythrough');\n }\n\n // Get duration as if we do it before load, it gives an incorrect value\n // https://github.com/sampotts/plyr/issues/891\n player.embed.getDuration().then(value => {\n if (value !== player.media.duration) {\n player.media.duration = value;\n triggerEvent.call(player, player.media, 'durationchange');\n }\n });\n });\n\n player.embed.on('seeked', () => {\n player.media.seeking = false;\n triggerEvent.call(player, player.media, 'seeked');\n });\n\n player.embed.on('ended', () => {\n player.media.paused = true;\n triggerEvent.call(player, player.media, 'ended');\n });\n\n player.embed.on('error', detail => {\n player.media.error = detail;\n triggerEvent.call(player, player.media, 'error');\n });\n\n // Rebuild UI\n setTimeout(() => ui.build.call(player), 0);\n },\n};\n\nexport default vimeo;\n","// ==========================================================================\n// YouTube plugin\n// ==========================================================================\n\nimport controls from './../controls';\nimport ui from './../ui';\nimport { dedupe } from './../utils/arrays';\nimport { createElement, replaceElement, toggleClass } from './../utils/elements';\nimport { triggerEvent } from './../utils/events';\nimport fetch from './../utils/fetch';\nimport is from './../utils/is';\nimport loadImage from './../utils/loadImage';\nimport loadScript from './../utils/loadScript';\nimport { format, generateId } from './../utils/strings';\n\n// Parse YouTube ID from URL\nfunction parseId(url) {\n if (is.empty(url)) {\n return null;\n }\n\n const regex = /^.*(youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=|&v=)([^#&?]*).*/;\n return url.match(regex) ? RegExp.$2 : url;\n}\n\n// Standardise YouTube quality unit\nfunction mapQualityUnit(input) {\n const qualities = {\n hd2160: 2160,\n hd1440: 1440,\n hd1080: 1080,\n hd720: 720,\n large: 480,\n medium: 360,\n small: 240,\n tiny: 144,\n };\n\n const entry = Object.entries(qualities).find(entry => entry.includes(input));\n\n if (entry) {\n // Get the match corresponding to the input\n return entry.find(value => value !== input);\n }\n\n return 'default';\n}\n\nfunction mapQualityUnits(levels) {\n if (is.empty(levels)) {\n return levels;\n }\n\n return dedupe(levels.map(level => mapQualityUnit(level)));\n}\n\n// Set playback state and trigger change (only on actual change)\nfunction assurePlaybackState(play) {\n if (play && !this.embed.hasPlayed) {\n this.embed.hasPlayed = true;\n }\n if (this.media.paused === play) {\n this.media.paused = !play;\n triggerEvent.call(this, this.media, play ? 'play' : 'pause');\n }\n}\n\nconst youtube = {\n setup() {\n // Add embed class for responsive\n toggleClass(this.elements.wrapper, this.config.classNames.embed, true);\n\n // Set aspect ratio\n youtube.setAspectRatio.call(this);\n\n // Setup API\n if (is.object(window.YT) && is.function(window.YT.Player)) {\n youtube.ready.call(this);\n } else {\n // Load the API\n loadScript(this.config.urls.youtube.sdk).catch(error => {\n this.debug.warn('YouTube API failed to load', error);\n });\n\n // Setup callback for the API\n // YouTube has it's own system of course...\n window.onYouTubeReadyCallbacks = window.onYouTubeReadyCallbacks || [];\n\n // Add to queue\n window.onYouTubeReadyCallbacks.push(() => {\n youtube.ready.call(this);\n });\n\n // Set callback to process queue\n window.onYouTubeIframeAPIReady = () => {\n window.onYouTubeReadyCallbacks.forEach(callback => {\n callback();\n });\n };\n }\n },\n\n // Get the media title\n getTitle(videoId) {\n // Try via undocumented API method first\n // This method disappears now and then though...\n // https://github.com/sampotts/plyr/issues/709\n if (is.function(this.embed.getVideoData)) {\n const { title } = this.embed.getVideoData();\n\n if (is.empty(title)) {\n this.config.title = title;\n ui.setTitle.call(this);\n return;\n }\n }\n\n // Or via Google API\n const key = this.config.keys.google;\n if (is.string(key) && !is.empty(key)) {\n const url = format(this.config.urls.youtube.api, videoId, key);\n\n fetch(url)\n .then(result => {\n if (is.object(result)) {\n this.config.title = result.items[0].snippet.title;\n ui.setTitle.call(this);\n }\n })\n .catch(() => {});\n }\n },\n\n // Set aspect ratio\n setAspectRatio() {\n const ratio = this.config.ratio.split(':');\n this.elements.wrapper.style.paddingBottom = `${100 / ratio[0] * ratio[1]}%`;\n },\n\n // API ready\n ready() {\n const player = this;\n\n // Ignore already setup (race condition)\n const currentId = player.media.getAttribute('id');\n if (!is.empty(currentId) && currentId.startsWith('youtube-')) {\n return;\n }\n\n // Get the source URL or ID\n let source = player.media.getAttribute('src');\n\n // Get from <div> if needed\n if (is.empty(source)) {\n source = player.media.getAttribute(this.config.attributes.embed.id);\n }\n\n // Replace the <iframe> with a <div> due to YouTube API issues\n const videoId = parseId(source);\n const id = generateId(player.provider);\n\n // Get poster, if already set\n const { poster } = player;\n\n // Replace media element\n const container = createElement('div', { id, poster });\n player.media = replaceElement(container, player.media);\n\n // Id to poster wrapper\n const posterSrc = format => `https://img.youtube.com/vi/${videoId}/${format}default.jpg`;\n\n // Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)\n loadImage(posterSrc('maxres'), 121) // Higest quality and unpadded\n .catch(() => loadImage(posterSrc('sd'), 121)) // 480p padded 4:3\n .catch(() => loadImage(posterSrc('hq'))) // 360p padded 4:3. Always exists\n .then(image => ui.setPoster.call(player, image.src))\n .then(posterSrc => {\n // If the image is padded, use background-size \"cover\" instead (like youtube does too with their posters)\n if (!posterSrc.includes('maxres')) {\n player.elements.poster.style.backgroundSize = 'cover';\n }\n })\n .catch(() => {});\n\n // Setup instance\n // https://developers.google.com/youtube/iframe_api_reference\n player.embed = new window.YT.Player(id, {\n videoId,\n playerVars: {\n autoplay: player.config.autoplay ? 1 : 0, // Autoplay\n controls: player.supported.ui ? 0 : 1, // Only show controls if not fully supported\n rel: 0, // No related vids\n showinfo: 0, // Hide info\n iv_load_policy: 3, // Hide annotations\n modestbranding: 1, // Hide logos as much as possible (they still show one in the corner when paused)\n disablekb: 1, // Disable keyboard as we handle it\n playsinline: 1, // Allow iOS inline playback\n\n // Tracking for stats\n // origin: window ? `${window.location.protocol}//${window.location.host}` : null,\n widget_referrer: window ? window.location.href : null,\n\n // Captions are flaky on YouTube\n cc_load_policy: player.captions.active ? 1 : 0,\n cc_lang_pref: player.config.captions.language,\n },\n events: {\n onError(event) {\n // YouTube may fire onError twice, so only handle it once\n if (!player.media.error) {\n const code = event.data;\n // Messages copied from https://developers.google.com/youtube/iframe_api_reference#onError\n const message =\n {\n 2: 'The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.',\n 5: 'The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.',\n 100: 'The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.',\n 101: 'The owner of the requested video does not allow it to be played in embedded players.',\n 150: 'The owner of the requested video does not allow it to be played in embedded players.',\n }[code] || 'An unknown error occured';\n\n player.media.error = { code, message };\n\n triggerEvent.call(player, player.media, 'error');\n }\n },\n onPlaybackQualityChange() {\n triggerEvent.call(player, player.media, 'qualitychange', false, {\n quality: player.media.quality,\n });\n },\n onPlaybackRateChange(event) {\n // Get the instance\n const instance = event.target;\n\n // Get current speed\n player.media.playbackRate = instance.getPlaybackRate();\n\n triggerEvent.call(player, player.media, 'ratechange');\n },\n onReady(event) {\n // Get the instance\n const instance = event.target;\n\n // Get the title\n youtube.getTitle.call(player, videoId);\n\n // Create a faux HTML5 API using the YouTube API\n player.media.play = () => {\n assurePlaybackState.call(player, true);\n instance.playVideo();\n };\n\n player.media.pause = () => {\n assurePlaybackState.call(player, false);\n instance.pauseVideo();\n };\n\n player.media.stop = () => {\n instance.stopVideo();\n };\n\n player.media.duration = instance.getDuration();\n player.media.paused = true;\n\n // Seeking\n player.media.currentTime = 0;\n Object.defineProperty(player.media, 'currentTime', {\n get() {\n return Number(instance.getCurrentTime());\n },\n set(time) {\n // If paused, mute audio preventively (YouTube starts playing on seek if the video hasn't been played yet).\n if (player.paused) {\n player.embed.mute();\n }\n\n // Set seeking state and trigger event\n player.media.seeking = true;\n triggerEvent.call(player, player.media, 'seeking');\n\n // Seek after events sent\n instance.seekTo(time);\n },\n });\n\n // Playback speed\n Object.defineProperty(player.media, 'playbackRate', {\n get() {\n return instance.getPlaybackRate();\n },\n set(input) {\n instance.setPlaybackRate(input);\n },\n });\n\n // Quality\n Object.defineProperty(player.media, 'quality', {\n get() {\n return mapQualityUnit(instance.getPlaybackQuality());\n },\n set(input) {\n instance.setPlaybackQuality(mapQualityUnit(input));\n },\n });\n\n // Volume\n let { volume } = player.config;\n Object.defineProperty(player.media, 'volume', {\n get() {\n return volume;\n },\n set(input) {\n volume = input;\n instance.setVolume(volume * 100);\n triggerEvent.call(player, player.media, 'volumechange');\n },\n });\n\n // Muted\n let { muted } = player.config;\n Object.defineProperty(player.media, 'muted', {\n get() {\n return muted;\n },\n set(input) {\n const toggle = is.boolean(input) ? input : muted;\n muted = toggle;\n instance[toggle ? 'mute' : 'unMute']();\n triggerEvent.call(player, player.media, 'volumechange');\n },\n });\n\n // Source\n Object.defineProperty(player.media, 'currentSrc', {\n get() {\n return instance.getVideoUrl();\n },\n });\n\n // Ended\n Object.defineProperty(player.media, 'ended', {\n get() {\n return player.currentTime === player.duration;\n },\n });\n\n // Get available speeds\n player.options.speed = instance.getAvailablePlaybackRates();\n\n // Set the tabindex to avoid focus entering iframe\n if (player.supported.ui) {\n player.media.setAttribute('tabindex', -1);\n }\n\n triggerEvent.call(player, player.media, 'timeupdate');\n triggerEvent.call(player, player.media, 'durationchange');\n\n // Reset timer\n clearInterval(player.timers.buffering);\n\n // Setup buffering\n player.timers.buffering = setInterval(() => {\n // Get loaded % from YouTube\n player.media.buffered = instance.getVideoLoadedFraction();\n\n // Trigger progress only when we actually buffer something\n if (player.media.lastBuffered === null || player.media.lastBuffered < player.media.buffered) {\n triggerEvent.call(player, player.media, 'progress');\n }\n\n // Set last buffer point\n player.media.lastBuffered = player.media.buffered;\n\n // Bail if we're at 100%\n if (player.media.buffered === 1) {\n clearInterval(player.timers.buffering);\n\n // Trigger event\n triggerEvent.call(player, player.media, 'canplaythrough');\n }\n }, 200);\n\n // Rebuild UI\n setTimeout(() => ui.build.call(player), 50);\n },\n onStateChange(event) {\n // Get the instance\n const instance = event.target;\n\n // Reset timer\n clearInterval(player.timers.playing);\n\n const seeked = player.media.seeking && [1, 2].includes(event.data);\n\n if (seeked) {\n // Unset seeking and fire seeked event\n player.media.seeking = false;\n triggerEvent.call(player, player.media, 'seeked');\n }\n\n // Handle events\n // -1 Unstarted\n // 0 Ended\n // 1 Playing\n // 2 Paused\n // 3 Buffering\n // 5 Video cued\n switch (event.data) {\n case -1:\n // Update scrubber\n triggerEvent.call(player, player.media, 'timeupdate');\n\n // Get loaded % from YouTube\n player.media.buffered = instance.getVideoLoadedFraction();\n triggerEvent.call(player, player.media, 'progress');\n\n break;\n\n case 0:\n assurePlaybackState.call(player, false);\n\n // YouTube doesn't support loop for a single video, so mimick it.\n if (player.media.loop) {\n // YouTube needs a call to `stopVideo` before playing again\n instance.stopVideo();\n instance.playVideo();\n } else {\n triggerEvent.call(player, player.media, 'ended');\n }\n\n break;\n\n case 1:\n // Restore paused state (YouTube starts playing on seek if the video hasn't been played yet)\n if (player.media.paused && !player.embed.hasPlayed) {\n player.media.pause();\n } else {\n assurePlaybackState.call(player, true);\n\n triggerEvent.call(player, player.media, 'playing');\n\n // Poll to get playback progress\n player.timers.playing = setInterval(() => {\n triggerEvent.call(player, player.media, 'timeupdate');\n }, 50);\n\n // Check duration again due to YouTube bug\n // https://github.com/sampotts/plyr/issues/374\n // https://code.google.com/p/gdata-issues/issues/detail?id=8690\n if (player.media.duration !== instance.getDuration()) {\n player.media.duration = instance.getDuration();\n triggerEvent.call(player, player.media, 'durationchange');\n }\n\n // Get quality\n controls.setQualityMenu.call(\n player,\n mapQualityUnits(instance.getAvailableQualityLevels()),\n );\n }\n\n break;\n\n case 2:\n // Restore audio (YouTube starts playing on seek if the video hasn't been played yet)\n if (!player.muted) {\n player.embed.unMute();\n }\n assurePlaybackState.call(player, false);\n\n break;\n\n default:\n break;\n }\n\n triggerEvent.call(player, player.elements.container, 'statechange', false, {\n code: event.data,\n });\n },\n },\n });\n },\n};\n\nexport default youtube;\n","// ==========================================================================\n// Plyr Media\n// ==========================================================================\n\nimport html5 from './html5';\nimport vimeo from './plugins/vimeo';\nimport youtube from './plugins/youtube';\nimport { createElement, toggleClass, wrap } from './utils/elements';\n\nconst media = {\n // Setup media\n setup() {\n // If there's no media, bail\n if (!this.media) {\n this.debug.warn('No media element found!');\n return;\n }\n\n // Add type class\n toggleClass(this.elements.container, this.config.classNames.type.replace('{0}', this.type), true);\n\n // Add provider class\n toggleClass(this.elements.container, this.config.classNames.provider.replace('{0}', this.provider), true);\n\n // Add video class for embeds\n // This will require changes if audio embeds are added\n if (this.isEmbed) {\n toggleClass(this.elements.container, this.config.classNames.type.replace('{0}', 'video'), true);\n }\n\n // Inject the player wrapper\n if (this.isVideo) {\n // Create the wrapper div\n this.elements.wrapper = createElement('div', {\n class: this.config.classNames.video,\n });\n\n // Wrap the video in a container\n wrap(this.media, this.elements.wrapper);\n\n // Faux poster container\n this.elements.poster = createElement('div', {\n class: this.config.classNames.poster,\n });\n\n this.elements.wrapper.appendChild(this.elements.poster);\n }\n\n if (this.isHTML5) {\n html5.extend.call(this);\n } else if (this.isYouTube) {\n youtube.setup.call(this);\n } else if (this.isVimeo) {\n vimeo.setup.call(this);\n }\n },\n};\n\nexport default media;\n","// ==========================================================================\n// Advertisement plugin using Google IMA HTML5 SDK\n// Create an account with our ad partner, vi here:\n// https://www.vi.ai/publisher-video-monetization/\n// ==========================================================================\n\n/* global google */\n\nimport i18n from '../i18n';\nimport { createElement } from './../utils/elements';\nimport { triggerEvent } from './../utils/events';\nimport is from './../utils/is';\nimport loadScript from './../utils/loadScript';\nimport { formatTime } from './../utils/time';\nimport { buildUrlParams } from './../utils/urls';\n\nclass Ads {\n /**\n * Ads constructor.\n * @param {object} player\n * @return {Ads}\n */\n constructor(player) {\n this.player = player;\n this.publisherId = player.config.ads.publisherId;\n this.playing = false;\n this.initialized = false;\n this.elements = {\n container: null,\n displayContainer: null,\n };\n this.manager = null;\n this.loader = null;\n this.cuePoints = null;\n this.events = {};\n this.safetyTimer = null;\n this.countdownTimer = null;\n\n // Setup a promise to resolve when the IMA manager is ready\n this.managerPromise = new Promise((resolve, reject) => {\n // The ad is loaded and ready\n this.on('loaded', resolve);\n\n // Ads failed\n this.on('error', reject);\n });\n\n this.load();\n }\n\n get enabled() {\n return this.player.isVideo && this.player.config.ads.enabled && !is.empty(this.publisherId);\n }\n\n /**\n * Load the IMA SDK\n */\n load() {\n if (this.enabled) {\n // Check if the Google IMA3 SDK is loaded or load it ourselves\n if (!is.object(window.google) || !is.object(window.google.ima)) {\n loadScript(this.player.config.urls.googleIMA.sdk)\n .then(() => {\n this.ready();\n })\n .catch(() => {\n // Script failed to load or is blocked\n this.trigger('error', new Error('Google IMA SDK failed to load'));\n });\n } else {\n this.ready();\n }\n }\n }\n\n /**\n * Get the ads instance ready\n */\n ready() {\n // Start ticking our safety timer. If the whole advertisement\n // thing doesn't resolve within our set time; we bail\n this.startSafetyTimer(12000, 'ready()');\n\n // Clear the safety timer\n this.managerPromise.then(() => {\n this.clearSafetyTimer('onAdsManagerLoaded()');\n });\n\n // Set listeners on the Plyr instance\n this.listeners();\n\n // Setup the IMA SDK\n this.setupIMA();\n }\n\n // Build the default tag URL\n get tagUrl() {\n const params = {\n AV_PUBLISHERID: '58c25bb0073ef448b1087ad6',\n AV_CHANNELID: '5a0458dc28a06145e4519d21',\n AV_URL: location.hostname,\n cb: Date.now(),\n AV_WIDTH: 640,\n AV_HEIGHT: 480,\n AV_CDIM2: this.publisherId,\n };\n\n const base = 'https://go.aniview.com/api/adserver6/vast/';\n\n return `${base}?${buildUrlParams(params)}`;\n }\n\n /**\n * In order for the SDK to display ads for our video, we need to tell it where to put them,\n * so here we define our ad container. This div is set up to render on top of the video player.\n * Using the code below, we tell the SDK to render ads within that div. We also provide a\n * handle to the content video player - the SDK will poll the current time of our player to\n * properly place mid-rolls. After we create the ad display container, we initialize it. On\n * mobile devices, this initialization is done as the result of a user action.\n */\n setupIMA() {\n // Create the container for our advertisements\n this.elements.container = createElement('div', {\n class: this.player.config.classNames.ads,\n });\n this.player.elements.container.appendChild(this.elements.container);\n\n // So we can run VPAID2\n google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED);\n\n // Set language\n google.ima.settings.setLocale(this.player.config.ads.language);\n\n // We assume the adContainer is the video container of the plyr element\n // that will house the ads\n this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container);\n\n // Request video ads to be pre-loaded\n this.requestAds();\n }\n\n /**\n * Request advertisements\n */\n requestAds() {\n const { container } = this.player.elements;\n\n try {\n // Create ads loader\n this.loader = new google.ima.AdsLoader(this.elements.displayContainer);\n\n // Listen and respond to ads loaded and error events\n this.loader.addEventListener(\n google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,\n event => this.onAdsManagerLoaded(event),\n false,\n );\n this.loader.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error), false);\n\n // Request video ads\n const request = new google.ima.AdsRequest();\n request.adTagUrl = this.tagUrl;\n\n // Specify the linear and nonlinear slot sizes. This helps the SDK\n // to select the correct creative if multiple are returned\n request.linearAdSlotWidth = container.offsetWidth;\n request.linearAdSlotHeight = container.offsetHeight;\n request.nonLinearAdSlotWidth = container.offsetWidth;\n request.nonLinearAdSlotHeight = container.offsetHeight;\n\n // We only overlay ads as we only support video.\n request.forceNonLinearFullSlot = false;\n\n // Mute based on current state\n request.setAdWillPlayMuted(!this.player.muted);\n\n this.loader.requestAds(request);\n } catch (e) {\n this.onAdError(e);\n }\n }\n\n /**\n * Update the ad countdown\n * @param {boolean} start\n */\n pollCountdown(start = false) {\n if (!start) {\n clearInterval(this.countdownTimer);\n this.elements.container.removeAttribute('data-badge-text');\n return;\n }\n\n const update = () => {\n const time = formatTime(Math.max(this.manager.getRemainingTime(), 0));\n const label = `${i18n.get('advertisement', this.player.config)} - ${time}`;\n this.elements.container.setAttribute('data-badge-text', label);\n };\n\n this.countdownTimer = setInterval(update, 100);\n }\n\n /**\n * This method is called whenever the ads are ready inside the AdDisplayContainer\n * @param {Event} adsManagerLoadedEvent\n */\n onAdsManagerLoaded(event) {\n // Get the ads manager\n const settings = new google.ima.AdsRenderingSettings();\n\n // Tell the SDK to save and restore content video state on our behalf\n settings.restoreCustomPlaybackStateOnAdBreakComplete = true;\n settings.enablePreloading = true;\n\n // The SDK is polling currentTime on the contentPlayback. And needs a duration\n // so it can determine when to start the mid- and post-roll\n this.manager = event.getAdsManager(this.player, settings);\n\n // Get the cue points for any mid-rolls by filtering out the pre- and post-roll\n this.cuePoints = this.manager.getCuePoints();\n\n // Add advertisement cue's within the time line if available\n if (!is.empty(this.cuePoints)) {\n this.cuePoints.forEach(cuePoint => {\n if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < this.player.duration) {\n const seekElement = this.player.elements.progress;\n\n if (is.element(seekElement)) {\n const cuePercentage = 100 / this.player.duration * cuePoint;\n const cue = createElement('span', {\n class: this.player.config.classNames.cues,\n });\n\n cue.style.left = `${cuePercentage.toString()}%`;\n seekElement.appendChild(cue);\n }\n }\n });\n }\n\n // Get skippable state\n // TODO: Skip button\n // this.player.debug.warn(this.manager.getAdSkippableState());\n\n // Set volume to match player\n this.manager.setVolume(this.player.volume);\n\n // Add listeners to the required events\n // Advertisement error events\n this.manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error));\n\n // Advertisement regular events\n Object.keys(google.ima.AdEvent.Type).forEach(type => {\n this.manager.addEventListener(google.ima.AdEvent.Type[type], event => this.onAdEvent(event));\n });\n\n // Resolve our adsManager\n this.trigger('loaded');\n }\n\n /**\n * This is where all the event handling takes place. Retrieve the ad from the event. Some\n * events (e.g. ALL_ADS_COMPLETED) don't have the ad object associated\n * https://developers.google.com/interactive-media-ads/docs/sdks/html5/v3/apis#ima.AdEvent.Type\n * @param {Event} event\n */\n onAdEvent(event) {\n const { container } = this.player.elements;\n\n // Retrieve the ad from the event. Some events (e.g. ALL_ADS_COMPLETED)\n // don't have ad object associated\n const ad = event.getAd();\n\n // Proxy event\n const dispatchEvent = type => {\n const event = `ads${type.replace(/_/g, '').toLowerCase()}`;\n triggerEvent.call(this.player, this.player.media, event);\n };\n\n switch (event.type) {\n case google.ima.AdEvent.Type.LOADED:\n // This is the first event sent for an ad - it is possible to determine whether the\n // ad is a video ad or an overlay\n this.trigger('loaded');\n\n // Bubble event\n dispatchEvent(event.type);\n\n // Start countdown\n this.pollCountdown(true);\n\n if (!ad.isLinear()) {\n // Position AdDisplayContainer correctly for overlay\n ad.width = container.offsetWidth;\n ad.height = container.offsetHeight;\n }\n\n // console.info('Ad type: ' + event.getAd().getAdPodInfo().getPodIndex());\n // console.info('Ad time: ' + event.getAd().getAdPodInfo().getTimeOffset());\n break;\n\n case google.ima.AdEvent.Type.ALL_ADS_COMPLETED:\n // All ads for the current videos are done. We can now request new advertisements\n // in case the video is re-played\n\n // Fire event\n dispatchEvent(event.type);\n\n // TODO: Example for what happens when a next video in a playlist would be loaded.\n // So here we load a new video when all ads are done.\n // Then we load new ads within a new adsManager. When the video\n // Is started - after - the ads are loaded, then we get ads.\n // You can also easily test cancelling and reloading by running\n // player.ads.cancel() and player.ads.play from the console I guess.\n // this.player.source = {\n // type: 'video',\n // title: 'View From A Blue Moon',\n // sources: [{\n // src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4', type:\n // 'video/mp4', }], poster:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg', tracks:\n // [ { kind: 'captions', label: 'English', srclang: 'en', src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt',\n // default: true, }, { kind: 'captions', label: 'French', srclang: 'fr', src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt', }, ],\n // };\n\n // TODO: So there is still this thing where a video should only be allowed to start\n // playing when the IMA SDK is ready or has failed\n\n this.loadAds();\n break;\n\n case google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED:\n // This event indicates the ad has started - the video player can adjust the UI,\n // for example display a pause button and remaining time. Fired when content should\n // be paused. This usually happens right before an ad is about to cover the content\n\n dispatchEvent(event.type);\n\n this.pauseContent();\n\n break;\n\n case google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED:\n // This event indicates the ad has finished - the video player can perform\n // appropriate UI actions, such as removing the timer for remaining time detection.\n // Fired when content should be resumed. This usually happens when an ad finishes\n // or collapses\n\n dispatchEvent(event.type);\n\n this.pollCountdown();\n\n this.resumeContent();\n\n break;\n\n case google.ima.AdEvent.Type.STARTED:\n case google.ima.AdEvent.Type.MIDPOINT:\n case google.ima.AdEvent.Type.COMPLETE:\n case google.ima.AdEvent.Type.IMPRESSION:\n case google.ima.AdEvent.Type.CLICK:\n dispatchEvent(event.type);\n break;\n\n default:\n break;\n }\n }\n\n /**\n * Any ad error handling comes through here\n * @param {Event} event\n */\n onAdError(event) {\n this.cancel();\n this.player.debug.warn('Ads error', event);\n }\n\n /**\n * Setup hooks for Plyr and window events. This ensures\n * the mid- and post-roll launch at the correct time. And\n * resize the advertisement when the player resizes\n */\n listeners() {\n const { container } = this.player.elements;\n let time;\n\n // Add listeners to the required events\n this.player.on('ended', () => {\n this.loader.contentComplete();\n });\n\n this.player.on('seeking', () => {\n time = this.player.currentTime;\n return time;\n });\n\n this.player.on('seeked', () => {\n const seekedTime = this.player.currentTime;\n\n if (is.empty(this.cuePoints)) {\n return;\n }\n\n this.cuePoints.forEach((cuePoint, index) => {\n if (time < cuePoint && cuePoint < seekedTime) {\n this.manager.discardAdBreak();\n this.cuePoints.splice(index, 1);\n }\n });\n });\n\n // Listen to the resizing of the window. And resize ad accordingly\n // TODO: eventually implement ResizeObserver\n window.addEventListener('resize', () => {\n if (this.manager) {\n this.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);\n }\n });\n }\n\n /**\n * Initialize the adsManager and start playing advertisements\n */\n play() {\n const { container } = this.player.elements;\n\n if (!this.managerPromise) {\n this.resumeContent();\n }\n\n // Play the requested advertisement whenever the adsManager is ready\n this.managerPromise\n .then(() => {\n // Initialize the container. Must be done via a user action on mobile devices\n this.elements.displayContainer.initialize();\n\n try {\n if (!this.initialized) {\n // Initialize the ads manager. Ad rules playlist will start at this time\n this.manager.init(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);\n\n // Call play to start showing the ad. Single video and overlay ads will\n // start at this time; the call will be ignored for ad rules\n this.manager.start();\n }\n\n this.initialized = true;\n } catch (adError) {\n // An error may be thrown if there was a problem with the\n // VAST response\n this.onAdError(adError);\n }\n })\n .catch(() => {});\n }\n\n /**\n * Resume our video\n */\n resumeContent() {\n // Hide the advertisement container\n this.elements.container.style.zIndex = '';\n\n // Ad is stopped\n this.playing = false;\n\n // Play our video\n if (this.player.currentTime < this.player.duration) {\n this.player.play();\n }\n }\n\n /**\n * Pause our video\n */\n pauseContent() {\n // Show the advertisement container\n this.elements.container.style.zIndex = 3;\n\n // Ad is playing.\n this.playing = true;\n\n // Pause our video.\n this.player.pause();\n }\n\n /**\n * Destroy the adsManager so we can grab new ads after this. If we don't then we're not\n * allowed to call new ads based on google policies, as they interpret this as an accidental\n * video requests. https://developers.google.com/interactive-\n * media-ads/docs/sdks/android/faq#8\n */\n cancel() {\n // Pause our video\n if (this.initialized) {\n this.resumeContent();\n }\n\n // Tell our instance that we're done for now\n this.trigger('error');\n\n // Re-create our adsManager\n this.loadAds();\n }\n\n /**\n * Re-create our adsManager\n */\n loadAds() {\n // Tell our adsManager to go bye bye\n this.managerPromise\n .then(() => {\n // Destroy our adsManager\n if (this.manager) {\n this.manager.destroy();\n }\n\n // Re-set our adsManager promises\n this.managerPromise = new Promise(resolve => {\n this.on('loaded', resolve);\n this.player.debug.log(this.manager);\n });\n\n // Now request some new advertisements\n this.requestAds();\n })\n .catch(() => {});\n }\n\n /**\n * Handles callbacks after an ad event was invoked\n * @param {string} event - Event type\n */\n trigger(event, ...args) {\n const handlers = this.events[event];\n\n if (is.array(handlers)) {\n handlers.forEach(handler => {\n if (is.function(handler)) {\n handler.apply(this, args);\n }\n });\n }\n }\n\n /**\n * Add event listeners\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n * @return {Ads}\n */\n on(event, callback) {\n if (!is.array(this.events[event])) {\n this.events[event] = [];\n }\n\n this.events[event].push(callback);\n\n return this;\n }\n\n /**\n * Setup a safety timer for when the ad network doesn't respond for whatever reason.\n * The advertisement has 12 seconds to get its things together. We stop this timer when the\n * advertisement is playing, or when a user action is required to start, then we clear the\n * timer on ad ready\n * @param {number} time\n * @param {string} from\n */\n startSafetyTimer(time, from) {\n this.player.debug.log(`Safety timer invoked from: ${from}`);\n\n this.safetyTimer = setTimeout(() => {\n this.cancel();\n this.clearSafetyTimer('startSafetyTimer()');\n }, time);\n }\n\n /**\n * Clear our safety timer(s)\n * @param {string} from\n */\n clearSafetyTimer(from) {\n if (!is.nullOrUndefined(this.safetyTimer)) {\n this.player.debug.log(`Safety timer cleared from: ${from}`);\n\n clearTimeout(this.safetyTimer);\n this.safetyTimer = null;\n }\n }\n}\n\nexport default Ads;\n","// ==========================================================================\n// Plyr source update\n// ==========================================================================\n\nimport { providers } from './config/types';\nimport html5 from './html5';\nimport media from './media';\nimport support from './support';\nimport ui from './ui';\nimport { createElement, insertElement, removeElement } from './utils/elements';\nimport is from './utils/is';\nimport { getDeep } from './utils/objects';\n\nconst source = {\n // Add elements to HTML5 media (source, tracks, etc)\n insertElements(type, attributes) {\n if (is.string(attributes)) {\n insertElement(type, this.media, {\n src: attributes,\n });\n } else if (is.array(attributes)) {\n attributes.forEach(attribute => {\n insertElement(type, this.media, attribute);\n });\n }\n },\n\n // Update source\n // Sources are not checked for support so be careful\n change(input) {\n if (!getDeep(input, 'sources.length')) {\n this.debug.warn('Invalid source format');\n return;\n }\n\n // Cancel current network requests\n html5.cancelRequests.call(this);\n\n // Destroy instance and re-setup\n this.destroy.call(\n this,\n () => {\n // Reset quality options\n this.options.quality = [];\n\n // Remove elements\n removeElement(this.media);\n this.media = null;\n\n // Reset class name\n if (is.element(this.elements.container)) {\n this.elements.container.removeAttribute('class');\n }\n\n // Set the type and provider\n const { sources, type } = input;\n const [{ provider = providers.html5, src }] = sources;\n const tagName = provider === 'html5' ? type : 'div';\n const attributes = provider === 'html5' ? {} : { src };\n\n Object.assign(this, {\n provider,\n type,\n // Check for support\n supported: support.check(type, provider, this.config.playsinline),\n // Create new element\n media: createElement(tagName, attributes),\n });\n\n // Inject the new element\n this.elements.container.appendChild(this.media);\n\n // Autoplay the new source?\n if (is.boolean(input.autoplay)) {\n this.config.autoplay = input.autoplay;\n }\n\n // Set attributes for audio and video\n if (this.isHTML5) {\n if (this.config.crossorigin) {\n this.media.setAttribute('crossorigin', '');\n }\n if (this.config.autoplay) {\n this.media.setAttribute('autoplay', '');\n }\n if (!is.empty(input.poster)) {\n this.poster = input.poster;\n }\n if (this.config.loop.active) {\n this.media.setAttribute('loop', '');\n }\n if (this.config.muted) {\n this.media.setAttribute('muted', '');\n }\n if (this.config.playsinline) {\n this.media.setAttribute('playsinline', '');\n }\n }\n\n // Restore class hook\n ui.addStyleHook.call(this);\n\n // Set new sources for html5\n if (this.isHTML5) {\n source.insertElements.call(this, 'source', sources);\n }\n\n // Set video title\n this.config.title = input.title;\n\n // Set up from scratch\n media.setup.call(this);\n\n // HTML5 stuff\n if (this.isHTML5) {\n // Setup captions\n if ('tracks' in input) {\n source.insertElements.call(this, 'track', input.tracks);\n }\n\n // Load HTML5 sources\n this.media.load();\n }\n\n // If HTML5 or embed but not fully supported, setupInterface and call ready now\n if (this.isHTML5 || (this.isEmbed && !this.supported.ui)) {\n // Setup interface\n ui.build.call(this);\n }\n\n // Update the fullscreen support\n this.fullscreen.update();\n },\n true,\n );\n },\n};\n\nexport default source;\n","// ==========================================================================\n// Plyr\n// plyr.js v3.3.15\n// https://github.com/sampotts/plyr\n// License: The MIT License (MIT)\n// ==========================================================================\n\nimport captions from './captions';\nimport defaults from './config/defaults';\nimport { getProviderByUrl, providers, types } from './config/types';\nimport Console from './console';\nimport controls from './controls';\nimport Fullscreen from './fullscreen';\nimport Listeners from './listeners';\nimport media from './media';\nimport Ads from './plugins/ads';\nimport source from './source';\nimport Storage from './storage';\nimport support from './support';\nimport ui from './ui';\nimport { closest } from './utils/arrays';\nimport { createElement, hasClass, removeElement, replaceElement, toggleClass, wrap } from './utils/elements';\nimport { off, on, once, triggerEvent, unbindListeners } from './utils/events';\nimport is from './utils/is';\nimport loadSprite from './utils/loadSprite';\nimport { cloneDeep, extend } from './utils/objects';\nimport { parseUrl } from './utils/urls';\n\n// Private properties\n// TODO: Use a WeakMap for private globals\n// const globals = new WeakMap();\n\n// Plyr instance\nclass Plyr {\n constructor(target, options) {\n this.timers = {};\n\n // State\n this.ready = false;\n this.loading = false;\n this.failed = false;\n\n // Touch device\n this.touch = support.touch;\n\n // Set the media element\n this.media = target;\n\n // String selector passed\n if (is.string(this.media)) {\n this.media = document.querySelectorAll(this.media);\n }\n\n // jQuery, NodeList or Array passed, use first element\n if ((window.jQuery && this.media instanceof jQuery) || is.nodeList(this.media) || is.array(this.media)) {\n // eslint-disable-next-line\n this.media = this.media[0];\n }\n\n // Set config\n this.config = extend(\n {},\n defaults,\n Plyr.defaults,\n options || {},\n (() => {\n try {\n return JSON.parse(this.media.getAttribute('data-plyr-config'));\n } catch (e) {\n return {};\n }\n })(),\n );\n\n // Elements cache\n this.elements = {\n container: null,\n captions: null,\n buttons: {},\n display: {},\n progress: {},\n inputs: {},\n settings: {\n popup: null,\n menu: null,\n panels: {},\n buttons: {},\n },\n };\n\n // Captions\n this.captions = {\n active: null,\n currentTrack: -1,\n meta: new WeakMap(),\n };\n\n // Fullscreen\n this.fullscreen = {\n active: false,\n };\n\n // Options\n this.options = {\n speed: [],\n quality: [],\n };\n\n // Debugging\n // TODO: move to globals\n this.debug = new Console(this.config.debug);\n\n // Log config options and support\n this.debug.log('Config', this.config);\n this.debug.log('Support', support);\n\n // We need an element to setup\n if (is.nullOrUndefined(this.media) || !is.element(this.media)) {\n this.debug.error('Setup failed: no suitable element passed');\n return;\n }\n\n // Bail if the element is initialized\n if (this.media.plyr) {\n this.debug.warn('Target already setup');\n return;\n }\n\n // Bail if not enabled\n if (!this.config.enabled) {\n this.debug.error('Setup failed: disabled by config');\n return;\n }\n\n // Bail if disabled or no basic support\n // You may want to disable certain UAs etc\n if (!support.check().api) {\n this.debug.error('Setup failed: no support');\n return;\n }\n\n // Cache original element state for .destroy()\n const clone = this.media.cloneNode(true);\n clone.autoplay = false;\n this.elements.original = clone;\n\n // Set media type based on tag or data attribute\n // Supported: video, audio, vimeo, youtube\n const type = this.media.tagName.toLowerCase();\n\n // Embed properties\n let iframe = null;\n let url = null;\n\n // Different setup based on type\n switch (type) {\n case 'div':\n // Find the frame\n iframe = this.media.querySelector('iframe');\n\n // <iframe> type\n if (is.element(iframe)) {\n // Detect provider\n url = parseUrl(iframe.getAttribute('src'));\n this.provider = getProviderByUrl(url.toString());\n\n // Rework elements\n this.elements.container = this.media;\n this.media = iframe;\n\n // Reset classname\n this.elements.container.className = '';\n\n // Get attributes from URL and set config\n if (url.searchParams.length) {\n const truthy = ['1', 'true'];\n\n if (truthy.includes(url.searchParams.get('autoplay'))) {\n this.config.autoplay = true;\n }\n if (truthy.includes(url.searchParams.get('loop'))) {\n this.config.loop.active = true;\n }\n\n // TODO: replace fullscreen.iosNative with this playsinline config option\n // YouTube requires the playsinline in the URL\n if (this.isYouTube) {\n this.config.playsinline = truthy.includes(url.searchParams.get('playsinline'));\n } else {\n this.config.playsinline = true;\n }\n }\n } else {\n // <div> with attributes\n this.provider = this.media.getAttribute(this.config.attributes.embed.provider);\n\n // Remove attribute\n this.media.removeAttribute(this.config.attributes.embed.provider);\n }\n\n // Unsupported or missing provider\n if (is.empty(this.provider) || !Object.keys(providers).includes(this.provider)) {\n this.debug.error('Setup failed: Invalid provider');\n return;\n }\n\n // Audio will come later for external providers\n this.type = types.video;\n\n break;\n\n case 'video':\n case 'audio':\n this.type = type;\n this.provider = providers.html5;\n\n // Get config from attributes\n if (this.media.hasAttribute('crossorigin')) {\n this.config.crossorigin = true;\n }\n if (this.media.hasAttribute('autoplay')) {\n this.config.autoplay = true;\n }\n if (this.media.hasAttribute('playsinline')) {\n this.config.playsinline = true;\n }\n if (this.media.hasAttribute('muted')) {\n this.config.muted = true;\n }\n if (this.media.hasAttribute('loop')) {\n this.config.loop.active = true;\n }\n\n break;\n\n default:\n this.debug.error('Setup failed: unsupported type');\n return;\n }\n\n // Check for support again but with type\n this.supported = support.check(this.type, this.provider, this.config.playsinline);\n\n // If no support for even API, bail\n if (!this.supported.api) {\n this.debug.error('Setup failed: no support');\n return;\n }\n\n this.eventListeners = [];\n\n // Create listeners\n this.listeners = new Listeners(this);\n\n // Setup local storage for user settings\n this.storage = new Storage(this);\n\n // Store reference\n this.media.plyr = this;\n\n // Wrap media\n if (!is.element(this.elements.container)) {\n this.elements.container = createElement('div');\n wrap(this.media, this.elements.container);\n }\n\n // Add style hook\n ui.addStyleHook.call(this);\n\n // Setup media\n media.setup.call(this);\n\n // Listen for events if debugging\n if (this.config.debug) {\n on.call(this, this.elements.container, this.config.events.join(' '), event => {\n this.debug.log(`event: ${event.type}`);\n });\n }\n\n // Setup interface\n // If embed but not fully supported, build interface now to avoid flash of controls\n if (this.isHTML5 || (this.isEmbed && !this.supported.ui)) {\n ui.build.call(this);\n }\n\n // Container listeners\n this.listeners.container();\n\n // Global listeners\n this.listeners.global();\n\n // Setup fullscreen\n this.fullscreen = new Fullscreen(this);\n\n // Setup ads if provided\n this.ads = new Ads(this);\n\n // Autoplay if required\n if (this.config.autoplay) {\n this.play();\n }\n }\n\n // ---------------------------------------\n // API\n // ---------------------------------------\n\n /**\n * Types and provider helpers\n */\n get isHTML5() {\n return Boolean(this.provider === providers.html5);\n }\n get isEmbed() {\n return Boolean(this.isYouTube || this.isVimeo);\n }\n get isYouTube() {\n return Boolean(this.provider === providers.youtube);\n }\n get isVimeo() {\n return Boolean(this.provider === providers.vimeo);\n }\n get isVideo() {\n return Boolean(this.type === types.video);\n }\n get isAudio() {\n return Boolean(this.type === types.audio);\n }\n\n /**\n * Play the media, or play the advertisement (if they are not blocked)\n */\n play() {\n if (!is.function(this.media.play)) {\n return null;\n }\n\n // Return the promise (for HTML5)\n return this.media.play();\n }\n\n /**\n * Pause the media\n */\n pause() {\n if (!this.playing || !is.function(this.media.pause)) {\n return;\n }\n\n this.media.pause();\n }\n\n /**\n * Get playing state\n */\n get playing() {\n return Boolean(this.ready && !this.paused && !this.ended);\n }\n\n /**\n * Get paused state\n */\n get paused() {\n return Boolean(this.media.paused);\n }\n\n /**\n * Get stopped state\n */\n get stopped() {\n return Boolean(this.paused && this.currentTime === 0);\n }\n\n /**\n * Get ended state\n */\n get ended() {\n return Boolean(this.media.ended);\n }\n\n /**\n * Toggle playback based on current status\n * @param {boolean} input\n */\n togglePlay(input) {\n // Toggle based on current state if nothing passed\n const toggle = is.boolean(input) ? input : !this.playing;\n\n if (toggle) {\n this.play();\n } else {\n this.pause();\n }\n }\n\n /**\n * Stop playback\n */\n stop() {\n if (this.isHTML5) {\n this.pause();\n this.restart();\n } else if (is.function(this.media.stop)) {\n this.media.stop();\n }\n }\n\n /**\n * Restart playback\n */\n restart() {\n this.currentTime = 0;\n }\n\n /**\n * Rewind\n * @param {number} seekTime - how far to rewind in seconds. Defaults to the config.seekTime\n */\n rewind(seekTime) {\n this.currentTime = this.currentTime - (is.number(seekTime) ? seekTime : this.config.seekTime);\n }\n\n /**\n * Fast forward\n * @param {number} seekTime - how far to fast forward in seconds. Defaults to the config.seekTime\n */\n forward(seekTime) {\n this.currentTime = this.currentTime + (is.number(seekTime) ? seekTime : this.config.seekTime);\n }\n\n /**\n * Seek to a time\n * @param {number} input - where to seek to in seconds. Defaults to 0 (the start)\n */\n set currentTime(input) {\n // Bail if media duration isn't available yet\n if (!this.duration) {\n return;\n }\n\n // Validate input\n const inputIsValid = is.number(input) && input > 0;\n\n // Set\n this.media.currentTime = inputIsValid ? Math.min(input, this.duration) : 0;\n\n // Logging\n this.debug.log(`Seeking to ${this.currentTime} seconds`);\n }\n\n /**\n * Get current time\n */\n get currentTime() {\n return Number(this.media.currentTime);\n }\n\n /**\n * Get buffered\n */\n get buffered() {\n const { buffered } = this.media;\n\n // YouTube / Vimeo return a float between 0-1\n if (is.number(buffered)) {\n return buffered;\n }\n\n // HTML5\n // TODO: Handle buffered chunks of the media\n // (i.e. seek to another section buffers only that section)\n if (buffered && buffered.length && this.duration > 0) {\n return buffered.end(0) / this.duration;\n }\n\n return 0;\n }\n\n /**\n * Get seeking status\n */\n get seeking() {\n return Boolean(this.media.seeking);\n }\n\n /**\n * Get the duration of the current media\n */\n get duration() {\n // Faux duration set via config\n const fauxDuration = parseFloat(this.config.duration);\n\n // Media duration can be NaN before the media has loaded\n const duration = (this.media || {}).duration || 0;\n\n // If config duration is funky, use regular duration\n return fauxDuration || duration;\n }\n\n /**\n * Set the player volume\n * @param {number} value - must be between 0 and 1. Defaults to the value from local storage and config.volume if not set in storage\n */\n set volume(value) {\n let volume = value;\n const max = 1;\n const min = 0;\n\n if (is.string(volume)) {\n volume = Number(volume);\n }\n\n // Load volume from storage if no value specified\n if (!is.number(volume)) {\n volume = this.storage.get('volume');\n }\n\n // Use config if all else fails\n if (!is.number(volume)) {\n ({ volume } = this.config);\n }\n\n // Maximum is volumeMax\n if (volume > max) {\n volume = max;\n }\n // Minimum is volumeMin\n if (volume < min) {\n volume = min;\n }\n\n // Update config\n this.config.volume = volume;\n\n // Set the player volume\n this.media.volume = volume;\n\n // If muted, and we're increasing volume manually, reset muted state\n if (!is.empty(value) && this.muted && volume > 0) {\n this.muted = false;\n }\n }\n\n /**\n * Get the current player volume\n */\n get volume() {\n return Number(this.media.volume);\n }\n\n /**\n * Increase volume\n * @param {boolean} step - How much to decrease by (between 0 and 1)\n */\n increaseVolume(step) {\n const volume = this.media.muted ? 0 : this.volume;\n this.volume = volume + (is.number(step) ? step : 1);\n }\n\n /**\n * Decrease volume\n * @param {boolean} step - How much to decrease by (between 0 and 1)\n */\n decreaseVolume(step) {\n const volume = this.media.muted ? 0 : this.volume;\n this.volume = volume - (is.number(step) ? step : 1);\n }\n\n /**\n * Set muted state\n * @param {boolean} mute\n */\n set muted(mute) {\n let toggle = mute;\n\n // Load muted state from storage\n if (!is.boolean(toggle)) {\n toggle = this.storage.get('muted');\n }\n\n // Use config if all else fails\n if (!is.boolean(toggle)) {\n toggle = this.config.muted;\n }\n\n // Update config\n this.config.muted = toggle;\n\n // Set mute on the player\n this.media.muted = toggle;\n }\n\n /**\n * Get current muted state\n */\n get muted() {\n return Boolean(this.media.muted);\n }\n\n /**\n * Check if the media has audio\n */\n get hasAudio() {\n // Assume yes for all non HTML5 (as we can't tell...)\n if (!this.isHTML5) {\n return true;\n }\n\n if (this.isAudio) {\n return true;\n }\n\n // Get audio tracks\n return (\n Boolean(this.media.mozHasAudio) ||\n Boolean(this.media.webkitAudioDecodedByteCount) ||\n Boolean(this.media.audioTracks && this.media.audioTracks.length)\n );\n }\n\n /**\n * Set playback speed\n * @param {number} speed - the speed of playback (0.5-2.0)\n */\n set speed(input) {\n let speed = null;\n\n if (is.number(input)) {\n speed = input;\n }\n\n if (!is.number(speed)) {\n speed = this.storage.get('speed');\n }\n\n if (!is.number(speed)) {\n speed = this.config.speed.selected;\n }\n\n // Set min/max\n if (speed < 0.1) {\n speed = 0.1;\n }\n if (speed > 2.0) {\n speed = 2.0;\n }\n\n if (!this.config.speed.options.includes(speed)) {\n this.debug.warn(`Unsupported speed (${speed})`);\n return;\n }\n\n // Update config\n this.config.speed.selected = speed;\n\n // Set media speed\n this.media.playbackRate = speed;\n }\n\n /**\n * Get current playback speed\n */\n get speed() {\n return Number(this.media.playbackRate);\n }\n\n /**\n * Set playback quality\n * Currently HTML5 & YouTube only\n * @param {number} input - Quality level\n */\n set quality(input) {\n const config = this.config.quality;\n const options = this.options.quality;\n\n if (!options.length) {\n return;\n }\n\n let quality = [\n !is.empty(input) && Number(input),\n this.storage.get('quality'),\n config.selected,\n config.default,\n ].find(is.number);\n\n if (!options.includes(quality)) {\n const value = closest(options, quality);\n this.debug.warn(`Unsupported quality option: ${quality}, using ${value} instead`);\n quality = value;\n }\n\n // Trigger request event\n triggerEvent.call(this, this.media, 'qualityrequested', false, { quality });\n\n // Update config\n config.selected = quality;\n\n // Set quality\n this.media.quality = quality;\n }\n\n /**\n * Get current quality level\n */\n get quality() {\n return this.media.quality;\n }\n\n /**\n * Toggle loop\n * TODO: Finish fancy new logic. Set the indicator on load as user may pass loop as config\n * @param {boolean} input - Whether to loop or not\n */\n set loop(input) {\n const toggle = is.boolean(input) ? input : this.config.loop.active;\n this.config.loop.active = toggle;\n this.media.loop = toggle;\n\n // Set default to be a true toggle\n /* const type = ['start', 'end', 'all', 'none', 'toggle'].includes(input) ? input : 'toggle';\n\n switch (type) {\n case 'start':\n if (this.config.loop.end && this.config.loop.end <= this.currentTime) {\n this.config.loop.end = null;\n }\n this.config.loop.start = this.currentTime;\n // this.config.loop.indicator.start = this.elements.display.played.value;\n break;\n\n case 'end':\n if (this.config.loop.start >= this.currentTime) {\n return this;\n }\n this.config.loop.end = this.currentTime;\n // this.config.loop.indicator.end = this.elements.display.played.value;\n break;\n\n case 'all':\n this.config.loop.start = 0;\n this.config.loop.end = this.duration - 2;\n this.config.loop.indicator.start = 0;\n this.config.loop.indicator.end = 100;\n break;\n\n case 'toggle':\n if (this.config.loop.active) {\n this.config.loop.start = 0;\n this.config.loop.end = null;\n } else {\n this.config.loop.start = 0;\n this.config.loop.end = this.duration - 2;\n }\n break;\n\n default:\n this.config.loop.start = 0;\n this.config.loop.end = null;\n break;\n } */\n }\n\n /**\n * Get current loop state\n */\n get loop() {\n return Boolean(this.media.loop);\n }\n\n /**\n * Set new media source\n * @param {object} input - The new source object (see docs)\n */\n set source(input) {\n source.change.call(this, input);\n }\n\n /**\n * Get current source\n */\n get source() {\n return this.media.currentSrc;\n }\n\n /**\n * Set the poster image for a video\n * @param {input} - the URL for the new poster image\n */\n set poster(input) {\n if (!this.isVideo) {\n this.debug.warn('Poster can only be set for video');\n return;\n }\n\n ui.setPoster.call(this, input, false).catch(() => {});\n }\n\n /**\n * Get the current poster image\n */\n get poster() {\n if (!this.isVideo) {\n return null;\n }\n\n return this.media.getAttribute('poster');\n }\n\n /**\n * Set the autoplay state\n * @param {boolean} input - Whether to autoplay or not\n */\n set autoplay(input) {\n const toggle = is.boolean(input) ? input : this.config.autoplay;\n this.config.autoplay = toggle;\n }\n\n /**\n * Get the current autoplay state\n */\n get autoplay() {\n return Boolean(this.config.autoplay);\n }\n\n /**\n * Toggle captions\n * @param {boolean} input - Whether to enable captions\n */\n toggleCaptions(input) {\n captions.toggle.call(this, input, false);\n }\n\n /**\n * Set the caption track by index\n * @param {number} - Caption index\n */\n set currentTrack(input) {\n captions.set.call(this, input, false);\n }\n\n /**\n * Get the current caption track index (-1 if disabled)\n */\n get currentTrack() {\n const { toggled, currentTrack } = this.captions;\n return toggled ? currentTrack : -1;\n }\n\n /**\n * Set the wanted language for captions\n * Since tracks can be added later it won't update the actual caption track until there is a matching track\n * @param {string} - Two character ISO language code (e.g. EN, FR, PT, etc)\n */\n set language(input) {\n captions.setLanguage.call(this, input, false);\n }\n\n /**\n * Get the current track's language\n */\n get language() {\n return (captions.getCurrentTrack.call(this) || {}).language;\n }\n\n /**\n * Toggle picture-in-picture playback on WebKit/MacOS\n * TODO: update player with state, support, enabled\n * TODO: detect outside changes\n */\n set pip(input) {\n const states = {\n pip: 'picture-in-picture',\n inline: 'inline',\n };\n\n // Bail if no support\n if (!support.pip) {\n return;\n }\n\n // Toggle based on current state if not passed\n const toggle = is.boolean(input) ? input : this.pip === states.inline;\n\n // Toggle based on current state\n this.media.webkitSetPresentationMode(toggle ? states.pip : states.inline);\n }\n\n /**\n * Get the current picture-in-picture state\n */\n get pip() {\n if (!support.pip) {\n return null;\n }\n\n return this.media.webkitPresentationMode;\n }\n\n /**\n * Trigger the airplay dialog\n * TODO: update player with state, support, enabled\n */\n airplay() {\n // Show dialog if supported\n if (support.airplay) {\n this.media.webkitShowPlaybackTargetPicker();\n }\n }\n\n /**\n * Toggle the player controls\n * @param {boolean} [toggle] - Whether to show the controls\n */\n toggleControls(toggle) {\n // Don't toggle if missing UI support or if it's audio\n if (this.supported.ui && !this.isAudio) {\n // Get state before change\n const isHidden = hasClass(this.elements.container, this.config.classNames.hideControls);\n\n // Negate the argument if not undefined since adding the class to hides the controls\n const force = typeof toggle === 'undefined' ? undefined : !toggle;\n\n // Apply and get updated state\n const hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force);\n\n // Close menu\n if (hiding && this.config.controls.includes('settings') && !is.empty(this.config.settings)) {\n controls.toggleMenu.call(this, false);\n }\n // Trigger event on change\n if (hiding !== isHidden) {\n const eventName = hiding ? 'controlshidden' : 'controlsshown';\n triggerEvent.call(this, this.media, eventName);\n }\n return !hiding;\n }\n return false;\n }\n\n /**\n * Add event listeners\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n */\n on(event, callback) {\n on.call(this, this.elements.container, event, callback);\n }\n /**\n * Add event listeners once\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n */\n once(event, callback) {\n once.call(this, this.elements.container, event, callback);\n }\n /**\n * Remove event listeners\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n */\n off(event, callback) {\n off(this.elements.container, event, callback);\n }\n\n /**\n * Destroy an instance\n * Event listeners are removed when elements are removed\n * http://stackoverflow.com/questions/12528049/if-a-dom-element-is-removed-are-its-listeners-also-removed-from-memory\n * @param {function} callback - Callback for when destroy is complete\n * @param {boolean} soft - Whether it's a soft destroy (for source changes etc)\n */\n destroy(callback, soft = false) {\n if (!this.ready) {\n return;\n }\n\n const done = () => {\n // Reset overflow (incase destroyed while in fullscreen)\n document.body.style.overflow = '';\n\n // GC for embed\n this.embed = null;\n\n // If it's a soft destroy, make minimal changes\n if (soft) {\n if (Object.keys(this.elements).length) {\n // Remove elements\n removeElement(this.elements.buttons.play);\n removeElement(this.elements.captions);\n removeElement(this.elements.controls);\n removeElement(this.elements.wrapper);\n\n // Clear for GC\n this.elements.buttons.play = null;\n this.elements.captions = null;\n this.elements.controls = null;\n this.elements.wrapper = null;\n }\n\n // Callback\n if (is.function(callback)) {\n callback();\n }\n } else {\n // Unbind listeners\n unbindListeners.call(this);\n\n // Replace the container with the original element provided\n replaceElement(this.elements.original, this.elements.container);\n\n // Event\n triggerEvent.call(this, this.elements.original, 'destroyed', true);\n\n // Callback\n if (is.function(callback)) {\n callback.call(this.elements.original);\n }\n\n // Reset state\n this.ready = false;\n\n // Clear for garbage collection\n setTimeout(() => {\n this.elements = null;\n this.media = null;\n }, 200);\n }\n };\n\n // Stop playback\n this.stop();\n\n // Provider specific stuff\n if (this.isHTML5) {\n // Clear timeout\n clearTimeout(this.timers.loading);\n\n // Restore native video controls\n ui.toggleNativeControls.call(this, true);\n\n // Clean up\n done();\n } else if (this.isYouTube) {\n // Clear timers\n clearInterval(this.timers.buffering);\n clearInterval(this.timers.playing);\n\n // Destroy YouTube API\n if (this.embed !== null && is.function(this.embed.destroy)) {\n this.embed.destroy();\n }\n\n // Clean up\n done();\n } else if (this.isVimeo) {\n // Destroy Vimeo API\n // then clean up (wait, to prevent postmessage errors)\n if (this.embed !== null) {\n this.embed.unload().then(done);\n }\n\n // Vimeo does not always return\n setTimeout(done, 200);\n }\n }\n\n /**\n * Check for support for a mime type (HTML5 only)\n * @param {string} type - Mime type\n */\n supports(type) {\n return support.mime.call(this, type);\n }\n\n /**\n * Check for support\n * @param {string} type - Player type (audio/video)\n * @param {string} provider - Provider (html5/youtube/vimeo)\n * @param {bool} inline - Where player has `playsinline` sttribute\n */\n static supported(type, provider, inline) {\n return support.check(type, provider, inline);\n }\n\n /**\n * Load an SVG sprite into the page\n * @param {string} url - URL for the SVG sprite\n * @param {string} [id] - Unique ID\n */\n static loadSprite(url, id) {\n return loadSprite(url, id);\n }\n\n /**\n * Setup multiple instances\n * @param {*} selector\n * @param {object} options\n */\n static setup(selector, options = {}) {\n let targets = null;\n\n if (is.string(selector)) {\n targets = Array.from(document.querySelectorAll(selector));\n } else if (is.nodeList(selector)) {\n targets = Array.from(selector);\n } else if (is.array(selector)) {\n targets = selector.filter(is.element);\n }\n\n if (is.empty(targets)) {\n return null;\n }\n\n return targets.map(t => new Plyr(t, options));\n }\n}\n\nPlyr.defaults = cloneDeep(defaults);\n\nexport default Plyr;\n"]}
\ No newline at end of file diff --git a/dist/plyr.min.js b/dist/plyr.min.js index 613f81ee..0de1096e 100644 --- a/dist/plyr.min.js +++ b/dist/plyr.min.js @@ -1,2 +1,2 @@ -"object"==typeof navigator&&function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define("Plyr",t):e.Plyr=t()}(this,function(){"use strict";var e=function(e){return null!=e?e.constructor:null},t=function(e,t){return Boolean(e&&t&&e instanceof t)},i={object:function(t){return e(t)===Object},number:function(t){return e(t)===Number&&!Number.isNaN(t)},string:function(t){return e(t)===String},boolean:function(t){return e(t)===Boolean},function:function(t){return e(t)===Function},array:function(e){return!i.nullOrUndefined(e)&&Array.isArray(e)},weakMap:function(e){return t(e,WeakMap)},nodeList:function(e){return t(e,NodeList)},element:function(e){return t(e,Element)},textNode:function(t){return e(t)===Text},event:function(e){return t(e,Event)},cue:function(e){return t(e,window.TextTrackCue)||t(e,window.VTTCue)},track:function(e){return t(e,TextTrack)||!i.nullOrUndefined(e)&&i.string(e.kind)},url:function(e){return!i.nullOrUndefined(e)&&/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-/]))?/.test(e)},nullOrUndefined:function(e){return null==e},empty:function(e){return i.nullOrUndefined(e)||(i.string(e)||i.array(e)||i.nodeList(e))&&!e.length||i.object(e)&&!Object.keys(e).length}},n=function(){var e=!1;try{var t=Object.defineProperty({},"passive",{get:function(){return e=!0,null}});window.addEventListener("test",null,t),window.removeEventListener("test",null,t)}catch(e){}return e}();function a(e,t,a){var s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],r=this,l=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],o=arguments.length>5&&void 0!==arguments[5]&&arguments[5];if(e&&"addEventListener"in e&&!i.empty(t)&&i.function(a)){var c=t.split(" "),u=o;n&&(u={passive:l,capture:o}),c.forEach(function(t){r&&r.eventListeners&&s&&r.eventListeners.push({element:e,type:t,callback:a,options:u}),e[s?"addEventListener":"removeEventListener"](t,a,u)})}}function s(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=arguments[2],n=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],s=arguments.length>4&&void 0!==arguments[4]&&arguments[4];a.call(this,e,t,i,!0,n,s)}function r(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=arguments[2],n=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],s=arguments.length>4&&void 0!==arguments[4]&&arguments[4];a.call(this,e,t,i,!1,n,s)}function l(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=arguments[2],n=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],s=arguments.length>4&&void 0!==arguments[4]&&arguments[4];a.call(this,e,t,function a(){r(e,t,a,n,s);for(var l=arguments.length,o=Array(l),c=0;c<l;c++)o[c]=arguments[c];i.apply(this,o)},!0,n,s)}function o(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};if(i.element(e)&&!i.empty(t)){var s=new CustomEvent(t,{bubbles:n,detail:Object.assign({},a,{plyr:this})});e.dispatchEvent(s)}}var c=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},u=function(){function e(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,i,n){return i&&e(t.prototype,i),n&&e(t,n),t}}(),d=function(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e},p=function(){return function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var i=[],n=!0,a=!1,s=void 0;try{for(var r,l=e[Symbol.iterator]();!(n=(r=l.next()).done)&&(i.push(r.value),!t||i.length!==t);n=!0);}catch(e){a=!0,s=e}finally{try{!n&&l.return&&l.return()}finally{if(a)throw s}}return i}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();function h(e,t){var i=e.length?e:[e];Array.from(i).reverse().forEach(function(e,i){var n=i>0?t.cloneNode(!0):t,a=e.parentNode,s=e.nextSibling;n.appendChild(e),s?a.insertBefore(n,s):a.appendChild(n)})}function m(e,t){i.element(e)&&!i.empty(t)&&Object.entries(t).filter(function(e){var t=p(e,2)[1];return!i.nullOrUndefined(t)}).forEach(function(t){var i=p(t,2),n=i[0],a=i[1];return e.setAttribute(n,a)})}function f(e,t,n){var a=document.createElement(e);return i.object(t)&&m(a,t),i.string(n)&&(a.innerText=n),a}function g(e,t,n,a){i.element(t)&&t.appendChild(f(e,n,a))}function y(e){i.nodeList(e)||i.array(e)?Array.from(e).forEach(y):i.element(e)&&i.element(e.parentNode)&&e.parentNode.removeChild(e)}function v(e){if(i.element(e))for(var t=e.childNodes.length;t>0;)e.removeChild(e.lastChild),t-=1}function b(e,t){return i.element(t)&&i.element(t.parentNode)&&i.element(e)?(t.parentNode.replaceChild(e,t),e):null}function k(e,t){if(!i.string(e)||i.empty(e))return{};var n={},a=t;return e.split(",").forEach(function(e){var t=e.trim(),s=t.replace(".",""),r=t.replace(/[[\]]/g,"").split("="),l=r[0],o=r.length>1?r[1].replace(/["']/g,""):"";switch(t.charAt(0)){case".":i.object(a)&&i.string(a.class)&&(a.class+=" "+s),n.class=s;break;case"#":n.id=t.replace("#","");break;case"[":n[l]=o}}),n}function w(e,t){if(i.element(e)){var n=t;i.boolean(n)||(n=!e.hasAttribute("hidden")),n?e.setAttribute("hidden",""):e.removeAttribute("hidden")}}function T(e,t,n){if(i.element(e)){var a="toggle";return void 0!==n&&(a=n?"add":"remove"),e.classList[a](t),e.classList.contains(t)}return null}function A(e,t){return i.element(e)&&e.classList.contains(t)}function E(e,t){var i={Element:Element};return(i.matches||i.webkitMatchesSelector||i.mozMatchesSelector||i.msMatchesSelector||function(){return Array.from(document.querySelectorAll(t)).includes(this)}).call(e,t)}function C(e){return this.elements.container.querySelectorAll(e)}function P(e){return this.elements.container.querySelector(e)}function S(){var e=document.activeElement;return e=e&&e!==document.body?document.querySelector(":focus"):null}var N,L,M,x=(N=document.createElement("span"),L={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},M=Object.keys(L).find(function(e){return void 0!==N.style[e]}),!!i.string(M)&&L[M]);var _,I={isIE:!!document.documentMode,isWebkit:"WebkitAppearance"in document.documentElement.style&&!/Edge/.test(navigator.userAgent),isIPhone:/(iPhone|iPod)/gi.test(navigator.platform),isIos:/(iPad|iPhone|iPod)/gi.test(navigator.platform)},q={"audio/ogg":"vorbis","audio/wav":"1","video/webm":"vp8, vorbis","video/mp4":"avc1.42E01E, mp4a.40.2","video/ogg":"theora"},O={audio:"canPlayType"in document.createElement("audio"),video:"canPlayType"in document.createElement("video"),check:function(e,t,i){var n=I.isIPhone&&i&&O.playsinline,a=O[e]||"html5"!==t;return{api:a,ui:a&&O.rangeInput&&("video"!==e||!I.isIPhone||n)}},pip:!I.isIPhone&&i.function(f("video").webkitSetPresentationMode),airplay:i.function(window.WebKitPlaybackTargetAvailabilityEvent),playsinline:"playsInline"in document.createElement("video"),mime:function(e){var t=e.split("/"),i=p(t,1)[0];if(!this.isHTML5||i!==this.type)return!1;var n=void 0;e&&e.includes("codecs=")?n=e:"audio/mpeg"===e?n="audio/mpeg;":e in q&&(n=e+'; codecs="'+q[e]+'"');try{return Boolean(n&&this.media.canPlayType(n).replace(/no/,""))}catch(e){return!1}},textTracks:"textTracks"in document.createElement("video"),rangeInput:(_=document.createElement("input"),_.type="range","range"===_.type),touch:"ontouchstart"in document.documentElement,transitions:!1!==x,reducedMotion:"matchMedia"in window&&window.matchMedia("(prefers-reduced-motion)").matches},j={getSources:function(){var e=this;return this.isHTML5?Array.from(this.media.querySelectorAll("source")).filter(function(t){return O.mime.call(e,t.getAttribute("type"))}):[]},getQualityOptions:function(){return j.getSources.call(this).map(function(e){return Number(e.getAttribute("size"))}).filter(Boolean)},extend:function(){if(this.isHTML5){var e=this;Object.defineProperty(e.media,"quality",{get:function(){var t=j.getSources.call(e).filter(function(t){return t.getAttribute("src")===e.source}),i=p(t,1)[0];return i&&Number(i.getAttribute("size"))},set:function(t){var i=j.getSources.call(e).find(function(e){return Number(e.getAttribute("size"))===t});if(i){var n=e.currentTime,a=e.playing;e.media.src=i.getAttribute("src");e.once("loadedmetadata",function(){e.currentTime=n}),e.media.load(),a&&e.play(),o.call(e,e.media,"qualitychange",!1,{quality:t})}}})}},cancelRequests:function(){this.isHTML5&&(y(j.getSources.call(this)),this.media.setAttribute("src",this.config.blankVideo),this.media.load(),this.debug.log("Cancelled network requests"))}};function R(e,t){return t.split(".").reduce(function(e,t){return e&&e[t]},e)}function V(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length,n=Array(t>1?t-1:0),a=1;a<t;a++)n[a-1]=arguments[a];if(!n.length)return e;var s=n.shift();return i.object(s)?(Object.keys(s).forEach(function(t){i.object(s[t])?(Object.keys(e).includes(t)||Object.assign(e,d({},t,{})),V(e[t],s[t])):Object.assign(e,d({},t,s[t]))}),V.apply(void 0,[e].concat(n))):e}function B(e){for(var t=arguments.length,n=Array(t>1?t-1:0),a=1;a<t;a++)n[a-1]=arguments[a];return i.empty(e)?e:e.toString().replace(/{(\d+)}/g,function(e,t){return n[t].toString()})}function H(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return e.replace(new RegExp(t.toString().replace(/([.*+?^=!:${}()|[\]/\\])/g,"\\$1"),"g"),i.toString())}function D(){return(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"").toString().replace(/\w\S*/g,function(e){return e.charAt(0).toUpperCase()+e.substr(1).toLowerCase()})}function F(){var e=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"").toString();return(e=function(){var e=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"").toString();return e=H(e,"-"," "),e=H(e,"_"," "),H(e=D(e)," ","")}(e)).charAt(0).toLowerCase()+e.slice(1)}function U(e){var t=document.createElement("div");return t.appendChild(e),t.innerHTML}var z=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(i.empty(e)||i.empty(t))return"";var n=R(t.i18n,e);if(i.empty(n))return"";var a={"{seektime}":t.seekTime,"{title}":t.title};return Object.entries(a).forEach(function(e){var t=p(e,2),i=t[0],a=t[1];n=H(n,i,a)}),n};function W(e){return i.array(e)?e.filter(function(t,i){return e.indexOf(t)===i}):e}var K=function(){function e(t){c(this,e),this.enabled=t.config.storage.enabled,this.key=t.config.storage.key}return u(e,[{key:"get",value:function(t){if(!e.supported||!this.enabled)return null;var n=window.localStorage.getItem(this.key);if(i.empty(n))return null;var a=JSON.parse(n);return i.string(t)&&t.length?a[t]:a}},{key:"set",value:function(t){if(e.supported&&this.enabled&&i.object(t)){var n=this.get();i.empty(n)&&(n={}),V(n,t),window.localStorage.setItem(this.key,JSON.stringify(n))}}}],[{key:"supported",get:function(){try{if(!("localStorage"in window))return!1;return window.localStorage.setItem("___test","___test"),window.localStorage.removeItem("___test"),!0}catch(e){return!1}}}]),e}();function Y(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"text";return new Promise(function(i,n){try{var a=new XMLHttpRequest;if(!("withCredentials"in a))return;a.addEventListener("load",function(){if("text"===t)try{i(JSON.parse(a.responseText))}catch(e){i(a.responseText)}else i(a.response)}),a.addEventListener("error",function(){throw new Error(a.status)}),a.open("GET",e,!0),a.responseType=t,a.send()}catch(e){n(e)}})}function Q(e,t){if(i.string(e)){var n=i.string(t),a=function(){return null!==document.getElementById(t)},s=function(e,t){e.innerHTML=t,n&&a()||document.body.insertAdjacentElement("afterbegin",e)};if(!n||!a()){var r=K.supported,l=document.createElement("div");if(l.setAttribute("hidden",""),n&&l.setAttribute("id",t),r){var o=window.localStorage.getItem("cache-"+t);if(null!==o){var c=JSON.parse(o);s(l,c.content)}}Y(e).then(function(e){i.empty(e)||(r&&window.localStorage.setItem("cache-"+t,JSON.stringify({content:e})),s(l,e))}).catch(function(){})}}}var J=function(e){return parseInt(e/60/60%60,10)},$=function(e){return parseInt(e/60%60,10)},X=function(e){return parseInt(e%60,10)};function G(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(!i.number(e))return G(null,t,n);var a=function(e){return("0"+e).slice(-2)},s=J(e),r=$(e),l=X(e);return t||s>0?s+=":":s="",(n&&e>0?"-":"")+s+a(r)+":"+a(l)}var Z={getIconUrl:function(){var e=new URL(this.config.iconUrl,window.location).host!==window.location.host||I.isIE&&!window.svg4everybody;return{url:this.config.iconUrl,cors:e}},findElements:function(){try{return this.elements.controls=P.call(this,this.config.selectors.controls.wrapper),this.elements.buttons={play:C.call(this,this.config.selectors.buttons.play),pause:P.call(this,this.config.selectors.buttons.pause),restart:P.call(this,this.config.selectors.buttons.restart),rewind:P.call(this,this.config.selectors.buttons.rewind),fastForward:P.call(this,this.config.selectors.buttons.fastForward),mute:P.call(this,this.config.selectors.buttons.mute),pip:P.call(this,this.config.selectors.buttons.pip),airplay:P.call(this,this.config.selectors.buttons.airplay),settings:P.call(this,this.config.selectors.buttons.settings),captions:P.call(this,this.config.selectors.buttons.captions),fullscreen:P.call(this,this.config.selectors.buttons.fullscreen)},this.elements.progress=P.call(this,this.config.selectors.progress),this.elements.inputs={seek:P.call(this,this.config.selectors.inputs.seek),volume:P.call(this,this.config.selectors.inputs.volume)},this.elements.display={buffer:P.call(this,this.config.selectors.display.buffer),currentTime:P.call(this,this.config.selectors.display.currentTime),duration:P.call(this,this.config.selectors.display.duration)},i.element(this.elements.progress)&&(this.elements.display.seekTooltip=this.elements.progress.querySelector("."+this.config.classNames.tooltip)),!0}catch(e){return this.debug.warn("It looks like there is a problem with your custom controls HTML",e),this.toggleNativeControls(!0),!1}},createIcon:function(e,t){var i=Z.getIconUrl.call(this),n=(i.cors?"":i.url)+"#"+this.config.iconPrefix,a=document.createElementNS("http://www.w3.org/2000/svg","svg");m(a,V(t,{role:"presentation",focusable:"false"}));var s=document.createElementNS("http://www.w3.org/2000/svg","use"),r=n+"-"+e;return"href"in s?s.setAttributeNS("http://www.w3.org/1999/xlink","href",r):s.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",r),a.appendChild(s),a},createLabel:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i={pip:"PIP",airplay:"AirPlay"}[e]||z(e,this.config);return f("span",Object.assign({},t,{class:[t.class,this.config.classNames.hidden].filter(Boolean).join(" ")}),i)},createBadge:function(e){if(i.empty(e))return null;var t=f("span",{class:this.config.classNames.menu.value});return t.appendChild(f("span",{class:this.config.classNames.menu.badge},e)),t},createButton:function(e,t){var n=f("button"),a=Object.assign({},t),s=F(e),r=!1,l=void 0,o=void 0,c=void 0,u=void 0;switch("type"in a||(a.type="button"),"class"in a?a.class.includes(this.config.classNames.control)&&(a.class+=" "+this.config.classNames.control):a.class=this.config.classNames.control,e){case"play":r=!0,l="play",c="pause",o="play",u="pause";break;case"mute":r=!0,l="mute",c="unmute",o="volume",u="muted";break;case"captions":r=!0,l="enableCaptions",c="disableCaptions",o="captions-off",u="captions-on";break;case"fullscreen":r=!0,l="enterFullscreen",c="exitFullscreen",o="enter-fullscreen",u="exit-fullscreen";break;case"play-large":a.class+=" "+this.config.classNames.control+"--overlaid",s="play",l="play",o="play";break;default:l=s,o=e}r?(n.appendChild(Z.createIcon.call(this,u,{class:"icon--pressed"})),n.appendChild(Z.createIcon.call(this,o,{class:"icon--not-pressed"})),n.appendChild(Z.createLabel.call(this,c,{class:"label--pressed"})),n.appendChild(Z.createLabel.call(this,l,{class:"label--not-pressed"}))):(n.appendChild(Z.createIcon.call(this,o)),n.appendChild(Z.createLabel.call(this,l))),V(a,k(this.config.selectors.buttons[s],a)),m(n,a),"play"===s?(i.array(this.elements.buttons[s])||(this.elements.buttons[s]=[]),this.elements.buttons[s].push(n)):this.elements.buttons[s]=n;var d=this.config.classNames.controlPressed;return Object.defineProperty(n,"pressed",{enumerable:!0,get:function(){return A(n,d)},set:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];T(n,d,e)}}),n},createRange:function(e,t){var i=f("input",V(k(this.config.selectors.inputs[e]),{type:"range",min:0,max:100,step:.01,value:0,autocomplete:"off",role:"slider","aria-label":z(e,this.config),"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":0},t));return this.elements.inputs[e]=i,Z.updateRangeFill.call(this,i),i},createProgress:function(e,t){var i=f("progress",V(k(this.config.selectors.display[e]),{min:0,max:100,value:0,role:"presentation","aria-hidden":!0},t));if("volume"!==e){i.appendChild(f("span",null,"0"));var n={played:"played",buffer:"buffered"}[e],a=n?z(n,this.config):"";i.innerText="% "+a.toLowerCase()}return this.elements.display[e]=i,i},createTime:function(e){var t=k(this.config.selectors.display[e]),i=f("div",V(t,{class:(this.config.classNames.display.time+" "+(t.class?t.class:"")).trim(),"aria-label":z(e,this.config)}),"00:00");return this.elements.display[e]=i,i},createMenuItem:function(e){var t=e.value,n=e.list,a=e.type,s=e.title,r=e.badge,l=void 0===r?null:r,o=e.checked,c=void 0!==o&&o,u=k(this.config.selectors.inputs[a]),d=f("button",V(u,{type:"button",role:"menuitemradio",class:(this.config.classNames.control+" "+(u.class?u.class:"")).trim(),value:t,"aria-checked":c}));d.innerHTML=s,i.element(l)&&d.appendChild(l),Object.defineProperty(d,"checked",{enumerable:!0,get:function(){return"true"===d.getAttribute("aria-checked")},set:function(e){e&&Array.from(d.parentNode.children).filter(function(e){return E(e,'[role="menuitemradio"]')}).forEach(function(e){return e.setAttribute("aria-checked","false")}),d.setAttribute("aria-checked",e?"true":"false")}}),n.appendChild(d)},formatTime:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return i.number(e)?G(e,J(this.duration)>0,t):e},updateTimeDisplay:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];i.element(e)&&i.number(t)&&(e.innerText=Z.formatTime(t,n))},updateVolume:function(){this.supported.ui&&(i.element(this.elements.inputs.volume)&&Z.setRange.call(this,this.elements.inputs.volume,this.muted?0:this.volume),i.element(this.elements.buttons.mute)&&(this.elements.buttons.mute.pressed=this.muted||0===this.volume))},setRange:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;i.element(e)&&(e.value=t,Z.updateRangeFill.call(this,e))},updateProgress:function(e){var t=this;if(this.supported.ui&&i.event(e)){var n,a,s=0;if(e)switch(e.type){case"timeupdate":case"seeking":case"seeked":n=this.currentTime,a=this.duration,s=0===n||0===a||Number.isNaN(n)||Number.isNaN(a)?0:(n/a*100).toFixed(2),"timeupdate"===e.type&&Z.setRange.call(this,this.elements.inputs.seek,s);break;case"playing":case"progress":!function(e,n){var a=i.number(n)?n:0,s=i.element(e)?e:t.elements.display.buffer;if(i.element(s)){s.value=a;var r=s.getElementsByTagName("span")[0];i.element(r)&&(r.childNodes[0].nodeValue=a)}}(this.elements.display.buffer,100*this.buffered)}}},updateRangeFill:function(e){var t=i.event(e)?e.target:e;if(i.element(t)&&"range"===t.getAttribute("type")){if(E(t,this.config.selectors.inputs.seek)){t.setAttribute("aria-valuenow",this.currentTime);var n=Z.formatTime(this.currentTime),a=Z.formatTime(this.duration),s=z("seekLabel",this.config);t.setAttribute("aria-valuetext",s.replace("{currentTime}",n).replace("{duration}",a))}else if(E(t,this.config.selectors.inputs.volume)){var r=100*t.value;t.setAttribute("aria-valuenow",r),t.setAttribute("aria-valuetext",r+"%")}else t.setAttribute("aria-valuenow",t.value);I.isWebkit&&t.style.setProperty("--value",t.value/t.max*100+"%")}},updateSeekTooltip:function(e){var t=this;if(this.config.tooltips.seek&&i.element(this.elements.inputs.seek)&&i.element(this.elements.display.seekTooltip)&&0!==this.duration){var n=0,a=this.elements.progress.getBoundingClientRect(),s=this.config.classNames.tooltip+"--visible",r=function(e){T(t.elements.display.seekTooltip,s,e)};if(this.touch)r(!1);else{if(i.event(e))n=100/a.width*(e.pageX-a.left);else{if(!A(this.elements.display.seekTooltip,s))return;n=parseFloat(this.elements.display.seekTooltip.style.left,10)}n<0?n=0:n>100&&(n=100),Z.updateTimeDisplay.call(this,this.elements.display.seekTooltip,this.duration/100*n),this.elements.display.seekTooltip.style.left=n+"%",i.event(e)&&["mouseenter","mouseleave"].includes(e.type)&&r("mouseenter"===e.type)}}},timeUpdate:function(e){var t=!i.element(this.elements.display.duration)&&this.config.invertTime;Z.updateTimeDisplay.call(this,this.elements.display.currentTime,t?this.duration-this.currentTime:this.currentTime,t),e&&"timeupdate"===e.type&&this.media.seeking||Z.updateProgress.call(this,e)},durationUpdate:function(){if(this.supported.ui&&(this.config.invertTime||!this.currentTime)){i.element(this.elements.inputs.seek)&&this.elements.inputs.seek.setAttribute("aria-valuemax",this.duration);var e=i.element(this.elements.display.duration);!e&&this.config.displayDuration&&this.paused&&Z.updateTimeDisplay.call(this,this.elements.display.currentTime,this.duration),e&&Z.updateTimeDisplay.call(this,this.elements.display.duration,this.duration),Z.updateSeekTooltip.call(this)}},toggleMenuButton:function(e,t){w(this.elements.settings.buttons[e],!t)},setQualityMenu:function(e){var t=this;if(i.element(this.elements.settings.panels.quality)){var n=this.elements.settings.panels.quality.querySelector('[role="menu"]');i.array(e)&&(this.options.quality=W(e).filter(function(e){return t.config.quality.options.includes(e)}));var a=!i.empty(this.options.quality)&&this.options.quality.length>1;if(Z.toggleMenuButton.call(this,"quality",a),Z.checkMenu.call(this),a){v(n);this.options.quality.sort(function(e,i){var n=t.config.quality.options;return n.indexOf(e)>n.indexOf(i)?1:-1}).forEach(function(e){Z.createMenuItem.call(t,{value:e,list:n,type:"quality",title:Z.getLabel.call(t,"quality",e),badge:function(e){var i=z("qualityBadge."+e,t.config);return i.length?Z.createBadge.call(t,i):null}(e)})}),Z.updateSetting.call(this,"quality",n)}}},getLabel:function(e,t){switch(e){case"speed":return 1===t?z("normal",this.config):t+"×";case"quality":if(i.number(t)){var n=z("qualityLabel."+t,this.config);return n.length?n:t+"p"}return D(t);case"captions":return ie.getLabel.call(this);default:return null}},updateSetting:function(e,t,n){var a=this.elements.settings.panels[e],s=null,r=t;if("captions"===e)s=this.currentTrack;else{if(s=i.empty(n)?this[e]:n,i.empty(s)&&(s=this.config[e].default),!i.empty(this.options[e])&&!this.options[e].includes(s))return void this.debug.warn("Unsupported value of '"+s+"' for "+e);if(!this.config[e].options.includes(s))return void this.debug.warn("Disabled value of '"+s+"' for "+e)}if(i.element(r)||(r=a&&a.querySelector('[role="menu"]')),i.element(r)){this.elements.settings.buttons[e].querySelector("."+this.config.classNames.menu.value).innerHTML=Z.getLabel.call(this,e,s);var l=r&&r.querySelector('[value="'+s+'"]');i.element(l)&&(l.checked=!0)}},setCaptionsMenu:function(){var e=this,t=this.elements.settings.panels.captions.querySelector('[role="menu"]'),i=ie.getTracks.call(this);if(Z.toggleMenuButton.call(this,"captions",i.length),v(t),Z.checkMenu.call(this),i.length){var n=i.map(function(i,n){return{value:n,checked:e.captions.toggled&&e.currentTrack===n,title:ie.getLabel.call(e,i),badge:i.language&&Z.createBadge.call(e,i.language.toUpperCase()),list:t,type:"language"}});n.unshift({value:-1,checked:!this.captions.toggled,title:z("disabled",this.config),list:t,type:"language"}),n.forEach(Z.createMenuItem.bind(this)),Z.updateSetting.call(this,"captions",t)}},setSpeedMenu:function(e){var t=this;if(this.config.controls.includes("settings")&&this.config.settings.includes("speed")&&i.element(this.elements.settings.panels.speed)){i.array(e)?this.options.speed=e:(this.isHTML5||this.isVimeo)&&(this.options.speed=[.5,.75,1,1.25,1.5,1.75,2]),this.options.speed=this.options.speed.filter(function(e){return t.config.speed.options.includes(e)});var n=!i.empty(this.options.speed)&&this.options.speed.length>1;if(Z.toggleMenuButton.call(this,"speed",n),Z.checkMenu.call(this),n){var a=this.elements.settings.panels.speed.querySelector('[role="menu"]');v(a),this.options.speed.forEach(function(e){Z.createMenuItem.call(t,{value:e,list:a,type:"speed",title:Z.getLabel.call(t,"speed",e)})}),Z.updateSetting.call(this,"speed",a)}}},checkMenu:function(){var e=this.elements.settings.buttons,t=!i.empty(e)&&Object.values(e).some(function(e){return!e.hidden});w(this.elements.settings.menu,!t)},toggleMenu:function(e){var t=this.elements.settings.popup,n=this.elements.buttons.settings;if(i.element(t)&&i.element(n)){var a=i.boolean(e)?e:i.element(t)&&t.hasAttribute("hidden");if(i.event(e)){var s=i.element(t)&&t.contains(e.target),r=e.target===this.elements.buttons.settings;if(s||!s&&!r&&a)return;r&&e.stopPropagation()}i.element(n)&&n.setAttribute("aria-expanded",a),i.element(t)&&(w(t,!a),T(this.elements.container,this.config.classNames.menu.open,a),a?t.removeAttribute("tabindex"):t.setAttribute("tabindex",-1))}},getMenuSize:function(e){var t=e.cloneNode(!0);t.style.position="absolute",t.style.opacity=0,t.removeAttribute("hidden"),e.parentNode.appendChild(t);var i=t.scrollWidth,n=t.scrollHeight;return y(t),{width:i,height:n}},showMenuPanel:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=document.getElementById("plyr-settings-"+this.id+"-"+t);if(i.element(n)){var a=n.parentNode,l=Array.from(a.children).find(function(e){return!e.hidden});if(O.transitions&&!O.reducedMotion){a.style.width=l.scrollWidth+"px",a.style.height=l.scrollHeight+"px";var o=Z.getMenuSize.call(this,n);s.call(this,a,x,function t(i){i.target===a&&["width","height"].includes(i.propertyName)&&(a.style.width="",a.style.height="",r.call(e,a,x,t))}),a.style.width=o.width+"px",a.style.height=o.height+"px"}w(l,!0),w(n,!1),n.querySelectorAll('[role^="menuitem"]')[0].focus()}},create:function(e){var t=this;if(i.empty(this.config.controls))return null;var n=f("div",k(this.config.selectors.controls.wrapper));if(this.config.controls.includes("restart")&&n.appendChild(Z.createButton.call(this,"restart")),this.config.controls.includes("rewind")&&n.appendChild(Z.createButton.call(this,"rewind")),this.config.controls.includes("play")&&n.appendChild(Z.createButton.call(this,"play")),this.config.controls.includes("fast-forward")&&n.appendChild(Z.createButton.call(this,"fast-forward")),this.config.controls.includes("progress")){var a=f("div",k(this.config.selectors.progress));if(a.appendChild(Z.createRange.call(this,"seek",{id:"plyr-seek-"+e.id})),a.appendChild(Z.createProgress.call(this,"buffer")),this.config.tooltips.seek){var s=f("span",{class:this.config.classNames.tooltip},"00:00");a.appendChild(s),this.elements.display.seekTooltip=s}this.elements.progress=a,n.appendChild(this.elements.progress)}if(this.config.controls.includes("current-time")&&n.appendChild(Z.createTime.call(this,"currentTime")),this.config.controls.includes("duration")&&n.appendChild(Z.createTime.call(this,"duration")),this.config.controls.includes("mute")&&n.appendChild(Z.createButton.call(this,"mute")),this.config.controls.includes("volume")){var r=f("div",{class:"plyr__volume"}),l={max:1,step:.05,value:this.config.volume};r.appendChild(Z.createRange.call(this,"volume",V(l,{id:"plyr-volume-"+e.id}))),this.elements.volume=r,n.appendChild(r)}if(this.config.controls.includes("captions")&&n.appendChild(Z.createButton.call(this,"captions")),this.config.controls.includes("settings")&&!i.empty(this.config.settings)){var o=f("div",{class:"plyr__menu",hidden:""});o.appendChild(Z.createButton.call(this,"settings",{id:"plyr-settings-toggle-"+e.id,"aria-haspopup":!0,"aria-controls":"plyr-settings-"+e.id,"aria-expanded":!1}));var c=f("div",{class:"plyr__menu__container",id:"plyr-settings-"+e.id,hidden:"","aria-labelled-by":"plyr-settings-toggle-"+e.id}),u=f("div"),d=f("div",{id:"plyr-settings-"+e.id+"-home"}),p=f("div",{role:"menu"});this.config.settings.forEach(function(i){var n=f("button",V(k(t.config.selectors.buttons.settings),{type:"button",class:t.config.classNames.control+" "+t.config.classNames.control+"--forward",role:"menuitem","aria-haspopup":!0})),a=f("span",null,z(i,t.config)),s=f("span",{class:t.config.classNames.menu.value});s.innerHTML=e[i],a.appendChild(s),n.appendChild(a),p.appendChild(n);var r=f("div",{id:"plyr-settings-"+e.id+"-"+i,hidden:""}),l=f("button",{type:"button",class:t.config.classNames.control+" "+t.config.classNames.control+"--back"},z(i,t.config));l.addEventListener("click",function(){Z.showMenuPanel.call(t,"home")}),r.appendChild(l),r.appendChild(f("div",{role:"menu"})),u.appendChild(r),n.addEventListener("click",function(){Z.showMenuPanel.call(t,i)}),t.elements.settings.buttons[i]=n,t.elements.settings.panels[i]=r}),d.appendChild(p),u.appendChild(d),c.appendChild(u),o.appendChild(c),n.appendChild(o),this.elements.settings.popup=c,this.elements.settings.menu=o}return this.config.controls.includes("pip")&&O.pip&&n.appendChild(Z.createButton.call(this,"pip")),this.config.controls.includes("airplay")&&O.airplay&&n.appendChild(Z.createButton.call(this,"airplay")),this.config.controls.includes("fullscreen")&&n.appendChild(Z.createButton.call(this,"fullscreen")),this.config.controls.includes("play-large")&&this.elements.container.appendChild(Z.createButton.call(this,"play-large")),this.elements.controls=n,this.isHTML5&&Z.setQualityMenu.call(this,j.getQualityOptions.call(this)),Z.setSpeedMenu.call(this),n},inject:function(){var e=this;if(this.config.loadSprite){var t=Z.getIconUrl.call(this);t.cors&&Q(t.url,"sprite-plyr")}this.id=Math.floor(1e4*Math.random());var n=null;this.elements.controls=null;var a={id:this.id,seektime:this.config.seekTime,title:this.config.title},s=!0;i.string(this.config.controls)||i.element(this.config.controls)?n=this.config.controls:i.function(this.config.controls)?n=this.config.controls.call(this,a):(n=Z.create.call(this,{id:this.id,seektime:this.config.seekTime,speed:this.speed,quality:this.quality,captions:ie.getLabel.call(this)}),s=!1);var r=function(e){var t=e;return Object.entries(a).forEach(function(e){var i=p(e,2),n=i[0],a=i[1];t=H(t,"{"+n+"}",a)}),t};s&&(i.string(this.config.controls)?n=r(n):i.element(n)&&(n.innerHTML=r(n.innerHTML)));var l,o=void 0;if(i.string(this.config.selectors.controls.container)&&(o=document.querySelector(this.config.selectors.controls.container)),i.element(o)||(o=this.elements.container),i.element(n)?o.appendChild(n):n&&o.insertAdjacentHTML("beforeend",n),i.element(this.elements.controls)||Z.findElements.call(this),window.navigator.userAgent.includes("Edge")&&(l=o,setTimeout(function(){w(l,!0),l.offsetHeight,w(l,!1)},0)),this.config.tooltips.controls){var c=this.config,u=c.classNames,d=c.selectors,h=d.controls.wrapper+" "+d.labels+" ."+u.hidden,m=C.call(this,h);Array.from(m).forEach(function(t){T(t,e.config.classNames.hidden,!1),T(t,e.config.classNames.tooltip,!0)})}}};function ee(e){var t=e;if(!(arguments.length>1&&void 0!==arguments[1])||arguments[1]){var i=document.createElement("a");i.href=t,t=i.href}try{return new URL(t)}catch(e){return null}}function te(e){var t=new URLSearchParams;return i.object(e)&&Object.entries(e).forEach(function(e){var i=p(e,2),n=i[0],a=i[1];t.set(n,a)}),t}var ie={setup:function(){if(this.supported.ui)if(!this.isVideo||this.isYouTube||this.isHTML5&&!O.textTracks)i.array(this.config.controls)&&this.config.controls.includes("settings")&&this.config.settings.includes("captions")&&Z.setCaptionsMenu.call(this);else{var e,t;if(i.element(this.elements.captions)||(this.elements.captions=f("div",k(this.config.selectors.captions)),e=this.elements.captions,t=this.elements.wrapper,i.element(e)&&i.element(t)&&t.parentNode.insertBefore(e,t.nextSibling)),I.isIE&&window.URL){var n=this.media.querySelectorAll("track");Array.from(n).forEach(function(e){var t=e.getAttribute("src"),i=ee(t);null!==i&&i.hostname!==window.location.href.hostname&&["http:","https:"].includes(i.protocol)&&Y(t,"blob").then(function(t){e.setAttribute("src",window.URL.createObjectURL(t))}).catch(function(){y(e)})})}var a=W(Array.from(navigator.languages||navigator.userLanguage).map(function(e){return e.split("-")[0]})),r=(this.storage.get("language")||this.config.captions.language||"auto").toLowerCase();if("auto"===r)r=p(a,1)[0];var l=this.storage.get("captions");if(i.boolean(l)||(l=this.config.captions.active),Object.assign(this.captions,{toggled:!1,active:l,language:r,languages:a}),this.isHTML5){var o=this.config.captions.update?"addtrack removetrack":"removetrack";s.call(this,this.media.textTracks,o,ie.update.bind(this))}setTimeout(ie.update.bind(this),0)}},update:function(){var e=this,t=ie.getTracks.call(this,!0),n=this.captions,a=n.active,r=n.language,l=n.meta,o=n.currentTrackNode,c=Boolean(t.find(function(e){return e.language===r}));this.isHTML5&&this.isVideo&&t.filter(function(e){return!l.get(e)}).forEach(function(t){e.debug.log("Track added",t),l.set(t,{default:"showing"===t.mode}),t.mode="hidden",s.call(e,t,"cuechange",function(){return ie.updateCues.call(e)})}),(c&&this.language!==r||!t.includes(o))&&(ie.setLanguage.call(this,r),ie.toggle.call(this,a&&c)),T(this.elements.container,this.config.classNames.captions.enabled,!i.empty(t)),(this.config.controls||[]).includes("settings")&&this.config.settings.includes("captions")&&Z.setCaptionsMenu.call(this)},toggle:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(this.supported.ui){var n=this.captions.toggled,a=this.config.classNames.captions.active,s=i.nullOrUndefined(e)?!n:e;if(s!==n){if(t||(this.captions.active=s,this.storage.set({captions:s})),!this.language&&s&&!t){var r=ie.getTracks.call(this),l=ie.findTrack.call(this,[this.captions.language].concat(function(e){if(Array.isArray(e)){for(var t=0,i=Array(e.length);t<e.length;t++)i[t]=e[t];return i}return Array.from(e)}(this.captions.languages)),!0);return this.captions.language=l.language,void ie.set.call(this,r.indexOf(l))}this.elements.buttons.captions.pressed=s,T(this.elements.container,a,s),this.captions.toggled=s,Z.updateSetting.call(this,"captions"),o.call(this,this.media,s?"captionsenabled":"captionsdisabled")}}},set:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=ie.getTracks.call(this);if(-1!==e)if(i.number(e))if(e in n){if(this.captions.currentTrack!==e){this.captions.currentTrack=e;var a=n[e],s=(a||{}).language;this.captions.currentTrackNode=a,Z.updateSetting.call(this,"captions"),t||(this.captions.language=s,this.storage.set({language:s})),this.isVimeo&&this.embed.enableTextTrack(s),o.call(this,this.media,"languagechange")}ie.toggle.call(this,!0,t),this.isHTML5&&this.isVideo&&ie.updateCues.call(this)}else this.debug.warn("Track not found",e);else this.debug.warn("Invalid caption argument",e);else ie.toggle.call(this,!1,t)},setLanguage:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(i.string(e)){var n=e.toLowerCase();this.captions.language=n;var a=ie.getTracks.call(this),s=ie.findTrack.call(this,[n]);ie.set.call(this,a.indexOf(s),t)}else this.debug.warn("Invalid language argument",e)},getTracks:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return Array.from((this.media||{}).textTracks||[]).filter(function(i){return!e.isHTML5||t||e.captions.meta.has(i)}).filter(function(e){return["captions","subtitles"].includes(e.kind)})},findTrack:function(e){var t=this,i=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=ie.getTracks.call(this),a=function(e){return Number((t.captions.meta.get(e)||{}).default)},s=Array.from(n).sort(function(e,t){return a(t)-a(e)}),r=void 0;return e.every(function(e){return!(r=s.find(function(t){return t.language===e}))}),r||(i?s[0]:void 0)},getCurrentTrack:function(){return ie.getTracks.call(this)[this.currentTrack]},getLabel:function(e){var t=e;return!i.track(t)&&O.textTracks&&this.captions.toggled&&(t=ie.getCurrentTrack.call(this)),i.track(t)?i.empty(t.label)?i.empty(t.language)?z("enabled",this.config):e.language.toUpperCase():t.label:z("disabled",this.config)},updateCues:function(e){if(this.supported.ui)if(i.element(this.elements.captions))if(i.nullOrUndefined(e)||Array.isArray(e)){var t=e;if(!t){var n=ie.getCurrentTrack.call(this);t=Array.from((n||{}).activeCues||[]).map(function(e){return e.getCueAsHTML()}).map(U)}var a=t.map(function(e){return e.trim()}).join("\n");if(a!==this.elements.captions.innerHTML){v(this.elements.captions);var s=f("span",k(this.config.selectors.caption));s.innerHTML=a,this.elements.captions.appendChild(s),o.call(this,this.media,"cuechange")}}else this.debug.warn("updateCues: Invalid input",e);else this.debug.warn("No captions element to render to")}},ne={enabled:!0,title:"",debug:!1,autoplay:!1,autopause:!0,playsinline:!0,seekTime:10,volume:1,muted:!1,duration:null,displayDuration:!0,invertTime:!0,toggleInvert:!0,ratio:"16:9",clickToPlay:!0,hideControls:!0,resetOnEnd:!1,disableContextMenu:!0,loadSprite:!0,iconPrefix:"plyr",iconUrl:"https://cdn.plyr.io/3.3.12/plyr.svg",blankVideo:"https://cdn.plyr.io/static/blank.mp4",quality:{default:576,options:[4320,2880,2160,1440,1080,720,576,480,360,240,"default"]},loop:{active:!1},speed:{selected:1,options:[.5,.75,1,1.25,1.5,1.75,2]},keyboard:{focused:!0,global:!1},tooltips:{controls:!1,seek:!0},captions:{active:!1,language:"auto",update:!1},fullscreen:{enabled:!0,fallback:!0,iosNative:!1},storage:{enabled:!0,key:"plyr"},controls:["play-large","play","progress","current-time","mute","volume","captions","settings","pip","airplay","fullscreen"],settings:["captions","quality","speed"],i18n:{restart:"Restart",rewind:"Rewind {seektime}s",play:"Play",pause:"Pause",fastForward:"Forward {seektime}s",seek:"Seek",seekLabel:"{currentTime} of {duration}",played:"Played",buffered:"Buffered",currentTime:"Current time",duration:"Duration",volume:"Volume",mute:"Mute",unmute:"Unmute",enableCaptions:"Enable captions",disableCaptions:"Disable captions",enterFullscreen:"Enter fullscreen",exitFullscreen:"Exit fullscreen",frameTitle:"Player for {title}",captions:"Captions",settings:"Settings",menuBack:"Go back to previous menu",speed:"Speed",normal:"Normal",quality:"Quality",loop:"Loop",start:"Start",end:"End",all:"All",reset:"Reset",disabled:"Disabled",enabled:"Enabled",advertisement:"Ad",qualityBadge:{2160:"4K",1440:"HD",1080:"HD",720:"HD",576:"SD",480:"SD"}},urls:{vimeo:{sdk:"https://player.vimeo.com/api/player.js",iframe:"https://player.vimeo.com/video/{0}?{1}",api:"https://vimeo.com/api/v2/video/{0}.json"},youtube:{sdk:"https://www.youtube.com/iframe_api",api:"https://www.googleapis.com/youtube/v3/videos?id={0}&key={1}&fields=items(snippet(title))&part=snippet"},googleIMA:{sdk:"https://imasdk.googleapis.com/js/sdkloader/ima3.js"}},listeners:{seek:null,play:null,pause:null,restart:null,rewind:null,fastForward:null,mute:null,volume:null,captions:null,fullscreen:null,pip:null,airplay:null,speed:null,quality:null,loop:null,language:null},events:["ended","progress","stalled","playing","waiting","canplay","canplaythrough","loadstart","loadeddata","loadedmetadata","timeupdate","volumechange","play","pause","error","seeking","seeked","emptied","ratechange","cuechange","enterfullscreen","exitfullscreen","captionsenabled","captionsdisabled","languagechange","controlshidden","controlsshown","ready","statechange","qualitychange","qualityrequested","adsloaded","adscontentpause","adscontentresume","adstarted","adsmidpoint","adscomplete","adsallcomplete","adsimpression","adsclick"],selectors:{editable:"input, textarea, select, [contenteditable]",container:".plyr",controls:{container:null,wrapper:".plyr__controls"},labels:"[data-plyr]",buttons:{play:'[data-plyr="play"]',pause:'[data-plyr="pause"]',restart:'[data-plyr="restart"]',rewind:'[data-plyr="rewind"]',fastForward:'[data-plyr="fast-forward"]',mute:'[data-plyr="mute"]',captions:'[data-plyr="captions"]',fullscreen:'[data-plyr="fullscreen"]',pip:'[data-plyr="pip"]',airplay:'[data-plyr="airplay"]',settings:'[data-plyr="settings"]',loop:'[data-plyr="loop"]'},inputs:{seek:'[data-plyr="seek"]',volume:'[data-plyr="volume"]',speed:'[data-plyr="speed"]',language:'[data-plyr="language"]',quality:'[data-plyr="quality"]'},display:{currentTime:".plyr__time--current",duration:".plyr__time--duration",buffer:".plyr__progress__buffer",loop:".plyr__progress__loop",volume:".plyr__volume--display"},progress:".plyr__progress",captions:".plyr__captions",caption:".plyr__caption",menu:{quality:".js-plyr__menu__list--quality"}},classNames:{type:"plyr--{0}",provider:"plyr--{0}",video:"plyr__video-wrapper",embed:"plyr__video-embed",embedContainer:"plyr__video-embed__container",poster:"plyr__poster",posterEnabled:"plyr__poster-enabled",ads:"plyr__ads",control:"plyr__control",controlPressed:"plyr__control--pressed",playing:"plyr--playing",paused:"plyr--paused",stopped:"plyr--stopped",loading:"plyr--loading",hover:"plyr--hover",tooltip:"plyr__tooltip",cues:"plyr__cues",hidden:"plyr__sr-only",hideControls:"plyr--hide-controls",isIos:"plyr--is-ios",isTouch:"plyr--is-touch",uiSupported:"plyr--full-ui",noTransition:"plyr--no-transition",display:{time:"plyr__time"},menu:{value:"plyr__menu__value",badge:"plyr__badge",open:"plyr--menu-open"},captions:{enabled:"plyr--captions-enabled",active:"plyr--captions-active"},fullscreen:{enabled:"plyr--fullscreen-enabled",fallback:"plyr--fullscreen-fallback"},pip:{supported:"plyr--pip-supported",active:"plyr--pip-active"},airplay:{supported:"plyr--airplay-supported",active:"plyr--airplay-active"},tabFocus:"plyr__tab-focus"},attributes:{embed:{provider:"data-plyr-provider",id:"data-plyr-embed-id"}},keys:{google:null},ads:{enabled:!1,publisherId:""}},ae={html5:"html5",youtube:"youtube",vimeo:"vimeo"},se={audio:"audio",video:"video"};var re=function(){},le=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];c(this,e),this.enabled=window.console&&t,this.enabled&&this.log("Debugging enabled")}return u(e,[{key:"log",get:function(){return this.enabled?Function.prototype.bind.call(console.log,console):re}},{key:"warn",get:function(){return this.enabled?Function.prototype.bind.call(console.warn,console):re}},{key:"error",get:function(){return this.enabled?Function.prototype.bind.call(console.error,console):re}}]),e}();function oe(){if(this.enabled){var e=this.player.elements.buttons.fullscreen;i.element(e)&&(e.pressed=this.active),o.call(this.player,this.target,this.active?"enterfullscreen":"exitfullscreen",!0),I.isIos||function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(i.element(e)){var n=C.call(this,"button:not(:disabled), input:not(:disabled), [tabindex]"),s=n[0],r=n[n.length-1];a.call(this,this.elements.container,"keydown",function(e){if("Tab"===e.key&&9===e.keyCode){var t=S();t!==r||e.shiftKey?t===s&&e.shiftKey&&(r.focus(),e.preventDefault()):(s.focus(),e.preventDefault())}},t,!1)}}.call(this.player,this.target,this.active)}}function ce(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];e?this.scrollPosition={x:window.scrollX||0,y:window.scrollY||0}:window.scrollTo(this.scrollPosition.x,this.scrollPosition.y),document.body.style.overflow=e?"hidden":"",T(this.target,this.player.config.classNames.fullscreen.fallback,e),oe.call(this)}var ue=function(){function e(t){var n=this;c(this,e),this.player=t,this.prefix=e.prefix,this.property=e.property,this.scrollPosition={x:0,y:0},s.call(this.player,document,"ms"===this.prefix?"MSFullscreenChange":this.prefix+"fullscreenchange",function(){oe.call(n)}),s.call(this.player,this.player.elements.container,"dblclick",function(e){i.element(n.player.elements.controls)&&n.player.elements.controls.contains(e.target)||n.toggle()}),this.update()}return u(e,[{key:"update",value:function(){this.enabled?this.player.debug.log((e.native?"Native":"Fallback")+" fullscreen enabled"):this.player.debug.log("Fullscreen not supported and fallback disabled"),T(this.player.elements.container,this.player.config.classNames.fullscreen.enabled,this.enabled)}},{key:"enter",value:function(){this.enabled&&(I.isIos&&this.player.config.fullscreen.iosNative?this.player.playing&&this.target.webkitEnterFullscreen():e.native?this.prefix?i.empty(this.prefix)||this.target[this.prefix+"Request"+this.property]():this.target.requestFullscreen():ce.call(this,!0))}},{key:"exit",value:function(){if(this.enabled)if(I.isIos&&this.player.config.fullscreen.iosNative)this.target.webkitExitFullscreen(),this.player.play();else if(e.native)if(this.prefix){if(!i.empty(this.prefix)){var t="moz"===this.prefix?"Cancel":"Exit";document[""+this.prefix+t+this.property]()}}else(document.cancelFullScreen||document.exitFullscreen).call(document);else ce.call(this,!1)}},{key:"toggle",value:function(){this.active?this.exit():this.enter()}},{key:"enabled",get:function(){return(e.native||this.player.config.fullscreen.fallback)&&this.player.config.fullscreen.enabled&&this.player.supported.ui&&this.player.isVideo}},{key:"active",get:function(){return!!this.enabled&&(e.native?(this.prefix?document[""+this.prefix+this.property+"Element"]:document.fullscreenElement)===this.target:A(this.target,this.player.config.classNames.fullscreen.fallback))}},{key:"target",get:function(){return I.isIos&&this.player.config.fullscreen.iosNative?this.player.media:this.player.elements.container}}],[{key:"native",get:function(){return!!(document.fullscreenEnabled||document.webkitFullscreenEnabled||document.mozFullScreenEnabled||document.msFullscreenEnabled)}},{key:"prefix",get:function(){if(i.function(document.exitFullscreen))return"";var e="";return["webkit","moz","ms"].some(function(t){return!(!i.function(document[t+"ExitFullscreen"])&&!i.function(document[t+"CancelFullScreen"]))&&(e=t,!0)}),e}},{key:"property",get:function(){return"moz"===this.prefix?"FullScreen":"Fullscreen"}}]),e}();function de(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return new Promise(function(i,n){var a=new Image,s=function(){delete a.onload,delete a.onerror,(a.naturalWidth>=t?i:n)(a)};Object.assign(a,{onload:s,onerror:s,src:e})})}var pe={addStyleHook:function(){T(this.elements.container,this.config.selectors.container.replace(".",""),!0),T(this.elements.container,this.config.classNames.uiSupported,this.supported.ui)},toggleNativeControls:function(){arguments.length>0&&void 0!==arguments[0]&&arguments[0]&&this.isHTML5?this.media.setAttribute("controls",""):this.media.removeAttribute("controls")},build:function(){var e=this;if(this.listeners.media(),!this.supported.ui)return this.debug.warn("Basic support only for "+this.provider+" "+this.type),void pe.toggleNativeControls.call(this,!0);i.element(this.elements.controls)||(Z.inject.call(this),this.listeners.controls()),pe.toggleNativeControls.call(this),this.isHTML5&&ie.setup.call(this),this.volume=null,this.muted=null,this.speed=null,this.loop=null,this.quality=null,Z.updateVolume.call(this),Z.timeUpdate.call(this),pe.checkPlaying.call(this),T(this.elements.container,this.config.classNames.pip.supported,O.pip&&this.isHTML5&&this.isVideo),T(this.elements.container,this.config.classNames.airplay.supported,O.airplay&&this.isHTML5),T(this.elements.container,this.config.classNames.isIos,I.isIos),T(this.elements.container,this.config.classNames.isTouch,this.touch),this.ready=!0,setTimeout(function(){o.call(e,e.media,"ready")},0),pe.setTitle.call(this),this.poster&&pe.setPoster.call(this,this.poster,!1).catch(function(){}),this.config.duration&&Z.durationUpdate.call(this)},setTitle:function(){var e=z("play",this.config);if(i.string(this.config.title)&&!i.empty(this.config.title)&&(e+=", "+this.config.title),i.nodeList(this.elements.buttons.play)&&Array.from(this.elements.buttons.play).forEach(function(t){t.setAttribute("aria-label",e)}),this.isEmbed){var t=P.call(this,"iframe");if(!i.element(t))return;var n=i.empty(this.config.title)?"video":this.config.title,a=z("frameTitle",this.config);t.setAttribute("title",a.replace("{title}",n))}},togglePoster:function(e){T(this.elements.container,this.config.classNames.posterEnabled,e)},setPoster:function(e){var t=this;return arguments.length>1&&void 0!==arguments[1]&&!arguments[1]||!this.poster?(this.media.setAttribute("poster",e),function(){var e=this;return new Promise(function(t){return e.ready?setTimeout(t,0):s.call(e,e.elements.container,"ready",t)}).then(function(){})}.call(this).then(function(){return de(e)}).catch(function(i){throw e===t.poster&&pe.togglePoster.call(t,!1),i}).then(function(){if(e!==t.poster)throw new Error("setPoster cancelled by later call to setPoster")}).then(function(){return Object.assign(t.elements.poster.style,{backgroundImage:"url('"+e+"')",backgroundSize:""}),pe.togglePoster.call(t,!0),e})):Promise.reject(new Error("Poster already set"))},checkPlaying:function(e){var t=this;T(this.elements.container,this.config.classNames.playing,this.playing),T(this.elements.container,this.config.classNames.paused,this.paused),T(this.elements.container,this.config.classNames.stopped,this.stopped),i.nodeList(this.elements.buttons.play)&&Array.from(this.elements.buttons.play).forEach(function(e){e.pressed=t.playing}),i.event(e)&&"timeupdate"===e.type||pe.toggleControls.call(this)},checkLoading:function(e){var t=this;this.loading=["stalled","waiting"].includes(e.type),clearTimeout(this.timers.loading),this.timers.loading=setTimeout(function(){T(t.elements.container,t.config.classNames.loading,t.loading),pe.toggleControls.call(t)},this.loading?250:0)},toggleControls:function(e){var t=this.elements.controls;t&&this.config.hideControls&&this.toggleControls(Boolean(e||this.loading||this.paused||t.pressed||t.hover))}},he=function(){function e(t){c(this,e),this.player=t,this.lastKey=null,this.handleKey=this.handleKey.bind(this),this.toggleMenu=this.toggleMenu.bind(this),this.firstTouch=this.firstTouch.bind(this)}return u(e,[{key:"handleKey",value:function(e){var t=this,n=e.keyCode?e.keyCode:e.which,a="keydown"===e.type,s=a&&n===this.lastKey;if(!(e.altKey||e.ctrlKey||e.metaKey||e.shiftKey)&&i.number(n)){if(a){var r=S();if(i.element(r)&&r!==this.player.elements.inputs.seek&&E(r,this.player.config.selectors.editable))return;switch([32,37,38,39,40,48,49,50,51,52,53,54,56,57,67,70,73,75,76,77,79].includes(n)&&(e.preventDefault(),e.stopPropagation()),n){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:s||(t.player.currentTime=t.player.duration/10*(n-48));break;case 32:case 75:s||this.player.togglePlay();break;case 38:this.player.increaseVolume(.1);break;case 40:this.player.decreaseVolume(.1);break;case 77:s||(this.player.muted=!this.player.muted);break;case 39:this.player.forward();break;case 37:this.player.rewind();break;case 70:this.player.fullscreen.toggle();break;case 67:s||this.player.toggleCaptions();break;case 76:this.player.loop=!this.player.loop}!this.player.fullscreen.enabled&&this.player.fullscreen.active&&27===n&&this.player.fullscreen.toggle(),this.lastKey=n}else this.lastKey=null}}},{key:"toggleMenu",value:function(e){Z.toggleMenu.call(this.player,e)}},{key:"firstTouch",value:function(){this.player.touch=!0,T(this.player.elements.container,this.player.config.classNames.isTouch,!0)}},{key:"global",value:function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.player.config.keyboard.global&&a.call(this.player,window,"keydown keyup",this.handleKey,e,!1),a.call(this.player,document.body,"click",this.toggleMenu,e),l.call(this.player,document.body,"touchstart",this.firstTouch)}},{key:"container",value:function(){var e=this;!this.player.config.keyboard.global&&this.player.config.keyboard.focused&&s.call(this.player,this.player.elements.container,"keydown keyup",this.handleKey,!1),s.call(this.player,this.player.elements.container,"focusout",function(t){T(t.target,e.player.config.classNames.tabFocus,!1)}),s.call(this.player,this.player.elements.container,"keydown",function(t){9===t.keyCode&&setTimeout(function(){T(S(),e.player.config.classNames.tabFocus,!0)},0)}),s.call(this.player,this.player.elements.container,"mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen",function(t){var i=e.player.elements.controls;"enterfullscreen"===t.type&&(i.pressed=!1,i.hover=!1);var n=0;["touchstart","touchmove","mousemove"].includes(t.type)&&(pe.toggleControls.call(e.player,!0),n=e.player.touch?3e3:2e3),clearTimeout(e.player.timers.controls),e.player.timers.controls=setTimeout(function(){return pe.toggleControls.call(e.player,!1)},n)})}},{key:"media",value:function(){var e=this;if(s.call(this.player,this.player.media,"timeupdate seeking seeked",function(t){return Z.timeUpdate.call(e.player,t)}),s.call(this.player,this.player.media,"durationchange loadeddata loadedmetadata",function(t){return Z.durationUpdate.call(e.player,t)}),s.call(this.player,this.player.media,"canplay",function(){w(e.player.elements.volume,!e.player.hasAudio),w(e.player.elements.buttons.mute,!e.player.hasAudio)}),s.call(this.player,this.player.media,"ended",function(){e.player.isHTML5&&e.player.isVideo&&e.player.config.resetOnEnd&&e.player.restart()}),s.call(this.player,this.player.media,"progress playing seeking seeked",function(t){return Z.updateProgress.call(e.player,t)}),s.call(this.player,this.player.media,"volumechange",function(t){return Z.updateVolume.call(e.player,t)}),s.call(this.player,this.player.media,"playing play pause ended emptied timeupdate",function(t){return pe.checkPlaying.call(e.player,t)}),s.call(this.player,this.player.media,"waiting canplay seeked playing",function(t){return pe.checkLoading.call(e.player,t)}),s.call(this.player,this.player.media,"playing",function(){e.player.ads&&e.player.ads.enabled&&!e.player.ads.initialized&&e.player.ads.managerPromise.then(function(){return e.player.ads.play()}).catch(function(){return e.player.play()})}),this.player.supported.ui&&this.player.config.clickToPlay&&!this.player.isAudio){var t=P.call(this.player,"."+this.player.config.classNames.video);if(!i.element(t))return;s.call(this.player,t,"click",function(){e.player.config.hideControls&&e.player.touch&&!e.player.paused||(e.player.paused?e.player.play():e.player.ended?(e.player.restart(),e.player.play()):e.player.pause())})}this.player.supported.ui&&this.player.config.disableContextMenu&&s.call(this.player,this.player.elements.wrapper,"contextmenu",function(e){e.preventDefault()},!1),s.call(this.player,this.player.media,"volumechange",function(){e.player.storage.set({volume:e.player.volume,muted:e.player.muted})}),s.call(this.player,this.player.media,"ratechange",function(){Z.updateSetting.call(e.player,"speed"),e.player.storage.set({speed:e.player.speed})}),s.call(this.player,this.player.media,"qualityrequested",function(t){e.player.storage.set({quality:t.detail.quality})}),s.call(this.player,this.player.media,"qualitychange",function(t){Z.updateSetting.call(e.player,"quality",null,t.detail.quality)});var n=this.player.config.events.concat(["keyup","keydown"]).join(" ");s.call(this.player,this.player.media,n,function(t){var i=t.detail,n=void 0===i?{}:i;"error"===t.type&&(n=e.player.media.error),o.call(e.player,e.player.elements.container,t.type,!0,n)})}},{key:"controls",value:function(){var e=this,t=I.isIE?"change":"input",n=function(t,n,a){var s=e.player.config.listeners[a],r=!0;i.function(s)&&(r=s.call(e.player,t)),r&&i.function(n)&&n.call(e.player,t)},a=function(t,a,r,l){var o=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],c=e.player.config.listeners[l],u=i.function(c);s.call(e.player,t,a,function(e){return n(e,r,l)},o&&!u)};Array.from(this.player.elements.buttons.play).forEach(function(t){a(t,"click",e.player.togglePlay,"play")}),a(this.player.elements.buttons.restart,"click",this.player.restart,"restart"),a(this.player.elements.buttons.rewind,"click",this.player.rewind,"rewind"),a(this.player.elements.buttons.fastForward,"click",this.player.forward,"fastForward"),a(this.player.elements.buttons.mute,"click",function(){e.player.muted=!e.player.muted},"mute"),a(this.player.elements.buttons.captions,"click",function(){return e.player.toggleCaptions()}),a(this.player.elements.buttons.fullscreen,"click",function(){e.player.fullscreen.toggle()},"fullscreen"),a(this.player.elements.buttons.pip,"click",function(){e.player.pip="toggle"},"pip"),a(this.player.elements.buttons.airplay,"click",this.player.airplay,"airplay"),a(this.player.elements.buttons.settings,"click",function(t){Z.toggleMenu.call(e.player,t)}),a(this.player.elements.settings.popup,"click",function(t){t.stopPropagation();var i=function(){Z.showMenuPanel.call(e.player,"home")};E(t.target,e.player.config.selectors.inputs.language)?n(t,function(){e.player.currentTrack=Number(t.target.value),i()},"language"):E(t.target,e.player.config.selectors.inputs.quality)?n(t,function(){e.player.quality=t.target.value,i()},"quality"):E(t.target,e.player.config.selectors.inputs.speed)&&n(t,function(){e.player.speed=parseFloat(t.target.value),i()},"speed")}),a(this.player.elements.inputs.seek,"mousedown mousemove",function(t){var i=e.player.elements.progress.getBoundingClientRect(),n=100/i.width*(t.pageX-i.left);t.currentTarget.setAttribute("seek-value",n)}),a(this.player.elements.inputs.seek,"mousedown mouseup keydown keyup touchstart touchend",function(t){var i=t.currentTarget,n=t.keyCode?t.keyCode:t.which,a=t.type;if("keydown"!==a&&"keyup"!==a||39===n||37===n){var s=i.hasAttribute("play-on-seeked"),r=["mouseup","touchend","keyup"].includes(t.type);s&&r?(i.removeAttribute("play-on-seeked"),e.player.play()):!r&&e.player.playing&&(i.setAttribute("play-on-seeked",""),e.player.pause())}}),a(this.player.elements.inputs.seek,t,function(t){var n=t.currentTarget,a=n.getAttribute("seek-value");i.empty(a)&&(a=n.value),n.removeAttribute("seek-value"),e.player.currentTime=a/n.max*e.player.duration},"seek"),this.player.config.toggleInvert&&!i.element(this.player.elements.display.duration)&&a(this.player.elements.display.currentTime,"click",function(){0!==e.player.currentTime&&(e.player.config.invertTime=!e.player.config.invertTime,Z.timeUpdate.call(e.player))}),a(this.player.elements.inputs.volume,t,function(t){e.player.volume=t.target.value},"volume"),I.isWebkit&&Array.from(C.call(this.player,'input[type="range"]')).forEach(function(t){a(t,"input",function(t){return Z.updateRangeFill.call(e.player,t.target)})}),a(this.player.elements.progress,"mouseenter mouseleave mousemove",function(t){return Z.updateSeekTooltip.call(e.player,t)}),a(this.player.elements.controls,"mouseenter mouseleave",function(t){e.player.elements.controls.hover=!e.player.touch&&"mouseenter"===t.type}),a(this.player.elements.controls,"mousedown mouseup touchstart touchend touchcancel",function(t){e.player.elements.controls.pressed=["mousedown","touchstart"].includes(t.type)}),a(this.player.elements.controls,"focusin focusout",function(t){var i=e.player,n=i.config,a=i.elements,s=i.timers;if(T(a.controls,n.classNames.noTransition,"focusin"===t.type),pe.toggleControls.call(e.player,"focusin"===t.type),"focusin"===t.type){setTimeout(function(){T(a.controls,n.classNames.noTransition,!1)},0);var r=e.touch?3e3:4e3;clearTimeout(s.controls),s.controls=setTimeout(function(){return pe.toggleControls.call(e.player,!1)},r)}}),a(this.player.elements.inputs.volume,"wheel",function(t){var i=t.webkitDirectionInvertedFromDevice,n=0;(t.deltaY<0||t.deltaX>0)&&(i?(e.player.decreaseVolume(.02),n=-1):(e.player.increaseVolume(.02),n=1)),(t.deltaY>0||t.deltaX<0)&&(i?(e.player.increaseVolume(.02),n=1):(e.player.decreaseVolume(.02),n=-1)),(1===n&&e.player.media.volume<1||-1===n&&e.player.media.volume>0)&&t.preventDefault()},"volume",!1)}}]),e}();"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var me,fe=(function(e,t){var i;i=function(){var e=function(){},t={},i={},n={};function a(e,t){if(e){var a=n[e];if(i[e]=t,a)for(;a.length;)a[0](e,t),a.splice(0,1)}}function s(t,i){t.call&&(t={success:t}),i.length?(t.error||e)(i):(t.success||e)(t)}function r(t,i,n,a){var s,l,o=document,c=n.async,u=(n.numRetries||0)+1,d=n.before||e,p=t.replace(/^(css|img)!/,"");a=a||0,/(^css!|\.css$)/.test(t)?(s=!0,(l=o.createElement("link")).rel="stylesheet",l.href=p):/(^img!|\.(png|gif|jpg|svg)$)/.test(t)?(l=o.createElement("img")).src=p:((l=o.createElement("script")).src=t,l.async=void 0===c||c),l.onload=l.onerror=l.onbeforeload=function(e){var o=e.type[0];if(s&&"hideFocus"in l)try{l.sheet.cssText.length||(o="e")}catch(e){o="e"}if("e"==o&&(a+=1)<u)return r(t,i,n,a);i(t,o,e.defaultPrevented)},!1!==d(t,l)&&o.head.appendChild(l)}function l(e,i,n){var l,o;if(i&&i.trim&&(l=i),o=(l?n:i)||{},l){if(l in t)throw"LoadJS";t[l]=!0}!function(e,t,i){var n,a,s=(e=e.push?e:[e]).length,l=s,o=[];for(n=function(e,i,n){if("e"==i&&o.push(e),"b"==i){if(!n)return;o.push(e)}--s||t(o)},a=0;a<l;a++)r(e[a],n,i)}(e,function(e){s(o,e),a(l,e)},o)}return l.ready=function(e,t){return function(e,t){e=e.push?e:[e];var a,s,r,l=[],o=e.length,c=o;for(a=function(e,i){i.length&&l.push(e),--c||t(l)};o--;)s=e[o],(r=i[s])?a(s,r):(n[s]=n[s]||[]).push(a)}(e,function(e){s(t,e)}),l},l.done=function(e){a(e,[])},l.reset=function(){t={},i={},n={}},l.isDefined=function(e){return e in t},l},e.exports=i()}(me={exports:{}},me.exports),me.exports);function ge(e){return new Promise(function(t,i){fe(e,{success:t,error:i})})}function ye(e){e&&!this.embed.hasPlayed&&(this.embed.hasPlayed=!0),this.media.paused===e&&(this.media.paused=!e,o.call(this,this.media,e?"play":"pause"))}var ve={setup:function(){var e=this;T(this.elements.wrapper,this.config.classNames.embed,!0),ve.setAspectRatio.call(this),i.object(window.Vimeo)?ve.ready.call(this):ge(this.config.urls.vimeo.sdk).then(function(){ve.ready.call(e)}).catch(function(t){e.debug.warn("Vimeo API failed to load",t)})},setAspectRatio:function(e){var t=(i.string(e)?e:this.config.ratio).split(":"),n=p(t,2),a=100/n[0]*n[1];if(this.elements.wrapper.style.paddingBottom=a+"%",this.supported.ui){var s=(240-a)/4.8;this.media.style.transform="translateY(-"+s+"%)"}},ready:function(){var e=this,t=this,n=te({loop:t.config.loop.active,autoplay:t.autoplay,byline:!1,portrait:!1,title:!1,speed:!0,transparent:0,gesture:"media",playsinline:!this.config.fullscreen.iosNative}),a=t.media.getAttribute("src");i.empty(a)&&(a=t.media.getAttribute(t.config.attributes.embed.id));var s,r=(s=a,i.empty(s)?null:i.number(Number(s))?s:s.match(/^.*(vimeo.com\/|video\/)(\d+).*/)?RegExp.$2:s),l=f("iframe"),c=B(t.config.urls.vimeo.iframe,r,n);l.setAttribute("src",c),l.setAttribute("allowfullscreen",""),l.setAttribute("allowtransparency",""),l.setAttribute("allow","autoplay");var u=f("div",{poster:t.poster,class:t.config.classNames.embedContainer});u.appendChild(l),t.media=b(u,t.media),Y(B(t.config.urls.vimeo.api,r),"json").then(function(e){if(!i.empty(e)){var n=new URL(e[0].thumbnail_large);n.pathname=n.pathname.split("_")[0]+".jpg",pe.setPoster.call(t,n.href).catch(function(){})}}),t.embed=new window.Vimeo.Player(l,{autopause:t.config.autopause,muted:t.muted}),t.media.paused=!0,t.media.currentTime=0,t.supported.ui&&t.embed.disableTextTrack(),t.media.play=function(){return ye.call(t,!0),t.embed.play()},t.media.pause=function(){return ye.call(t,!1),t.embed.pause()},t.media.stop=function(){t.pause(),t.currentTime=0};var d=t.media.currentTime;Object.defineProperty(t.media,"currentTime",{get:function(){return d},set:function(e){var i=t.embed,n=t.media,a=t.paused,s=t.volume,r=a&&!i.hasPlayed;n.seeking=!0,o.call(t,n,"seeking"),Promise.resolve(r&&i.setVolume(0)).then(function(){return i.setCurrentTime(e)}).then(function(){return r&&i.pause()}).then(function(){return r&&i.setVolume(s)}).catch(function(){})}});var p=t.config.speed.selected;Object.defineProperty(t.media,"playbackRate",{get:function(){return p},set:function(e){t.embed.setPlaybackRate(e).then(function(){p=e,o.call(t,t.media,"ratechange")}).catch(function(e){"Error"===e.name&&Z.setSpeedMenu.call(t,[])})}});var h=t.config.volume;Object.defineProperty(t.media,"volume",{get:function(){return h},set:function(e){t.embed.setVolume(e).then(function(){h=e,o.call(t,t.media,"volumechange")})}});var m=t.config.muted;Object.defineProperty(t.media,"muted",{get:function(){return m},set:function(e){var n=!!i.boolean(e)&&e;t.embed.setVolume(n?0:t.config.volume).then(function(){m=n,o.call(t,t.media,"volumechange")})}});var g=t.config.loop;Object.defineProperty(t.media,"loop",{get:function(){return g},set:function(e){var n=i.boolean(e)?e:t.config.loop.active;t.embed.setLoop(n).then(function(){g=n})}});var y=void 0;t.embed.getVideoUrl().then(function(e){y=e}).catch(function(t){e.debug.warn(t)}),Object.defineProperty(t.media,"currentSrc",{get:function(){return y}}),Object.defineProperty(t.media,"ended",{get:function(){return t.currentTime===t.duration}}),Promise.all([t.embed.getVideoWidth(),t.embed.getVideoHeight()]).then(function(t){var i=function(e,t){var i=function e(t,i){return 0===i?t:e(i,t%i)}(e,t);return e/i+":"+t/i}(t[0],t[1]);ve.setAspectRatio.call(e,i)}),t.embed.setAutopause(t.config.autopause).then(function(e){t.config.autopause=e}),t.embed.getVideoTitle().then(function(i){t.config.title=i,pe.setTitle.call(e)}),t.embed.getCurrentTime().then(function(e){d=e,o.call(t,t.media,"timeupdate")}),t.embed.getDuration().then(function(e){t.media.duration=e,o.call(t,t.media,"durationchange")}),t.embed.getTextTracks().then(function(e){t.media.textTracks=e,ie.setup.call(t)}),t.embed.on("cuechange",function(e){var i=e.cues,n=(void 0===i?[]:i).map(function(e){return t=e.text,i=document.createDocumentFragment(),n=document.createElement("div"),i.appendChild(n),n.innerHTML=t,i.firstChild.innerText;var t,i,n});ie.updateCues.call(t,n)}),t.embed.on("loaded",function(){(t.embed.getPaused().then(function(e){ye.call(t,!e),e||o.call(t,t.media,"playing")}),i.element(t.embed.element)&&t.supported.ui)&&t.embed.element.setAttribute("tabindex",-1)}),t.embed.on("play",function(){ye.call(t,!0),o.call(t,t.media,"playing")}),t.embed.on("pause",function(){ye.call(t,!1)}),t.embed.on("timeupdate",function(e){t.media.seeking=!1,d=e.seconds,o.call(t,t.media,"timeupdate")}),t.embed.on("progress",function(e){t.media.buffered=e.percent,o.call(t,t.media,"progress"),1===parseInt(e.percent,10)&&o.call(t,t.media,"canplaythrough"),t.embed.getDuration().then(function(e){e!==t.media.duration&&(t.media.duration=e,o.call(t,t.media,"durationchange"))})}),t.embed.on("seeked",function(){t.media.seeking=!1,o.call(t,t.media,"seeked")}),t.embed.on("ended",function(){t.media.paused=!0,o.call(t,t.media,"ended")}),t.embed.on("error",function(e){t.media.error=e,o.call(t,t.media,"error")}),setTimeout(function(){return pe.build.call(t)},0)}};function be(e){var t=Object.entries({hd2160:2160,hd1440:1440,hd1080:1080,hd720:720,large:480,medium:360,small:240,tiny:144}).find(function(t){return t.includes(e)});return t?t.find(function(t){return t!==e}):"default"}function ke(e){e&&!this.embed.hasPlayed&&(this.embed.hasPlayed=!0),this.media.paused===e&&(this.media.paused=!e,o.call(this,this.media,e?"play":"pause"))}var we,Te={setup:function(){var e=this;T(this.elements.wrapper,this.config.classNames.embed,!0),Te.setAspectRatio.call(this),i.object(window.YT)&&i.function(window.YT.Player)?Te.ready.call(this):(ge(this.config.urls.youtube.sdk).catch(function(t){e.debug.warn("YouTube API failed to load",t)}),window.onYouTubeReadyCallbacks=window.onYouTubeReadyCallbacks||[],window.onYouTubeReadyCallbacks.push(function(){Te.ready.call(e)}),window.onYouTubeIframeAPIReady=function(){window.onYouTubeReadyCallbacks.forEach(function(e){e()})})},getTitle:function(e){var t=this;if(i.function(this.embed.getVideoData)){var n=this.embed.getVideoData().title;if(i.empty(n))return this.config.title=n,void pe.setTitle.call(this)}var a=this.config.keys.google;i.string(a)&&!i.empty(a)&&Y(B(this.config.urls.youtube.api,e,a)).then(function(e){i.object(e)&&(t.config.title=e.items[0].snippet.title,pe.setTitle.call(t))}).catch(function(){})},setAspectRatio:function(){var e=this.config.ratio.split(":");this.elements.wrapper.style.paddingBottom=100/e[0]*e[1]+"%"},ready:function(){var e=this,t=e.media.getAttribute("id");if(i.empty(t)||!t.startsWith("youtube-")){var n=e.media.getAttribute("src");i.empty(n)&&(n=e.media.getAttribute(this.config.attributes.embed.id));var a,s=(a=n,i.empty(a)?null:a.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/)?RegExp.$2:a),r=e.provider+"-"+Math.floor(1e4*Math.random()),l=f("div",{id:r,poster:e.poster});e.media=b(l,e.media);var c=function(e){return"https://img.youtube.com/vi/"+s+"/"+e+"default.jpg"};de(c("maxres"),121).catch(function(){return de(c("sd"),121)}).catch(function(){return de(c("hq"))}).then(function(t){return pe.setPoster.call(e,t.src)}).then(function(t){t.includes("maxres")||(e.elements.poster.style.backgroundSize="cover")}).catch(function(){}),e.embed=new window.YT.Player(r,{videoId:s,playerVars:{autoplay:e.config.autoplay?1:0,controls:e.supported.ui?0:1,rel:0,showinfo:0,iv_load_policy:3,modestbranding:1,disablekb:1,playsinline:1,widget_referrer:window?window.location.href:null,cc_load_policy:e.captions.active?1:0,cc_lang_pref:e.config.captions.language},events:{onError:function(t){if(!e.media.error){var i=t.data,n={2:"The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.",5:"The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.",100:"The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.",101:"The owner of the requested video does not allow it to be played in embedded players.",150:"The owner of the requested video does not allow it to be played in embedded players."}[i]||"An unknown error occured";e.media.error={code:i,message:n},o.call(e,e.media,"error")}},onPlaybackQualityChange:function(){o.call(e,e.media,"qualitychange",!1,{quality:e.media.quality})},onPlaybackRateChange:function(t){var i=t.target;e.media.playbackRate=i.getPlaybackRate(),o.call(e,e.media,"ratechange")},onReady:function(t){var n=t.target;Te.getTitle.call(e,s),e.media.play=function(){ke.call(e,!0),n.playVideo()},e.media.pause=function(){ke.call(e,!1),n.pauseVideo()},e.media.stop=function(){n.stopVideo()},e.media.duration=n.getDuration(),e.media.paused=!0,e.media.currentTime=0,Object.defineProperty(e.media,"currentTime",{get:function(){return Number(n.getCurrentTime())},set:function(t){e.paused&&e.embed.mute(),e.media.seeking=!0,o.call(e,e.media,"seeking"),n.seekTo(t)}}),Object.defineProperty(e.media,"playbackRate",{get:function(){return n.getPlaybackRate()},set:function(e){n.setPlaybackRate(e)}}),Object.defineProperty(e.media,"quality",{get:function(){return be(n.getPlaybackQuality())},set:function(e){n.setPlaybackQuality(be(e))}});var a=e.config.volume;Object.defineProperty(e.media,"volume",{get:function(){return a},set:function(t){a=t,n.setVolume(100*a),o.call(e,e.media,"volumechange")}});var r=e.config.muted;Object.defineProperty(e.media,"muted",{get:function(){return r},set:function(t){var a=i.boolean(t)?t:r;r=a,n[a?"mute":"unMute"](),o.call(e,e.media,"volumechange")}}),Object.defineProperty(e.media,"currentSrc",{get:function(){return n.getVideoUrl()}}),Object.defineProperty(e.media,"ended",{get:function(){return e.currentTime===e.duration}}),e.options.speed=n.getAvailablePlaybackRates(),e.supported.ui&&e.media.setAttribute("tabindex",-1),o.call(e,e.media,"timeupdate"),o.call(e,e.media,"durationchange"),clearInterval(e.timers.buffering),e.timers.buffering=setInterval(function(){e.media.buffered=n.getVideoLoadedFraction(),(null===e.media.lastBuffered||e.media.lastBuffered<e.media.buffered)&&o.call(e,e.media,"progress"),e.media.lastBuffered=e.media.buffered,1===e.media.buffered&&(clearInterval(e.timers.buffering),o.call(e,e.media,"canplaythrough"))},200),setTimeout(function(){return pe.build.call(e)},50)},onStateChange:function(t){var n,a=t.target;switch(clearInterval(e.timers.playing),e.media.seeking&&[1,2].includes(t.data)&&(e.media.seeking=!1,o.call(e,e.media,"seeked")),t.data){case-1:o.call(e,e.media,"timeupdate"),e.media.buffered=a.getVideoLoadedFraction(),o.call(e,e.media,"progress");break;case 0:ke.call(e,!1),e.media.loop?(a.stopVideo(),a.playVideo()):o.call(e,e.media,"ended");break;case 1:e.media.paused&&!e.embed.hasPlayed?e.media.pause():(ke.call(e,!0),o.call(e,e.media,"playing"),e.timers.playing=setInterval(function(){o.call(e,e.media,"timeupdate")},50),e.media.duration!==a.getDuration()&&(e.media.duration=a.getDuration(),o.call(e,e.media,"durationchange")),Z.setQualityMenu.call(e,(n=a.getAvailableQualityLevels(),i.empty(n)?n:W(n.map(function(e){return be(e)})))));break;case 2:e.muted||e.embed.unMute(),ke.call(e,!1)}o.call(e,e.elements.container,"statechange",!1,{code:t.data})}}})}}},Ae={setup:function(){this.media?(T(this.elements.container,this.config.classNames.type.replace("{0}",this.type),!0),T(this.elements.container,this.config.classNames.provider.replace("{0}",this.provider),!0),this.isEmbed&&T(this.elements.container,this.config.classNames.type.replace("{0}","video"),!0),this.isVideo&&(this.elements.wrapper=f("div",{class:this.config.classNames.video}),h(this.media,this.elements.wrapper),this.elements.poster=f("div",{class:this.config.classNames.poster}),this.elements.wrapper.appendChild(this.elements.poster)),this.isHTML5?j.extend.call(this):this.isYouTube?Te.setup.call(this):this.isVimeo&&ve.setup.call(this)):this.debug.warn("No media element found!")}},Ee=function(){function e(t){var i=this;c(this,e),this.player=t,this.publisherId=t.config.ads.publisherId,this.playing=!1,this.initialized=!1,this.elements={container:null,displayContainer:null},this.manager=null,this.loader=null,this.cuePoints=null,this.events={},this.safetyTimer=null,this.countdownTimer=null,this.managerPromise=new Promise(function(e,t){i.on("loaded",e),i.on("error",t)}),this.load()}return u(e,[{key:"load",value:function(){var e=this;this.enabled&&(i.object(window.google)&&i.object(window.google.ima)?this.ready():ge(this.player.config.urls.googleIMA.sdk).then(function(){e.ready()}).catch(function(){e.trigger("error",new Error("Google IMA SDK failed to load"))}))}},{key:"ready",value:function(){var e=this;this.startSafetyTimer(12e3,"ready()"),this.managerPromise.then(function(){e.clearSafetyTimer("onAdsManagerLoaded()")}),this.listeners(),this.setupIMA()}},{key:"setupIMA",value:function(){this.elements.container=f("div",{class:this.player.config.classNames.ads}),this.player.elements.container.appendChild(this.elements.container),google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED),google.ima.settings.setLocale(this.player.config.ads.language),this.elements.displayContainer=new google.ima.AdDisplayContainer(this.elements.container),this.requestAds()}},{key:"requestAds",value:function(){var e=this,t=this.player.elements.container;try{this.loader=new google.ima.AdsLoader(this.elements.displayContainer),this.loader.addEventListener(google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,function(t){return e.onAdsManagerLoaded(t)},!1),this.loader.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,function(t){return e.onAdError(t)},!1);var i=new google.ima.AdsRequest;i.adTagUrl=this.tagUrl,i.linearAdSlotWidth=t.offsetWidth,i.linearAdSlotHeight=t.offsetHeight,i.nonLinearAdSlotWidth=t.offsetWidth,i.nonLinearAdSlotHeight=t.offsetHeight,i.forceNonLinearFullSlot=!1,i.setAdWillPlayMuted(!this.player.muted),this.loader.requestAds(i)}catch(e){this.onAdError(e)}}},{key:"pollCountdown",value:function(){var e=this;if(!(arguments.length>0&&void 0!==arguments[0]&&arguments[0]))return clearInterval(this.countdownTimer),void this.elements.container.removeAttribute("data-badge-text");this.countdownTimer=setInterval(function(){var t=G(Math.max(e.manager.getRemainingTime(),0)),i=z("advertisement",e.player.config)+" - "+t;e.elements.container.setAttribute("data-badge-text",i)},100)}},{key:"onAdsManagerLoaded",value:function(e){var t=this,n=new google.ima.AdsRenderingSettings;n.restoreCustomPlaybackStateOnAdBreakComplete=!0,n.enablePreloading=!0,this.manager=e.getAdsManager(this.player,n),this.cuePoints=this.manager.getCuePoints(),i.empty(this.cuePoints)||this.cuePoints.forEach(function(e){if(0!==e&&-1!==e&&e<t.player.duration){var n=t.player.elements.progress;if(i.element(n)){var a=100/t.player.duration*e,s=f("span",{class:t.player.config.classNames.cues});s.style.left=a.toString()+"%",n.appendChild(s)}}}),this.manager.setVolume(this.player.volume),this.manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,function(e){return t.onAdError(e)}),Object.keys(google.ima.AdEvent.Type).forEach(function(e){t.manager.addEventListener(google.ima.AdEvent.Type[e],function(e){return t.onAdEvent(e)})}),this.trigger("loaded")}},{key:"onAdEvent",value:function(e){var t=this,i=this.player.elements.container,n=e.getAd(),a=function(e){var i="ads"+e.replace(/_/g,"").toLowerCase();o.call(t.player,t.player.media,i)};switch(e.type){case google.ima.AdEvent.Type.LOADED:this.trigger("loaded"),a(e.type),this.pollCountdown(!0),n.isLinear()||(n.width=i.offsetWidth,n.height=i.offsetHeight);break;case google.ima.AdEvent.Type.ALL_ADS_COMPLETED:a(e.type),this.loadAds();break;case google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED:a(e.type),this.pauseContent();break;case google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED:a(e.type),this.pollCountdown(),this.resumeContent();break;case google.ima.AdEvent.Type.STARTED:case google.ima.AdEvent.Type.MIDPOINT:case google.ima.AdEvent.Type.COMPLETE:case google.ima.AdEvent.Type.IMPRESSION:case google.ima.AdEvent.Type.CLICK:a(e.type)}}},{key:"onAdError",value:function(e){this.cancel(),this.player.debug.warn("Ads error",e)}},{key:"listeners",value:function(){var e=this,t=this.player.elements.container,n=void 0;this.player.on("ended",function(){e.loader.contentComplete()}),this.player.on("seeking",function(){return n=e.player.currentTime}),this.player.on("seeked",function(){var t=e.player.currentTime;i.empty(e.cuePoints)||e.cuePoints.forEach(function(i,a){n<i&&i<t&&(e.manager.discardAdBreak(),e.cuePoints.splice(a,1))})}),window.addEventListener("resize",function(){e.manager&&e.manager.resize(t.offsetWidth,t.offsetHeight,google.ima.ViewMode.NORMAL)})}},{key:"play",value:function(){var e=this,t=this.player.elements.container;this.managerPromise||this.resumeContent(),this.managerPromise.then(function(){e.elements.displayContainer.initialize();try{e.initialized||(e.manager.init(t.offsetWidth,t.offsetHeight,google.ima.ViewMode.NORMAL),e.manager.start()),e.initialized=!0}catch(t){e.onAdError(t)}}).catch(function(){})}},{key:"resumeContent",value:function(){this.elements.container.style.zIndex="",this.playing=!1,this.player.currentTime<this.player.duration&&this.player.play()}},{key:"pauseContent",value:function(){this.elements.container.style.zIndex=3,this.playing=!0,this.player.pause()}},{key:"cancel",value:function(){this.initialized&&this.resumeContent(),this.trigger("error"),this.loadAds()}},{key:"loadAds",value:function(){var e=this;this.managerPromise.then(function(){e.manager&&e.manager.destroy(),e.managerPromise=new Promise(function(t){e.on("loaded",t),e.player.debug.log(e.manager)}),e.requestAds()}).catch(function(){})}},{key:"trigger",value:function(e){for(var t=this,n=arguments.length,a=Array(n>1?n-1:0),s=1;s<n;s++)a[s-1]=arguments[s];var r=this.events[e];i.array(r)&&r.forEach(function(e){i.function(e)&&e.apply(t,a)})}},{key:"on",value:function(e,t){return i.array(this.events[e])||(this.events[e]=[]),this.events[e].push(t),this}},{key:"startSafetyTimer",value:function(e,t){var i=this;this.player.debug.log("Safety timer invoked from: "+t),this.safetyTimer=setTimeout(function(){i.cancel(),i.clearSafetyTimer("startSafetyTimer()")},e)}},{key:"clearSafetyTimer",value:function(e){i.nullOrUndefined(this.safetyTimer)||(this.player.debug.log("Safety timer cleared from: "+e),clearTimeout(this.safetyTimer),this.safetyTimer=null)}},{key:"enabled",get:function(){return this.player.isVideo&&this.player.config.ads.enabled&&!i.empty(this.publisherId)}},{key:"tagUrl",get:function(){return"https://go.aniview.com/api/adserver6/vast/?"+te({AV_PUBLISHERID:"58c25bb0073ef448b1087ad6",AV_CHANNELID:"5a0458dc28a06145e4519d21",AV_URL:location.hostname,cb:Date.now(),AV_WIDTH:640,AV_HEIGHT:480,AV_CDIM2:this.publisherId})}}]),e}(),Ce={insertElements:function(e,t){var n=this;i.string(t)?g(e,this.media,{src:t}):i.array(t)&&t.forEach(function(t){g(e,n.media,t)})},change:function(e){var t=this;R(e,"sources.length")?(j.cancelRequests.call(this),this.destroy.call(this,function(){t.options.quality=[],y(t.media),t.media=null,i.element(t.elements.container)&&t.elements.container.removeAttribute("class");var n=e.sources,a=e.type,s=p(n,1)[0],r=s.provider,l=void 0===r?ae.html5:r,o=s.src,c="html5"===l?a:"div",u="html5"===l?{}:{src:o};Object.assign(t,{provider:l,type:a,supported:O.check(a,l,t.config.playsinline),media:f(c,u)}),t.elements.container.appendChild(t.media),i.boolean(e.autoplay)&&(t.config.autoplay=e.autoplay),t.isHTML5&&(t.config.crossorigin&&t.media.setAttribute("crossorigin",""),t.config.autoplay&&t.media.setAttribute("autoplay",""),i.empty(e.poster)||(t.poster=e.poster),t.config.loop.active&&t.media.setAttribute("loop",""),t.config.muted&&t.media.setAttribute("muted",""),t.config.playsinline&&t.media.setAttribute("playsinline","")),pe.addStyleHook.call(t),t.isHTML5&&Ce.insertElements.call(t,"source",n),t.config.title=e.title,Ae.setup.call(t),t.isHTML5&&("tracks"in e&&Ce.insertElements.call(t,"track",e.tracks),t.media.load()),(t.isHTML5||t.isEmbed&&!t.supported.ui)&&pe.build.call(t),t.fullscreen.update()},!0)):this.debug.warn("Invalid source format")}},Pe=function(){function e(t,n){var a=this;if(c(this,e),this.timers={},this.ready=!1,this.loading=!1,this.failed=!1,this.touch=O.touch,this.media=t,i.string(this.media)&&(this.media=document.querySelectorAll(this.media)),(window.jQuery&&this.media instanceof jQuery||i.nodeList(this.media)||i.array(this.media))&&(this.media=this.media[0]),this.config=V({},ne,e.defaults,n||{},function(){try{return JSON.parse(a.media.getAttribute("data-plyr-config"))}catch(e){return{}}}()),this.elements={container:null,captions:null,buttons:{},display:{},progress:{},inputs:{},settings:{popup:null,menu:null,panels:{},buttons:{}}},this.captions={active:null,currentTrack:-1,meta:new WeakMap},this.fullscreen={active:!1},this.options={speed:[],quality:[]},this.debug=new le(this.config.debug),this.debug.log("Config",this.config),this.debug.log("Support",O),!i.nullOrUndefined(this.media)&&i.element(this.media))if(this.media.plyr)this.debug.warn("Target already setup");else if(this.config.enabled)if(O.check().api){var r=this.media.cloneNode(!0);r.autoplay=!1,this.elements.original=r;var l=this.media.tagName.toLowerCase(),o=null,u=null;switch(l){case"div":if(o=this.media.querySelector("iframe"),i.element(o)){if(u=ee(o.getAttribute("src")),this.provider=function(e){return/^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.?be)\/.+$/.test(e)?ae.youtube:/^https?:\/\/player.vimeo.com\/video\/\d{0,9}(?=\b|\/)/.test(e)?ae.vimeo:null}(u.toString()),this.elements.container=this.media,this.media=o,this.elements.container.className="",u.searchParams.length){var d=["1","true"];d.includes(u.searchParams.get("autoplay"))&&(this.config.autoplay=!0),d.includes(u.searchParams.get("loop"))&&(this.config.loop.active=!0),this.isYouTube?this.config.playsinline=d.includes(u.searchParams.get("playsinline")):this.config.playsinline=!0}}else this.provider=this.media.getAttribute(this.config.attributes.embed.provider),this.media.removeAttribute(this.config.attributes.embed.provider);if(i.empty(this.provider)||!Object.keys(ae).includes(this.provider))return void this.debug.error("Setup failed: Invalid provider");this.type=se.video;break;case"video":case"audio":this.type=l,this.provider=ae.html5,this.media.hasAttribute("crossorigin")&&(this.config.crossorigin=!0),this.media.hasAttribute("autoplay")&&(this.config.autoplay=!0),this.media.hasAttribute("playsinline")&&(this.config.playsinline=!0),this.media.hasAttribute("muted")&&(this.config.muted=!0),this.media.hasAttribute("loop")&&(this.config.loop.active=!0);break;default:return void this.debug.error("Setup failed: unsupported type")}this.supported=O.check(this.type,this.provider,this.config.playsinline),this.supported.api?(this.eventListeners=[],this.listeners=new he(this),this.storage=new K(this),this.media.plyr=this,i.element(this.elements.container)||(this.elements.container=f("div"),h(this.media,this.elements.container)),pe.addStyleHook.call(this),Ae.setup.call(this),this.config.debug&&s.call(this,this.elements.container,this.config.events.join(" "),function(e){a.debug.log("event: "+e.type)}),(this.isHTML5||this.isEmbed&&!this.supported.ui)&&pe.build.call(this),this.listeners.container(),this.listeners.global(),this.fullscreen=new ue(this),this.ads=new Ee(this),this.config.autoplay&&this.play()):this.debug.error("Setup failed: no support")}else this.debug.error("Setup failed: no support");else this.debug.error("Setup failed: disabled by config");else this.debug.error("Setup failed: no suitable element passed")}return u(e,[{key:"play",value:function(){return i.function(this.media.play)?this.media.play():null}},{key:"pause",value:function(){this.playing&&i.function(this.media.pause)&&this.media.pause()}},{key:"togglePlay",value:function(e){(i.boolean(e)?e:!this.playing)?this.play():this.pause()}},{key:"stop",value:function(){this.isHTML5?(this.pause(),this.restart()):i.function(this.media.stop)&&this.media.stop()}},{key:"restart",value:function(){this.currentTime=0}},{key:"rewind",value:function(e){this.currentTime=this.currentTime-(i.number(e)?e:this.config.seekTime)}},{key:"forward",value:function(e){this.currentTime=this.currentTime+(i.number(e)?e:this.config.seekTime)}},{key:"increaseVolume",value:function(e){var t=this.media.muted?0:this.volume;this.volume=t+(i.number(e)?e:1)}},{key:"decreaseVolume",value:function(e){var t=this.media.muted?0:this.volume;this.volume=t-(i.number(e)?e:1)}},{key:"toggleCaptions",value:function(e){ie.toggle.call(this,e,!1)}},{key:"airplay",value:function(){O.airplay&&this.media.webkitShowPlaybackTargetPicker()}},{key:"toggleControls",value:function(e){if(this.supported.ui&&!this.isAudio){var t=A(this.elements.container,this.config.classNames.hideControls),n=void 0===e?void 0:!e,a=T(this.elements.container,this.config.classNames.hideControls,n);if(a&&this.config.controls.includes("settings")&&!i.empty(this.config.settings)&&Z.toggleMenu.call(this,!1),a!==t){var s=a?"controlshidden":"controlsshown";o.call(this,this.media,s)}return!a}return!1}},{key:"on",value:function(e,t){s.call(this,this.elements.container,e,t)}},{key:"once",value:function(e,t){l.call(this,this.elements.container,e,t)}},{key:"off",value:function(e,t){r(this.elements.container,e,t)}},{key:"destroy",value:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(this.ready){var a=function(){document.body.style.overflow="",t.embed=null,n?(Object.keys(t.elements).length&&(y(t.elements.buttons.play),y(t.elements.captions),y(t.elements.controls),y(t.elements.wrapper),t.elements.buttons.play=null,t.elements.captions=null,t.elements.controls=null,t.elements.wrapper=null),i.function(e)&&e()):(function(){this&&this.eventListeners&&(this.eventListeners.forEach(function(e){var t=e.element,i=e.type,n=e.callback,a=e.options;t.removeEventListener(i,n,a)}),this.eventListeners=[])}.call(t),b(t.elements.original,t.elements.container),o.call(t,t.elements.original,"destroyed",!0),i.function(e)&&e.call(t.elements.original),t.ready=!1,setTimeout(function(){t.elements=null,t.media=null},200))};this.stop(),this.isHTML5?(clearTimeout(this.timers.loading),pe.toggleNativeControls.call(this,!0),a()):this.isYouTube?(clearInterval(this.timers.buffering),clearInterval(this.timers.playing),null!==this.embed&&i.function(this.embed.destroy)&&this.embed.destroy(),a()):this.isVimeo&&(null!==this.embed&&this.embed.unload().then(a),setTimeout(a,200))}}},{key:"supports",value:function(e){return O.mime.call(this,e)}},{key:"isHTML5",get:function(){return Boolean(this.provider===ae.html5)}},{key:"isEmbed",get:function(){return Boolean(this.isYouTube||this.isVimeo)}},{key:"isYouTube",get:function(){return Boolean(this.provider===ae.youtube)}},{key:"isVimeo",get:function(){return Boolean(this.provider===ae.vimeo)}},{key:"isVideo",get:function(){return Boolean(this.type===se.video)}},{key:"isAudio",get:function(){return Boolean(this.type===se.audio)}},{key:"playing",get:function(){return Boolean(this.ready&&!this.paused&&!this.ended)}},{key:"paused",get:function(){return Boolean(this.media.paused)}},{key:"stopped",get:function(){return Boolean(this.paused&&0===this.currentTime)}},{key:"ended",get:function(){return Boolean(this.media.ended)}},{key:"currentTime",set:function(e){if(this.duration){var t=i.number(e)&&e>0;this.media.currentTime=t?Math.min(e,this.duration):0,this.debug.log("Seeking to "+this.currentTime+" seconds")}},get:function(){return Number(this.media.currentTime)}},{key:"buffered",get:function(){var e=this.media.buffered;return i.number(e)?e:e&&e.length&&this.duration>0?e.end(0)/this.duration:0}},{key:"seeking",get:function(){return Boolean(this.media.seeking)}},{key:"duration",get:function(){var e=parseFloat(this.config.duration),t=(this.media||{}).duration||0;return e||t}},{key:"volume",set:function(e){var t=e;i.string(t)&&(t=Number(t)),i.number(t)||(t=this.storage.get("volume")),i.number(t)||(t=this.config.volume),t>1&&(t=1),t<0&&(t=0),this.config.volume=t,this.media.volume=t,!i.empty(e)&&this.muted&&t>0&&(this.muted=!1)},get:function(){return Number(this.media.volume)}},{key:"muted",set:function(e){var t=e;i.boolean(t)||(t=this.storage.get("muted")),i.boolean(t)||(t=this.config.muted),this.config.muted=t,this.media.muted=t},get:function(){return Boolean(this.media.muted)}},{key:"hasAudio",get:function(){return!this.isHTML5||(!!this.isAudio||(Boolean(this.media.mozHasAudio)||Boolean(this.media.webkitAudioDecodedByteCount)||Boolean(this.media.audioTracks&&this.media.audioTracks.length)))}},{key:"speed",set:function(e){var t=null;i.number(e)&&(t=e),i.number(t)||(t=this.storage.get("speed")),i.number(t)||(t=this.config.speed.selected),t<.1&&(t=.1),t>2&&(t=2),this.config.speed.options.includes(t)?(this.config.speed.selected=t,this.media.playbackRate=t):this.debug.warn("Unsupported speed ("+t+")")},get:function(){return Number(this.media.playbackRate)}},{key:"quality",set:function(e){var t=this.config.quality,n=this.options.quality;if(n.length){var a=[!i.empty(e)&&Number(e),this.storage.get("quality"),t.selected,t.default].find(i.number);if(!n.includes(a)){var s=function(e,t){return i.array(e)&&e.length?e.reduce(function(e,i){return Math.abs(i-t)<Math.abs(e-t)?i:e}):null}(n,a);this.debug.warn("Unsupported quality option: "+a+", using "+s+" instead"),a=s}o.call(this,this.media,"qualityrequested",!1,{quality:a}),t.selected=a,this.media.quality=a}},get:function(){return this.media.quality}},{key:"loop",set:function(e){var t=i.boolean(e)?e:this.config.loop.active;this.config.loop.active=t,this.media.loop=t},get:function(){return Boolean(this.media.loop)}},{key:"source",set:function(e){Ce.change.call(this,e)},get:function(){return this.media.currentSrc}},{key:"poster",set:function(e){this.isVideo?pe.setPoster.call(this,e,!1).catch(function(){}):this.debug.warn("Poster can only be set for video")},get:function(){return this.isVideo?this.media.getAttribute("poster"):null}},{key:"autoplay",set:function(e){var t=i.boolean(e)?e:this.config.autoplay;this.config.autoplay=t},get:function(){return Boolean(this.config.autoplay)}},{key:"currentTrack",set:function(e){ie.set.call(this,e,!1)},get:function(){var e=this.captions,t=e.toggled,i=e.currentTrack;return t?i:-1}},{key:"language",set:function(e){ie.setLanguage.call(this,e,!1)},get:function(){return(ie.getCurrentTrack.call(this)||{}).language}},{key:"pip",set:function(e){var t="picture-in-picture",n="inline";if(O.pip){var a=i.boolean(e)?e:this.pip===n;this.media.webkitSetPresentationMode(a?t:n)}},get:function(){return O.pip?this.media.webkitPresentationMode:null}}],[{key:"supported",value:function(e,t,i){return O.check(e,t,i)}},{key:"loadSprite",value:function(e,t){return Q(e,t)}},{key:"setup",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},a=null;return i.string(t)?a=Array.from(document.querySelectorAll(t)):i.nodeList(t)?a=Array.from(t):i.array(t)&&(a=t.filter(i.element)),i.empty(a)?null:a.map(function(t){return new e(t,n)})}}]),e}();return Pe.defaults=(we=ne,JSON.parse(JSON.stringify(we))),Pe}); +"object"==typeof navigator&&function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define("Plyr",t):e.Plyr=t()}(this,function(){"use strict";var e=function(e){return null!=e?e.constructor:null},t=function(e,t){return Boolean(e&&t&&e instanceof t)},i={object:function(t){return e(t)===Object},number:function(t){return e(t)===Number&&!Number.isNaN(t)},string:function(t){return e(t)===String},boolean:function(t){return e(t)===Boolean},function:function(t){return e(t)===Function},array:function(e){return!i.nullOrUndefined(e)&&Array.isArray(e)},weakMap:function(e){return t(e,WeakMap)},nodeList:function(e){return t(e,NodeList)},element:function(e){return t(e,Element)},textNode:function(t){return e(t)===Text},event:function(e){return t(e,Event)},cue:function(e){return t(e,window.TextTrackCue)||t(e,window.VTTCue)},track:function(e){return t(e,TextTrack)||!i.nullOrUndefined(e)&&i.string(e.kind)},url:function(e){return!i.nullOrUndefined(e)&&/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-/]))?/.test(e)},nullOrUndefined:function(e){return null==e},empty:function(e){return i.nullOrUndefined(e)||(i.string(e)||i.array(e)||i.nodeList(e))&&!e.length||i.object(e)&&!Object.keys(e).length}},n=function(){var e=!1;try{var t=Object.defineProperty({},"passive",{get:function(){return e=!0,null}});window.addEventListener("test",null,t),window.removeEventListener("test",null,t)}catch(e){}return e}();function a(e,t,a){var s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],r=this,l=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],o=arguments.length>5&&void 0!==arguments[5]&&arguments[5];if(e&&"addEventListener"in e&&!i.empty(t)&&i.function(a)){var c=t.split(" "),u=o;n&&(u={passive:l,capture:o}),c.forEach(function(t){r&&r.eventListeners&&s&&r.eventListeners.push({element:e,type:t,callback:a,options:u}),e[s?"addEventListener":"removeEventListener"](t,a,u)})}}function s(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=arguments[2],n=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],s=arguments.length>4&&void 0!==arguments[4]&&arguments[4];a.call(this,e,t,i,!0,n,s)}function r(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=arguments[2],n=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],s=arguments.length>4&&void 0!==arguments[4]&&arguments[4];a.call(this,e,t,i,!1,n,s)}function l(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=arguments[2],n=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],s=arguments.length>4&&void 0!==arguments[4]&&arguments[4];a.call(this,e,t,function a(){r(e,t,a,n,s);for(var l=arguments.length,o=Array(l),c=0;c<l;c++)o[c]=arguments[c];i.apply(this,o)},!0,n,s)}function o(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};if(i.element(e)&&!i.empty(t)){var s=new CustomEvent(t,{bubbles:n,detail:Object.assign({},a,{plyr:this})});e.dispatchEvent(s)}}var c=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},u=function(){function e(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,i,n){return i&&e(t.prototype,i),n&&e(t,n),t}}(),d=function(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e},p=function(){return function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var i=[],n=!0,a=!1,s=void 0;try{for(var r,l=e[Symbol.iterator]();!(n=(r=l.next()).done)&&(i.push(r.value),!t||i.length!==t);n=!0);}catch(e){a=!0,s=e}finally{try{!n&&l.return&&l.return()}finally{if(a)throw s}}return i}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();function h(e,t){var i=e.length?e:[e];Array.from(i).reverse().forEach(function(e,i){var n=i>0?t.cloneNode(!0):t,a=e.parentNode,s=e.nextSibling;n.appendChild(e),s?a.insertBefore(n,s):a.appendChild(n)})}function m(e,t){i.element(e)&&!i.empty(t)&&Object.entries(t).filter(function(e){var t=p(e,2)[1];return!i.nullOrUndefined(t)}).forEach(function(t){var i=p(t,2),n=i[0],a=i[1];return e.setAttribute(n,a)})}function f(e,t,n){var a=document.createElement(e);return i.object(t)&&m(a,t),i.string(n)&&(a.innerText=n),a}function g(e,t,n,a){i.element(t)&&t.appendChild(f(e,n,a))}function y(e){i.nodeList(e)||i.array(e)?Array.from(e).forEach(y):i.element(e)&&i.element(e.parentNode)&&e.parentNode.removeChild(e)}function v(e){if(i.element(e))for(var t=e.childNodes.length;t>0;)e.removeChild(e.lastChild),t-=1}function b(e,t){return i.element(t)&&i.element(t.parentNode)&&i.element(e)?(t.parentNode.replaceChild(e,t),e):null}function k(e,t){if(!i.string(e)||i.empty(e))return{};var n={},a=t;return e.split(",").forEach(function(e){var t=e.trim(),s=t.replace(".",""),r=t.replace(/[[\]]/g,"").split("="),l=r[0],o=r.length>1?r[1].replace(/["']/g,""):"";switch(t.charAt(0)){case".":i.object(a)&&i.string(a.class)&&(a.class+=" "+s),n.class=s;break;case"#":n.id=t.replace("#","");break;case"[":n[l]=o}}),n}function w(e,t){if(i.element(e)){var n=t;i.boolean(n)||(n=!e.hasAttribute("hidden")),n?e.setAttribute("hidden",""):e.removeAttribute("hidden")}}function T(e,t,n){if(i.element(e)){var a="toggle";return void 0!==n&&(a=n?"add":"remove"),e.classList[a](t),e.classList.contains(t)}return null}function A(e,t){return i.element(e)&&e.classList.contains(t)}function E(e,t){var i={Element:Element};return(i.matches||i.webkitMatchesSelector||i.mozMatchesSelector||i.msMatchesSelector||function(){return Array.from(document.querySelectorAll(t)).includes(this)}).call(e,t)}function C(e){return this.elements.container.querySelectorAll(e)}function P(e){return this.elements.container.querySelector(e)}function S(){var e=document.activeElement;return e=e&&e!==document.body?document.querySelector(":focus"):null}var N,L,M,x=(N=document.createElement("span"),L={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},M=Object.keys(L).find(function(e){return void 0!==N.style[e]}),!!i.string(M)&&L[M]);var _,q={isIE:!!document.documentMode,isWebkit:"WebkitAppearance"in document.documentElement.style&&!/Edge/.test(navigator.userAgent),isIPhone:/(iPhone|iPod)/gi.test(navigator.platform),isIos:/(iPad|iPhone|iPod)/gi.test(navigator.platform)},I={"audio/ogg":"vorbis","audio/wav":"1","video/webm":"vp8, vorbis","video/mp4":"avc1.42E01E, mp4a.40.2","video/ogg":"theora"},O={audio:"canPlayType"in document.createElement("audio"),video:"canPlayType"in document.createElement("video"),check:function(e,t,i){var n=q.isIPhone&&i&&O.playsinline,a=O[e]||"html5"!==t;return{api:a,ui:a&&O.rangeInput&&("video"!==e||!q.isIPhone||n)}},pip:!q.isIPhone&&i.function(f("video").webkitSetPresentationMode),airplay:i.function(window.WebKitPlaybackTargetAvailabilityEvent),playsinline:"playsInline"in document.createElement("video"),mime:function(e){var t=e.split("/"),i=p(t,1)[0];if(!this.isHTML5||i!==this.type)return!1;var n=void 0;e&&e.includes("codecs=")?n=e:"audio/mpeg"===e?n="audio/mpeg;":e in I&&(n=e+'; codecs="'+I[e]+'"');try{return Boolean(n&&this.media.canPlayType(n).replace(/no/,""))}catch(e){return!1}},textTracks:"textTracks"in document.createElement("video"),rangeInput:(_=document.createElement("input"),_.type="range","range"===_.type),touch:"ontouchstart"in document.documentElement,transitions:!1!==x,reducedMotion:"matchMedia"in window&&window.matchMedia("(prefers-reduced-motion)").matches},j={getSources:function(){var e=this;return this.isHTML5?Array.from(this.media.querySelectorAll("source")).filter(function(t){return O.mime.call(e,t.getAttribute("type"))}):[]},getQualityOptions:function(){return j.getSources.call(this).map(function(e){return Number(e.getAttribute("size"))}).filter(Boolean)},extend:function(){if(this.isHTML5){var e=this;Object.defineProperty(e.media,"quality",{get:function(){var t=j.getSources.call(e).filter(function(t){return t.getAttribute("src")===e.source}),i=p(t,1)[0];return i&&Number(i.getAttribute("size"))},set:function(t){var i=j.getSources.call(e).find(function(e){return Number(e.getAttribute("size"))===t});if(i){var n=e.currentTime,a=e.playing;e.media.src=i.getAttribute("src");e.once("loadedmetadata",function(){e.currentTime=n}),e.media.load(),a&&e.play(),o.call(e,e.media,"qualitychange",!1,{quality:t})}}})}},cancelRequests:function(){this.isHTML5&&(y(j.getSources.call(this)),this.media.setAttribute("src",this.config.blankVideo),this.media.load(),this.debug.log("Cancelled network requests"))}};function R(e,t){return t.split(".").reduce(function(e,t){return e&&e[t]},e)}function V(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length,n=Array(t>1?t-1:0),a=1;a<t;a++)n[a-1]=arguments[a];if(!n.length)return e;var s=n.shift();return i.object(s)?(Object.keys(s).forEach(function(t){i.object(s[t])?(Object.keys(e).includes(t)||Object.assign(e,d({},t,{})),V(e[t],s[t])):Object.assign(e,d({},t,s[t]))}),V.apply(void 0,[e].concat(n))):e}function B(e){for(var t=arguments.length,n=Array(t>1?t-1:0),a=1;a<t;a++)n[a-1]=arguments[a];return i.empty(e)?e:e.toString().replace(/{(\d+)}/g,function(e,t){return n[t].toString()})}function H(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return e.replace(new RegExp(t.toString().replace(/([.*+?^=!:${}()|[\]/\\])/g,"\\$1"),"g"),i.toString())}function D(){return(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"").toString().replace(/\w\S*/g,function(e){return e.charAt(0).toUpperCase()+e.substr(1).toLowerCase()})}function F(){var e=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"").toString();return(e=function(){var e=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"").toString();return e=H(e,"-"," "),e=H(e,"_"," "),H(e=D(e)," ","")}(e)).charAt(0).toLowerCase()+e.slice(1)}function U(e){var t=document.createElement("div");return t.appendChild(e),t.innerHTML}var z=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(i.empty(e)||i.empty(t))return"";var n=R(t.i18n,e);if(i.empty(n))return"";var a={"{seektime}":t.seekTime,"{title}":t.title};return Object.entries(a).forEach(function(e){var t=p(e,2),i=t[0],a=t[1];n=H(n,i,a)}),n};function W(e){return i.array(e)?e.filter(function(t,i){return e.indexOf(t)===i}):e}var K=function(){function e(t){c(this,e),this.enabled=t.config.storage.enabled,this.key=t.config.storage.key}return u(e,[{key:"get",value:function(t){if(!e.supported||!this.enabled)return null;var n=window.localStorage.getItem(this.key);if(i.empty(n))return null;var a=JSON.parse(n);return i.string(t)&&t.length?a[t]:a}},{key:"set",value:function(t){if(e.supported&&this.enabled&&i.object(t)){var n=this.get();i.empty(n)&&(n={}),V(n,t),window.localStorage.setItem(this.key,JSON.stringify(n))}}}],[{key:"supported",get:function(){try{if(!("localStorage"in window))return!1;return window.localStorage.setItem("___test","___test"),window.localStorage.removeItem("___test"),!0}catch(e){return!1}}}]),e}();function Y(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"text";return new Promise(function(i,n){try{var a=new XMLHttpRequest;if(!("withCredentials"in a))return;a.addEventListener("load",function(){if("text"===t)try{i(JSON.parse(a.responseText))}catch(e){i(a.responseText)}else i(a.response)}),a.addEventListener("error",function(){throw new Error(a.status)}),a.open("GET",e,!0),a.responseType=t,a.send()}catch(e){n(e)}})}function Q(e,t){if(i.string(e)){var n=i.string(t),a=function(){return null!==document.getElementById(t)},s=function(e,t){e.innerHTML=t,n&&a()||document.body.insertAdjacentElement("afterbegin",e)};if(!n||!a()){var r=K.supported,l=document.createElement("div");if(l.setAttribute("hidden",""),n&&l.setAttribute("id",t),r){var o=window.localStorage.getItem("cache-"+t);if(null!==o){var c=JSON.parse(o);s(l,c.content)}}Y(e).then(function(e){i.empty(e)||(r&&window.localStorage.setItem("cache-"+t,JSON.stringify({content:e})),s(l,e))}).catch(function(){})}}}var J=function(e){return parseInt(e/60/60%60,10)},$=function(e){return parseInt(e/60%60,10)},X=function(e){return parseInt(e%60,10)};function G(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(!i.number(e))return G(null,t,n);var a=function(e){return("0"+e).slice(-2)},s=J(e),r=$(e),l=X(e);return t||s>0?s+=":":s="",(n&&e>0?"-":"")+s+a(r)+":"+a(l)}var Z={getIconUrl:function(){var e=new URL(this.config.iconUrl,window.location).host!==window.location.host||q.isIE&&!window.svg4everybody;return{url:this.config.iconUrl,cors:e}},findElements:function(){try{return this.elements.controls=P.call(this,this.config.selectors.controls.wrapper),this.elements.buttons={play:C.call(this,this.config.selectors.buttons.play),pause:P.call(this,this.config.selectors.buttons.pause),restart:P.call(this,this.config.selectors.buttons.restart),rewind:P.call(this,this.config.selectors.buttons.rewind),fastForward:P.call(this,this.config.selectors.buttons.fastForward),mute:P.call(this,this.config.selectors.buttons.mute),pip:P.call(this,this.config.selectors.buttons.pip),airplay:P.call(this,this.config.selectors.buttons.airplay),settings:P.call(this,this.config.selectors.buttons.settings),captions:P.call(this,this.config.selectors.buttons.captions),fullscreen:P.call(this,this.config.selectors.buttons.fullscreen)},this.elements.progress=P.call(this,this.config.selectors.progress),this.elements.inputs={seek:P.call(this,this.config.selectors.inputs.seek),volume:P.call(this,this.config.selectors.inputs.volume)},this.elements.display={buffer:P.call(this,this.config.selectors.display.buffer),currentTime:P.call(this,this.config.selectors.display.currentTime),duration:P.call(this,this.config.selectors.display.duration)},i.element(this.elements.progress)&&(this.elements.display.seekTooltip=this.elements.progress.querySelector("."+this.config.classNames.tooltip)),!0}catch(e){return this.debug.warn("It looks like there is a problem with your custom controls HTML",e),this.toggleNativeControls(!0),!1}},createIcon:function(e,t){var i=Z.getIconUrl.call(this),n=(i.cors?"":i.url)+"#"+this.config.iconPrefix,a=document.createElementNS("http://www.w3.org/2000/svg","svg");m(a,V(t,{role:"presentation",focusable:"false"}));var s=document.createElementNS("http://www.w3.org/2000/svg","use"),r=n+"-"+e;return"href"in s?s.setAttributeNS("http://www.w3.org/1999/xlink","href",r):s.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",r),a.appendChild(s),a},createLabel:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i={pip:"PIP",airplay:"AirPlay"}[e]||z(e,this.config);return f("span",Object.assign({},t,{class:[t.class,this.config.classNames.hidden].filter(Boolean).join(" ")}),i)},createBadge:function(e){if(i.empty(e))return null;var t=f("span",{class:this.config.classNames.menu.value});return t.appendChild(f("span",{class:this.config.classNames.menu.badge},e)),t},createButton:function(e,t){var n=f("button"),a=Object.assign({},t),s=F(e),r=!1,l=void 0,o=void 0,c=void 0,u=void 0;switch("type"in a||(a.type="button"),"class"in a?a.class.includes(this.config.classNames.control)&&(a.class+=" "+this.config.classNames.control):a.class=this.config.classNames.control,e){case"play":r=!0,l="play",c="pause",o="play",u="pause";break;case"mute":r=!0,l="mute",c="unmute",o="volume",u="muted";break;case"captions":r=!0,l="enableCaptions",c="disableCaptions",o="captions-off",u="captions-on";break;case"fullscreen":r=!0,l="enterFullscreen",c="exitFullscreen",o="enter-fullscreen",u="exit-fullscreen";break;case"play-large":a.class+=" "+this.config.classNames.control+"--overlaid",s="play",l="play",o="play";break;default:l=s,o=e}r?(n.appendChild(Z.createIcon.call(this,u,{class:"icon--pressed"})),n.appendChild(Z.createIcon.call(this,o,{class:"icon--not-pressed"})),n.appendChild(Z.createLabel.call(this,c,{class:"label--pressed"})),n.appendChild(Z.createLabel.call(this,l,{class:"label--not-pressed"}))):(n.appendChild(Z.createIcon.call(this,o)),n.appendChild(Z.createLabel.call(this,l))),V(a,k(this.config.selectors.buttons[s],a)),m(n,a),"play"===s?(i.array(this.elements.buttons[s])||(this.elements.buttons[s]=[]),this.elements.buttons[s].push(n)):this.elements.buttons[s]=n;var d=this.config.classNames.controlPressed;return Object.defineProperty(n,"pressed",{enumerable:!0,get:function(){return A(n,d)},set:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];T(n,d,e)}}),n},createRange:function(e,t){var i=f("input",V(k(this.config.selectors.inputs[e]),{type:"range",min:0,max:100,step:.01,value:0,autocomplete:"off",role:"slider","aria-label":z(e,this.config),"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":0},t));return this.elements.inputs[e]=i,Z.updateRangeFill.call(this,i),i},createProgress:function(e,t){var i=f("progress",V(k(this.config.selectors.display[e]),{min:0,max:100,value:0,role:"presentation","aria-hidden":!0},t));if("volume"!==e){i.appendChild(f("span",null,"0"));var n={played:"played",buffer:"buffered"}[e],a=n?z(n,this.config):"";i.innerText="% "+a.toLowerCase()}return this.elements.display[e]=i,i},createTime:function(e){var t=k(this.config.selectors.display[e]),i=f("div",V(t,{class:(this.config.classNames.display.time+" "+(t.class?t.class:"")).trim(),"aria-label":z(e,this.config)}),"00:00");return this.elements.display[e]=i,i},createMenuItem:function(e){var t=e.value,n=e.list,a=e.type,s=e.title,r=e.badge,l=void 0===r?null:r,o=e.checked,c=void 0!==o&&o,u=k(this.config.selectors.inputs[a]),d=f("button",V(u,{type:"button",role:"menuitemradio",class:(this.config.classNames.control+" "+(u.class?u.class:"")).trim(),value:t,"aria-checked":c}));d.innerHTML=s,i.element(l)&&d.appendChild(l),Object.defineProperty(d,"checked",{enumerable:!0,get:function(){return"true"===d.getAttribute("aria-checked")},set:function(e){e&&Array.from(d.parentNode.children).filter(function(e){return E(e,'[role="menuitemradio"]')}).forEach(function(e){return e.setAttribute("aria-checked","false")}),d.setAttribute("aria-checked",e?"true":"false")}}),n.appendChild(d)},formatTime:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return i.number(e)?G(e,J(this.duration)>0,t):e},updateTimeDisplay:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];i.element(e)&&i.number(t)&&(e.innerText=Z.formatTime(t,n))},updateVolume:function(){this.supported.ui&&(i.element(this.elements.inputs.volume)&&Z.setRange.call(this,this.elements.inputs.volume,this.muted?0:this.volume),i.element(this.elements.buttons.mute)&&(this.elements.buttons.mute.pressed=this.muted||0===this.volume))},setRange:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;i.element(e)&&(e.value=t,Z.updateRangeFill.call(this,e))},updateProgress:function(e){var t=this;if(this.supported.ui&&i.event(e)){var n,a,s=0;if(e)switch(e.type){case"timeupdate":case"seeking":case"seeked":n=this.currentTime,a=this.duration,s=0===n||0===a||Number.isNaN(n)||Number.isNaN(a)?0:(n/a*100).toFixed(2),"timeupdate"===e.type&&Z.setRange.call(this,this.elements.inputs.seek,s);break;case"playing":case"progress":!function(e,n){var a=i.number(n)?n:0,s=i.element(e)?e:t.elements.display.buffer;if(i.element(s)){s.value=a;var r=s.getElementsByTagName("span")[0];i.element(r)&&(r.childNodes[0].nodeValue=a)}}(this.elements.display.buffer,100*this.buffered)}}},updateRangeFill:function(e){var t=i.event(e)?e.target:e;if(i.element(t)&&"range"===t.getAttribute("type")){if(E(t,this.config.selectors.inputs.seek)){t.setAttribute("aria-valuenow",this.currentTime);var n=Z.formatTime(this.currentTime),a=Z.formatTime(this.duration),s=z("seekLabel",this.config);t.setAttribute("aria-valuetext",s.replace("{currentTime}",n).replace("{duration}",a))}else if(E(t,this.config.selectors.inputs.volume)){var r=100*t.value;t.setAttribute("aria-valuenow",r),t.setAttribute("aria-valuetext",r+"%")}else t.setAttribute("aria-valuenow",t.value);q.isWebkit&&t.style.setProperty("--value",t.value/t.max*100+"%")}},updateSeekTooltip:function(e){var t=this;if(this.config.tooltips.seek&&i.element(this.elements.inputs.seek)&&i.element(this.elements.display.seekTooltip)&&0!==this.duration){var n=0,a=this.elements.progress.getBoundingClientRect(),s=this.config.classNames.tooltip+"--visible",r=function(e){T(t.elements.display.seekTooltip,s,e)};if(this.touch)r(!1);else{if(i.event(e))n=100/a.width*(e.pageX-a.left);else{if(!A(this.elements.display.seekTooltip,s))return;n=parseFloat(this.elements.display.seekTooltip.style.left,10)}n<0?n=0:n>100&&(n=100),Z.updateTimeDisplay.call(this,this.elements.display.seekTooltip,this.duration/100*n),this.elements.display.seekTooltip.style.left=n+"%",i.event(e)&&["mouseenter","mouseleave"].includes(e.type)&&r("mouseenter"===e.type)}}},timeUpdate:function(e){var t=!i.element(this.elements.display.duration)&&this.config.invertTime;Z.updateTimeDisplay.call(this,this.elements.display.currentTime,t?this.duration-this.currentTime:this.currentTime,t),e&&"timeupdate"===e.type&&this.media.seeking||Z.updateProgress.call(this,e)},durationUpdate:function(){if(this.supported.ui&&(this.config.invertTime||!this.currentTime)){i.element(this.elements.inputs.seek)&&this.elements.inputs.seek.setAttribute("aria-valuemax",this.duration);var e=i.element(this.elements.display.duration);!e&&this.config.displayDuration&&this.paused&&Z.updateTimeDisplay.call(this,this.elements.display.currentTime,this.duration),e&&Z.updateTimeDisplay.call(this,this.elements.display.duration,this.duration),Z.updateSeekTooltip.call(this)}},toggleMenuButton:function(e,t){w(this.elements.settings.buttons[e],!t)},setQualityMenu:function(e){var t=this;if(i.element(this.elements.settings.panels.quality)){var n=this.elements.settings.panels.quality.querySelector('[role="menu"]');i.array(e)&&(this.options.quality=W(e).filter(function(e){return t.config.quality.options.includes(e)})),console.warn(this.options.quality);var a=!i.empty(this.options.quality)&&this.options.quality.length>1;if(Z.toggleMenuButton.call(this,"quality",a),Z.checkMenu.call(this),a){v(n);this.options.quality.sort(function(e,i){var n=t.config.quality.options;return n.indexOf(e)>n.indexOf(i)?1:-1}).forEach(function(e){Z.createMenuItem.call(t,{value:e,list:n,type:"quality",title:Z.getLabel.call(t,"quality",e),badge:function(e){var i=z("qualityBadge."+e,t.config);return i.length?Z.createBadge.call(t,i):null}(e)})}),Z.updateSetting.call(this,"quality",n)}}else console.warn("Not an element")},getLabel:function(e,t){switch(e){case"speed":return 1===t?z("normal",this.config):t+"×";case"quality":if(i.number(t)){var n=z("qualityLabel."+t,this.config);return n.length?n:t+"p"}return D(t);case"captions":return ie.getLabel.call(this);default:return null}},updateSetting:function(e,t,n){var a=this.elements.settings.panels[e],s=null,r=t;if("captions"===e)s=this.currentTrack;else{if(s=i.empty(n)?this[e]:n,i.empty(s)&&(s=this.config[e].default),!i.empty(this.options[e])&&!this.options[e].includes(s))return void this.debug.warn("Unsupported value of '"+s+"' for "+e);if(!this.config[e].options.includes(s))return void this.debug.warn("Disabled value of '"+s+"' for "+e)}if(i.element(r)||(r=a&&a.querySelector('[role="menu"]')),i.element(r)){this.elements.settings.buttons[e].querySelector("."+this.config.classNames.menu.value).innerHTML=Z.getLabel.call(this,e,s);var l=r&&r.querySelector('[value="'+s+'"]');i.element(l)&&(l.checked=!0)}},setCaptionsMenu:function(){var e=this,t=this.elements.settings.panels.captions.querySelector('[role="menu"]'),i=ie.getTracks.call(this);if(Z.toggleMenuButton.call(this,"captions",i.length),v(t),Z.checkMenu.call(this),i.length){var n=i.map(function(i,n){return{value:n,checked:e.captions.toggled&&e.currentTrack===n,title:ie.getLabel.call(e,i),badge:i.language&&Z.createBadge.call(e,i.language.toUpperCase()),list:t,type:"language"}});n.unshift({value:-1,checked:!this.captions.toggled,title:z("disabled",this.config),list:t,type:"language"}),n.forEach(Z.createMenuItem.bind(this)),Z.updateSetting.call(this,"captions",t)}},setSpeedMenu:function(e){var t=this;if(this.config.controls.includes("settings")&&this.config.settings.includes("speed")&&i.element(this.elements.settings.panels.speed)){i.array(e)?this.options.speed=e:(this.isHTML5||this.isVimeo)&&(this.options.speed=[.5,.75,1,1.25,1.5,1.75,2]),this.options.speed=this.options.speed.filter(function(e){return t.config.speed.options.includes(e)});var n=!i.empty(this.options.speed)&&this.options.speed.length>1;if(Z.toggleMenuButton.call(this,"speed",n),Z.checkMenu.call(this),n){var a=this.elements.settings.panels.speed.querySelector('[role="menu"]');v(a),this.options.speed.forEach(function(e){Z.createMenuItem.call(t,{value:e,list:a,type:"speed",title:Z.getLabel.call(t,"speed",e)})}),Z.updateSetting.call(this,"speed",a)}}},checkMenu:function(){var e=this.elements.settings.buttons,t=!i.empty(e)&&Object.values(e).some(function(e){return!e.hidden});w(this.elements.settings.menu,!t)},toggleMenu:function(e){var t=this.elements.settings.popup,n=this.elements.buttons.settings;if(i.element(t)&&i.element(n)){var a=i.boolean(e)?e:i.element(t)&&t.hasAttribute("hidden");if(i.event(e)){var s=i.element(t)&&t.contains(e.target),r=e.target===this.elements.buttons.settings;if(s||!s&&!r&&a)return;r&&e.stopPropagation()}i.element(n)&&n.setAttribute("aria-expanded",a),i.element(t)&&(w(t,!a),T(this.elements.container,this.config.classNames.menu.open,a),a?t.removeAttribute("tabindex"):t.setAttribute("tabindex",-1))}},getMenuSize:function(e){var t=e.cloneNode(!0);t.style.position="absolute",t.style.opacity=0,t.removeAttribute("hidden"),e.parentNode.appendChild(t);var i=t.scrollWidth,n=t.scrollHeight;return y(t),{width:i,height:n}},showMenuPanel:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=document.getElementById("plyr-settings-"+this.id+"-"+t);if(i.element(n)){var a=n.parentNode,l=Array.from(a.children).find(function(e){return!e.hidden});if(O.transitions&&!O.reducedMotion){a.style.width=l.scrollWidth+"px",a.style.height=l.scrollHeight+"px";var o=Z.getMenuSize.call(this,n);s.call(this,a,x,function t(i){i.target===a&&["width","height"].includes(i.propertyName)&&(a.style.width="",a.style.height="",r.call(e,a,x,t))}),a.style.width=o.width+"px",a.style.height=o.height+"px"}w(l,!0),w(n,!1);var c=n.querySelector('[role^="menuitem"]');c&&c.focus()}},create:function(e){var t=this;if(i.empty(this.config.controls))return null;var n=f("div",k(this.config.selectors.controls.wrapper));if(this.config.controls.includes("restart")&&n.appendChild(Z.createButton.call(this,"restart")),this.config.controls.includes("rewind")&&n.appendChild(Z.createButton.call(this,"rewind")),this.config.controls.includes("play")&&n.appendChild(Z.createButton.call(this,"play")),this.config.controls.includes("fast-forward")&&n.appendChild(Z.createButton.call(this,"fast-forward")),this.config.controls.includes("progress")){var a=f("div",k(this.config.selectors.progress));if(a.appendChild(Z.createRange.call(this,"seek",{id:"plyr-seek-"+e.id})),a.appendChild(Z.createProgress.call(this,"buffer")),this.config.tooltips.seek){var s=f("span",{class:this.config.classNames.tooltip},"00:00");a.appendChild(s),this.elements.display.seekTooltip=s}this.elements.progress=a,n.appendChild(this.elements.progress)}if(this.config.controls.includes("current-time")&&n.appendChild(Z.createTime.call(this,"currentTime")),this.config.controls.includes("duration")&&n.appendChild(Z.createTime.call(this,"duration")),this.config.controls.includes("mute")&&n.appendChild(Z.createButton.call(this,"mute")),this.config.controls.includes("volume")){var r=f("div",{class:"plyr__volume"}),l={max:1,step:.05,value:this.config.volume};r.appendChild(Z.createRange.call(this,"volume",V(l,{id:"plyr-volume-"+e.id}))),this.elements.volume=r,n.appendChild(r)}if(this.config.controls.includes("captions")&&n.appendChild(Z.createButton.call(this,"captions")),this.config.controls.includes("settings")&&!i.empty(this.config.settings)){var o=f("div",{class:"plyr__menu",hidden:""});o.appendChild(Z.createButton.call(this,"settings",{id:"plyr-settings-toggle-"+e.id,"aria-haspopup":!0,"aria-controls":"plyr-settings-"+e.id,"aria-expanded":!1}));var c=f("div",{class:"plyr__menu__container",id:"plyr-settings-"+e.id,hidden:"","aria-labelled-by":"plyr-settings-toggle-"+e.id}),u=f("div"),d=f("div",{id:"plyr-settings-"+e.id+"-home"}),p=f("div",{role:"menu"});this.config.settings.forEach(function(i){var n=f("button",V(k(t.config.selectors.buttons.settings),{type:"button",class:t.config.classNames.control+" "+t.config.classNames.control+"--forward",role:"menuitem","aria-haspopup":!0})),a=f("span",null,z(i,t.config)),s=f("span",{class:t.config.classNames.menu.value});s.innerHTML=e[i],a.appendChild(s),n.appendChild(a),p.appendChild(n);var r=f("div",{id:"plyr-settings-"+e.id+"-"+i,hidden:""}),l=f("button",{type:"button",class:t.config.classNames.control+" "+t.config.classNames.control+"--back"},z(i,t.config));l.addEventListener("click",function(){Z.showMenuPanel.call(t,"home")}),r.appendChild(l),r.appendChild(f("div",{role:"menu"})),u.appendChild(r),n.addEventListener("click",function(){Z.showMenuPanel.call(t,i)}),t.elements.settings.buttons[i]=n,t.elements.settings.panels[i]=r}),d.appendChild(p),u.appendChild(d),c.appendChild(u),o.appendChild(c),n.appendChild(o),this.elements.settings.popup=c,this.elements.settings.menu=o}return this.config.controls.includes("pip")&&O.pip&&n.appendChild(Z.createButton.call(this,"pip")),this.config.controls.includes("airplay")&&O.airplay&&n.appendChild(Z.createButton.call(this,"airplay")),this.config.controls.includes("fullscreen")&&n.appendChild(Z.createButton.call(this,"fullscreen")),this.config.controls.includes("play-large")&&this.elements.container.appendChild(Z.createButton.call(this,"play-large")),this.elements.controls=n,this.isHTML5&&Z.setQualityMenu.call(this,j.getQualityOptions.call(this)),Z.setSpeedMenu.call(this),n},inject:function(){var e=this;if(this.config.loadSprite){var t=Z.getIconUrl.call(this);t.cors&&Q(t.url,"sprite-plyr")}this.id=Math.floor(1e4*Math.random());var n=null;this.elements.controls=null;var a={id:this.id,seektime:this.config.seekTime,title:this.config.title},s=!0;i.string(this.config.controls)||i.element(this.config.controls)?n=this.config.controls:i.function(this.config.controls)?n=this.config.controls.call(this,a):(n=Z.create.call(this,{id:this.id,seektime:this.config.seekTime,speed:this.speed,quality:this.quality,captions:ie.getLabel.call(this)}),s=!1);var r=function(e){var t=e;return Object.entries(a).forEach(function(e){var i=p(e,2),n=i[0],a=i[1];t=H(t,"{"+n+"}",a)}),t};s&&(i.string(this.config.controls)?n=r(n):i.element(n)&&(n.innerHTML=r(n.innerHTML)));var l,o=void 0;if(i.string(this.config.selectors.controls.container)&&(o=document.querySelector(this.config.selectors.controls.container)),i.element(o)||(o=this.elements.container),i.element(n)?o.appendChild(n):n&&o.insertAdjacentHTML("beforeend",n),i.element(this.elements.controls)||Z.findElements.call(this),window.navigator.userAgent.includes("Edge")&&(l=o,setTimeout(function(){w(l,!0),l.offsetHeight,w(l,!1)},0)),this.config.tooltips.controls){var c=this.config,u=c.classNames,d=c.selectors,h=d.controls.wrapper+" "+d.labels+" ."+u.hidden,m=C.call(this,h);Array.from(m).forEach(function(t){T(t,e.config.classNames.hidden,!1),T(t,e.config.classNames.tooltip,!0)})}}};function ee(e){var t=e;if(!(arguments.length>1&&void 0!==arguments[1])||arguments[1]){var i=document.createElement("a");i.href=t,t=i.href}try{return new URL(t)}catch(e){return null}}function te(e){var t=new URLSearchParams;return i.object(e)&&Object.entries(e).forEach(function(e){var i=p(e,2),n=i[0],a=i[1];t.set(n,a)}),t}var ie={setup:function(){if(this.supported.ui)if(!this.isVideo||this.isYouTube||this.isHTML5&&!O.textTracks)i.array(this.config.controls)&&this.config.controls.includes("settings")&&this.config.settings.includes("captions")&&Z.setCaptionsMenu.call(this);else{var e,t;if(i.element(this.elements.captions)||(this.elements.captions=f("div",k(this.config.selectors.captions)),e=this.elements.captions,t=this.elements.wrapper,i.element(e)&&i.element(t)&&t.parentNode.insertBefore(e,t.nextSibling)),q.isIE&&window.URL){var n=this.media.querySelectorAll("track");Array.from(n).forEach(function(e){var t=e.getAttribute("src"),i=ee(t);null!==i&&i.hostname!==window.location.href.hostname&&["http:","https:"].includes(i.protocol)&&Y(t,"blob").then(function(t){e.setAttribute("src",window.URL.createObjectURL(t))}).catch(function(){y(e)})})}var a=W(Array.from(navigator.languages||navigator.userLanguage).map(function(e){return e.split("-")[0]})),r=(this.storage.get("language")||this.config.captions.language||"auto").toLowerCase();if("auto"===r)r=p(a,1)[0];var l=this.storage.get("captions");if(i.boolean(l)||(l=this.config.captions.active),Object.assign(this.captions,{toggled:!1,active:l,language:r,languages:a}),this.isHTML5){var o=this.config.captions.update?"addtrack removetrack":"removetrack";s.call(this,this.media.textTracks,o,ie.update.bind(this))}setTimeout(ie.update.bind(this),0)}},update:function(){var e=this,t=ie.getTracks.call(this,!0),n=this.captions,a=n.active,r=n.language,l=n.meta,o=n.currentTrackNode,c=Boolean(t.find(function(e){return e.language===r}));this.isHTML5&&this.isVideo&&t.filter(function(e){return!l.get(e)}).forEach(function(t){e.debug.log("Track added",t),l.set(t,{default:"showing"===t.mode}),t.mode="hidden",s.call(e,t,"cuechange",function(){return ie.updateCues.call(e)})}),(c&&this.language!==r||!t.includes(o))&&(ie.setLanguage.call(this,r),ie.toggle.call(this,a&&c)),T(this.elements.container,this.config.classNames.captions.enabled,!i.empty(t)),(this.config.controls||[]).includes("settings")&&this.config.settings.includes("captions")&&Z.setCaptionsMenu.call(this)},toggle:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(this.supported.ui){var n=this.captions.toggled,a=this.config.classNames.captions.active,s=i.nullOrUndefined(e)?!n:e;if(s!==n){if(t||(this.captions.active=s,this.storage.set({captions:s})),!this.language&&s&&!t){var r=ie.getTracks.call(this),l=ie.findTrack.call(this,[this.captions.language].concat(function(e){if(Array.isArray(e)){for(var t=0,i=Array(e.length);t<e.length;t++)i[t]=e[t];return i}return Array.from(e)}(this.captions.languages)),!0);return this.captions.language=l.language,void ie.set.call(this,r.indexOf(l))}this.elements.buttons.captions.pressed=s,T(this.elements.container,a,s),this.captions.toggled=s,Z.updateSetting.call(this,"captions"),o.call(this,this.media,s?"captionsenabled":"captionsdisabled")}}},set:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=ie.getTracks.call(this);if(-1!==e)if(i.number(e))if(e in n){if(this.captions.currentTrack!==e){this.captions.currentTrack=e;var a=n[e],s=(a||{}).language;this.captions.currentTrackNode=a,Z.updateSetting.call(this,"captions"),t||(this.captions.language=s,this.storage.set({language:s})),this.isVimeo&&this.embed.enableTextTrack(s),o.call(this,this.media,"languagechange")}ie.toggle.call(this,!0,t),this.isHTML5&&this.isVideo&&ie.updateCues.call(this)}else this.debug.warn("Track not found",e);else this.debug.warn("Invalid caption argument",e);else ie.toggle.call(this,!1,t)},setLanguage:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(i.string(e)){var n=e.toLowerCase();this.captions.language=n;var a=ie.getTracks.call(this),s=ie.findTrack.call(this,[n]);ie.set.call(this,a.indexOf(s),t)}else this.debug.warn("Invalid language argument",e)},getTracks:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return Array.from((this.media||{}).textTracks||[]).filter(function(i){return!e.isHTML5||t||e.captions.meta.has(i)}).filter(function(e){return["captions","subtitles"].includes(e.kind)})},findTrack:function(e){var t=this,i=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=ie.getTracks.call(this),a=function(e){return Number((t.captions.meta.get(e)||{}).default)},s=Array.from(n).sort(function(e,t){return a(t)-a(e)}),r=void 0;return e.every(function(e){return!(r=s.find(function(t){return t.language===e}))}),r||(i?s[0]:void 0)},getCurrentTrack:function(){return ie.getTracks.call(this)[this.currentTrack]},getLabel:function(e){var t=e;return!i.track(t)&&O.textTracks&&this.captions.toggled&&(t=ie.getCurrentTrack.call(this)),i.track(t)?i.empty(t.label)?i.empty(t.language)?z("enabled",this.config):e.language.toUpperCase():t.label:z("disabled",this.config)},updateCues:function(e){if(this.supported.ui)if(i.element(this.elements.captions))if(i.nullOrUndefined(e)||Array.isArray(e)){var t=e;if(!t){var n=ie.getCurrentTrack.call(this);t=Array.from((n||{}).activeCues||[]).map(function(e){return e.getCueAsHTML()}).map(U)}var a=t.map(function(e){return e.trim()}).join("\n");if(a!==this.elements.captions.innerHTML){v(this.elements.captions);var s=f("span",k(this.config.selectors.caption));s.innerHTML=a,this.elements.captions.appendChild(s),o.call(this,this.media,"cuechange")}}else this.debug.warn("updateCues: Invalid input",e);else this.debug.warn("No captions element to render to")}},ne={enabled:!0,title:"",debug:!1,autoplay:!1,autopause:!0,playsinline:!0,seekTime:10,volume:1,muted:!1,duration:null,displayDuration:!0,invertTime:!0,toggleInvert:!0,ratio:"16:9",clickToPlay:!0,hideControls:!0,resetOnEnd:!1,disableContextMenu:!0,loadSprite:!0,iconPrefix:"plyr",iconUrl:"https://cdn.plyr.io/3.3.12/plyr.svg",blankVideo:"https://cdn.plyr.io/static/blank.mp4",quality:{default:576,options:[4320,2880,2160,1440,1080,720,576,480,360,240,"default"]},loop:{active:!1},speed:{selected:1,options:[.5,.75,1,1.25,1.5,1.75,2]},keyboard:{focused:!0,global:!1},tooltips:{controls:!1,seek:!0},captions:{active:!1,language:"auto",update:!1},fullscreen:{enabled:!0,fallback:!0,iosNative:!1},storage:{enabled:!0,key:"plyr"},controls:["play-large","play","progress","current-time","mute","volume","captions","settings","pip","airplay","fullscreen"],settings:["captions","quality","speed"],i18n:{restart:"Restart",rewind:"Rewind {seektime}s",play:"Play",pause:"Pause",fastForward:"Forward {seektime}s",seek:"Seek",seekLabel:"{currentTime} of {duration}",played:"Played",buffered:"Buffered",currentTime:"Current time",duration:"Duration",volume:"Volume",mute:"Mute",unmute:"Unmute",enableCaptions:"Enable captions",disableCaptions:"Disable captions",enterFullscreen:"Enter fullscreen",exitFullscreen:"Exit fullscreen",frameTitle:"Player for {title}",captions:"Captions",settings:"Settings",menuBack:"Go back to previous menu",speed:"Speed",normal:"Normal",quality:"Quality",loop:"Loop",start:"Start",end:"End",all:"All",reset:"Reset",disabled:"Disabled",enabled:"Enabled",advertisement:"Ad",qualityBadge:{2160:"4K",1440:"HD",1080:"HD",720:"HD",576:"SD",480:"SD"}},urls:{vimeo:{sdk:"https://player.vimeo.com/api/player.js",iframe:"https://player.vimeo.com/video/{0}?{1}",api:"https://vimeo.com/api/v2/video/{0}.json"},youtube:{sdk:"https://www.youtube.com/iframe_api",api:"https://www.googleapis.com/youtube/v3/videos?id={0}&key={1}&fields=items(snippet(title))&part=snippet"},googleIMA:{sdk:"https://imasdk.googleapis.com/js/sdkloader/ima3.js"}},listeners:{seek:null,play:null,pause:null,restart:null,rewind:null,fastForward:null,mute:null,volume:null,captions:null,fullscreen:null,pip:null,airplay:null,speed:null,quality:null,loop:null,language:null},events:["ended","progress","stalled","playing","waiting","canplay","canplaythrough","loadstart","loadeddata","loadedmetadata","timeupdate","volumechange","play","pause","error","seeking","seeked","emptied","ratechange","cuechange","enterfullscreen","exitfullscreen","captionsenabled","captionsdisabled","languagechange","controlshidden","controlsshown","ready","statechange","qualitychange","qualityrequested","adsloaded","adscontentpause","adscontentresume","adstarted","adsmidpoint","adscomplete","adsallcomplete","adsimpression","adsclick"],selectors:{editable:"input, textarea, select, [contenteditable]",container:".plyr",controls:{container:null,wrapper:".plyr__controls"},labels:"[data-plyr]",buttons:{play:'[data-plyr="play"]',pause:'[data-plyr="pause"]',restart:'[data-plyr="restart"]',rewind:'[data-plyr="rewind"]',fastForward:'[data-plyr="fast-forward"]',mute:'[data-plyr="mute"]',captions:'[data-plyr="captions"]',fullscreen:'[data-plyr="fullscreen"]',pip:'[data-plyr="pip"]',airplay:'[data-plyr="airplay"]',settings:'[data-plyr="settings"]',loop:'[data-plyr="loop"]'},inputs:{seek:'[data-plyr="seek"]',volume:'[data-plyr="volume"]',speed:'[data-plyr="speed"]',language:'[data-plyr="language"]',quality:'[data-plyr="quality"]'},display:{currentTime:".plyr__time--current",duration:".plyr__time--duration",buffer:".plyr__progress__buffer",loop:".plyr__progress__loop",volume:".plyr__volume--display"},progress:".plyr__progress",captions:".plyr__captions",caption:".plyr__caption",menu:{quality:".js-plyr__menu__list--quality"}},classNames:{type:"plyr--{0}",provider:"plyr--{0}",video:"plyr__video-wrapper",embed:"plyr__video-embed",embedContainer:"plyr__video-embed__container",poster:"plyr__poster",posterEnabled:"plyr__poster-enabled",ads:"plyr__ads",control:"plyr__control",controlPressed:"plyr__control--pressed",playing:"plyr--playing",paused:"plyr--paused",stopped:"plyr--stopped",loading:"plyr--loading",hover:"plyr--hover",tooltip:"plyr__tooltip",cues:"plyr__cues",hidden:"plyr__sr-only",hideControls:"plyr--hide-controls",isIos:"plyr--is-ios",isTouch:"plyr--is-touch",uiSupported:"plyr--full-ui",noTransition:"plyr--no-transition",display:{time:"plyr__time"},menu:{value:"plyr__menu__value",badge:"plyr__badge",open:"plyr--menu-open"},captions:{enabled:"plyr--captions-enabled",active:"plyr--captions-active"},fullscreen:{enabled:"plyr--fullscreen-enabled",fallback:"plyr--fullscreen-fallback"},pip:{supported:"plyr--pip-supported",active:"plyr--pip-active"},airplay:{supported:"plyr--airplay-supported",active:"plyr--airplay-active"},tabFocus:"plyr__tab-focus"},attributes:{embed:{provider:"data-plyr-provider",id:"data-plyr-embed-id"}},keys:{google:null},ads:{enabled:!1,publisherId:""}},ae={html5:"html5",youtube:"youtube",vimeo:"vimeo"},se={audio:"audio",video:"video"};var re=function(){},le=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];c(this,e),this.enabled=window.console&&t,this.enabled&&this.log("Debugging enabled")}return u(e,[{key:"log",get:function(){return this.enabled?Function.prototype.bind.call(console.log,console):re}},{key:"warn",get:function(){return this.enabled?Function.prototype.bind.call(console.warn,console):re}},{key:"error",get:function(){return this.enabled?Function.prototype.bind.call(console.error,console):re}}]),e}();function oe(){if(this.enabled){var e=this.player.elements.buttons.fullscreen;i.element(e)&&(e.pressed=this.active),o.call(this.player,this.target,this.active?"enterfullscreen":"exitfullscreen",!0),q.isIos||function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(i.element(e)){var n=C.call(this,"button:not(:disabled), input:not(:disabled), [tabindex]"),s=n[0],r=n[n.length-1];a.call(this,this.elements.container,"keydown",function(e){if("Tab"===e.key&&9===e.keyCode){var t=S();t!==r||e.shiftKey?t===s&&e.shiftKey&&(r.focus(),e.preventDefault()):(s.focus(),e.preventDefault())}},t,!1)}}.call(this.player,this.target,this.active)}}function ce(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];e?this.scrollPosition={x:window.scrollX||0,y:window.scrollY||0}:window.scrollTo(this.scrollPosition.x,this.scrollPosition.y),document.body.style.overflow=e?"hidden":"",T(this.target,this.player.config.classNames.fullscreen.fallback,e),oe.call(this)}var ue=function(){function e(t){var n=this;c(this,e),this.player=t,this.prefix=e.prefix,this.property=e.property,this.scrollPosition={x:0,y:0},s.call(this.player,document,"ms"===this.prefix?"MSFullscreenChange":this.prefix+"fullscreenchange",function(){oe.call(n)}),s.call(this.player,this.player.elements.container,"dblclick",function(e){i.element(n.player.elements.controls)&&n.player.elements.controls.contains(e.target)||n.toggle()}),this.update()}return u(e,[{key:"update",value:function(){this.enabled?this.player.debug.log((e.native?"Native":"Fallback")+" fullscreen enabled"):this.player.debug.log("Fullscreen not supported and fallback disabled"),T(this.player.elements.container,this.player.config.classNames.fullscreen.enabled,this.enabled)}},{key:"enter",value:function(){this.enabled&&(q.isIos&&this.player.config.fullscreen.iosNative?this.player.playing&&this.target.webkitEnterFullscreen():e.native?this.prefix?i.empty(this.prefix)||this.target[this.prefix+"Request"+this.property]():this.target.requestFullscreen():ce.call(this,!0))}},{key:"exit",value:function(){if(this.enabled)if(q.isIos&&this.player.config.fullscreen.iosNative)this.target.webkitExitFullscreen(),this.player.play();else if(e.native)if(this.prefix){if(!i.empty(this.prefix)){var t="moz"===this.prefix?"Cancel":"Exit";document[""+this.prefix+t+this.property]()}}else(document.cancelFullScreen||document.exitFullscreen).call(document);else ce.call(this,!1)}},{key:"toggle",value:function(){this.active?this.exit():this.enter()}},{key:"enabled",get:function(){return(e.native||this.player.config.fullscreen.fallback)&&this.player.config.fullscreen.enabled&&this.player.supported.ui&&this.player.isVideo}},{key:"active",get:function(){return!!this.enabled&&(e.native?(this.prefix?document[""+this.prefix+this.property+"Element"]:document.fullscreenElement)===this.target:A(this.target,this.player.config.classNames.fullscreen.fallback))}},{key:"target",get:function(){return q.isIos&&this.player.config.fullscreen.iosNative?this.player.media:this.player.elements.container}}],[{key:"native",get:function(){return!!(document.fullscreenEnabled||document.webkitFullscreenEnabled||document.mozFullScreenEnabled||document.msFullscreenEnabled)}},{key:"prefix",get:function(){if(i.function(document.exitFullscreen))return"";var e="";return["webkit","moz","ms"].some(function(t){return!(!i.function(document[t+"ExitFullscreen"])&&!i.function(document[t+"CancelFullScreen"]))&&(e=t,!0)}),e}},{key:"property",get:function(){return"moz"===this.prefix?"FullScreen":"Fullscreen"}}]),e}();function de(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return new Promise(function(i,n){var a=new Image,s=function(){delete a.onload,delete a.onerror,(a.naturalWidth>=t?i:n)(a)};Object.assign(a,{onload:s,onerror:s,src:e})})}var pe={addStyleHook:function(){T(this.elements.container,this.config.selectors.container.replace(".",""),!0),T(this.elements.container,this.config.classNames.uiSupported,this.supported.ui)},toggleNativeControls:function(){arguments.length>0&&void 0!==arguments[0]&&arguments[0]&&this.isHTML5?this.media.setAttribute("controls",""):this.media.removeAttribute("controls")},build:function(){var e=this;if(this.listeners.media(),!this.supported.ui)return this.debug.warn("Basic support only for "+this.provider+" "+this.type),void pe.toggleNativeControls.call(this,!0);i.element(this.elements.controls)||(Z.inject.call(this),this.listeners.controls()),pe.toggleNativeControls.call(this),this.isHTML5&&ie.setup.call(this),this.volume=null,this.muted=null,this.speed=null,this.loop=null,this.quality=null,Z.updateVolume.call(this),Z.timeUpdate.call(this),pe.checkPlaying.call(this),T(this.elements.container,this.config.classNames.pip.supported,O.pip&&this.isHTML5&&this.isVideo),T(this.elements.container,this.config.classNames.airplay.supported,O.airplay&&this.isHTML5),T(this.elements.container,this.config.classNames.isIos,q.isIos),T(this.elements.container,this.config.classNames.isTouch,this.touch),this.ready=!0,setTimeout(function(){o.call(e,e.media,"ready")},0),pe.setTitle.call(this),this.poster&&pe.setPoster.call(this,this.poster,!1).catch(function(){}),this.config.duration&&Z.durationUpdate.call(this)},setTitle:function(){var e=z("play",this.config);if(i.string(this.config.title)&&!i.empty(this.config.title)&&(e+=", "+this.config.title),Array.from(this.elements.buttons.play||[]).forEach(function(t){t.setAttribute("aria-label",e)}),this.isEmbed){var t=P.call(this,"iframe");if(!i.element(t))return;var n=i.empty(this.config.title)?"video":this.config.title,a=z("frameTitle",this.config);t.setAttribute("title",a.replace("{title}",n))}},togglePoster:function(e){T(this.elements.container,this.config.classNames.posterEnabled,e)},setPoster:function(e){var t=this;return arguments.length>1&&void 0!==arguments[1]&&!arguments[1]||!this.poster?(this.media.setAttribute("poster",e),function(){var e=this;return new Promise(function(t){return e.ready?setTimeout(t,0):s.call(e,e.elements.container,"ready",t)}).then(function(){})}.call(this).then(function(){return de(e)}).catch(function(i){throw e===t.poster&&pe.togglePoster.call(t,!1),i}).then(function(){if(e!==t.poster)throw new Error("setPoster cancelled by later call to setPoster")}).then(function(){return Object.assign(t.elements.poster.style,{backgroundImage:"url('"+e+"')",backgroundSize:""}),pe.togglePoster.call(t,!0),e})):Promise.reject(new Error("Poster already set"))},checkPlaying:function(e){var t=this;T(this.elements.container,this.config.classNames.playing,this.playing),T(this.elements.container,this.config.classNames.paused,this.paused),T(this.elements.container,this.config.classNames.stopped,this.stopped),Array.from(this.elements.buttons.play||[]).forEach(function(e){e.pressed=t.playing}),i.event(e)&&"timeupdate"===e.type||pe.toggleControls.call(this)},checkLoading:function(e){var t=this;this.loading=["stalled","waiting"].includes(e.type),clearTimeout(this.timers.loading),this.timers.loading=setTimeout(function(){T(t.elements.container,t.config.classNames.loading,t.loading),pe.toggleControls.call(t)},this.loading?250:0)},toggleControls:function(e){var t=this.elements.controls;t&&this.config.hideControls&&this.toggleControls(Boolean(e||this.loading||this.paused||t.pressed||t.hover))}},he=function(){function e(t){c(this,e),this.player=t,this.lastKey=null,this.handleKey=this.handleKey.bind(this),this.toggleMenu=this.toggleMenu.bind(this),this.firstTouch=this.firstTouch.bind(this)}return u(e,[{key:"handleKey",value:function(e){var t=this,n=e.keyCode?e.keyCode:e.which,a="keydown"===e.type,s=a&&n===this.lastKey;if(!(e.altKey||e.ctrlKey||e.metaKey||e.shiftKey)&&i.number(n)){if(a){var r=S();if(i.element(r)&&r!==this.player.elements.inputs.seek&&E(r,this.player.config.selectors.editable))return;switch([32,37,38,39,40,48,49,50,51,52,53,54,56,57,67,70,73,75,76,77,79].includes(n)&&(e.preventDefault(),e.stopPropagation()),n){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:s||(t.player.currentTime=t.player.duration/10*(n-48));break;case 32:case 75:s||this.player.togglePlay();break;case 38:this.player.increaseVolume(.1);break;case 40:this.player.decreaseVolume(.1);break;case 77:s||(this.player.muted=!this.player.muted);break;case 39:this.player.forward();break;case 37:this.player.rewind();break;case 70:this.player.fullscreen.toggle();break;case 67:s||this.player.toggleCaptions();break;case 76:this.player.loop=!this.player.loop}!this.player.fullscreen.enabled&&this.player.fullscreen.active&&27===n&&this.player.fullscreen.toggle(),this.lastKey=n}else this.lastKey=null}}},{key:"toggleMenu",value:function(e){Z.toggleMenu.call(this.player,e)}},{key:"firstTouch",value:function(){this.player.touch=!0,T(this.player.elements.container,this.player.config.classNames.isTouch,!0)}},{key:"global",value:function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.player.config.keyboard.global&&a.call(this.player,window,"keydown keyup",this.handleKey,e,!1),a.call(this.player,document.body,"click",this.toggleMenu,e),l.call(this.player,document.body,"touchstart",this.firstTouch)}},{key:"container",value:function(){var e=this;!this.player.config.keyboard.global&&this.player.config.keyboard.focused&&s.call(this.player,this.player.elements.container,"keydown keyup",this.handleKey,!1),s.call(this.player,this.player.elements.container,"focusout",function(t){T(t.target,e.player.config.classNames.tabFocus,!1)}),s.call(this.player,this.player.elements.container,"keydown",function(t){9===t.keyCode&&setTimeout(function(){T(S(),e.player.config.classNames.tabFocus,!0)},0)}),s.call(this.player,this.player.elements.container,"mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen",function(t){var i=e.player.elements.controls;"enterfullscreen"===t.type&&(i.pressed=!1,i.hover=!1);var n=0;["touchstart","touchmove","mousemove"].includes(t.type)&&(pe.toggleControls.call(e.player,!0),n=e.player.touch?3e3:2e3),clearTimeout(e.player.timers.controls),e.player.timers.controls=setTimeout(function(){return pe.toggleControls.call(e.player,!1)},n)})}},{key:"media",value:function(){var e=this;if(s.call(this.player,this.player.media,"timeupdate seeking seeked",function(t){return Z.timeUpdate.call(e.player,t)}),s.call(this.player,this.player.media,"durationchange loadeddata loadedmetadata",function(t){return Z.durationUpdate.call(e.player,t)}),s.call(this.player,this.player.media,"canplay",function(){w(e.player.elements.volume,!e.player.hasAudio),w(e.player.elements.buttons.mute,!e.player.hasAudio)}),s.call(this.player,this.player.media,"ended",function(){e.player.isHTML5&&e.player.isVideo&&e.player.config.resetOnEnd&&e.player.restart()}),s.call(this.player,this.player.media,"progress playing seeking seeked",function(t){return Z.updateProgress.call(e.player,t)}),s.call(this.player,this.player.media,"volumechange",function(t){return Z.updateVolume.call(e.player,t)}),s.call(this.player,this.player.media,"playing play pause ended emptied timeupdate",function(t){return pe.checkPlaying.call(e.player,t)}),s.call(this.player,this.player.media,"waiting canplay seeked playing",function(t){return pe.checkLoading.call(e.player,t)}),s.call(this.player,this.player.media,"playing",function(){e.player.ads&&e.player.ads.enabled&&!e.player.ads.initialized&&e.player.ads.managerPromise.then(function(){return e.player.ads.play()}).catch(function(){return e.player.play()})}),this.player.supported.ui&&this.player.config.clickToPlay&&!this.player.isAudio){var t=P.call(this.player,"."+this.player.config.classNames.video);if(!i.element(t))return;s.call(this.player,t,"click",function(){e.player.config.hideControls&&e.player.touch&&!e.player.paused||(e.player.paused?e.player.play():e.player.ended?(e.player.restart(),e.player.play()):e.player.pause())})}this.player.supported.ui&&this.player.config.disableContextMenu&&s.call(this.player,this.player.elements.wrapper,"contextmenu",function(e){e.preventDefault()},!1),s.call(this.player,this.player.media,"volumechange",function(){e.player.storage.set({volume:e.player.volume,muted:e.player.muted})}),s.call(this.player,this.player.media,"ratechange",function(){Z.updateSetting.call(e.player,"speed"),e.player.storage.set({speed:e.player.speed})}),s.call(this.player,this.player.media,"qualityrequested",function(t){e.player.storage.set({quality:t.detail.quality})}),s.call(this.player,this.player.media,"qualitychange",function(t){Z.updateSetting.call(e.player,"quality",null,t.detail.quality)});var n=this.player.config.events.concat(["keyup","keydown"]).join(" ");s.call(this.player,this.player.media,n,function(t){var i=t.detail,n=void 0===i?{}:i;"error"===t.type&&(n=e.player.media.error),o.call(e.player,e.player.elements.container,t.type,!0,n)})}},{key:"controls",value:function(){var e=this,t=q.isIE?"change":"input",n=function(t,n,a){var s=e.player.config.listeners[a],r=!0;i.function(s)&&(r=s.call(e.player,t)),r&&i.function(n)&&n.call(e.player,t)},a=function(t,a,r,l){var o=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],c=e.player.config.listeners[l],u=i.function(c);s.call(e.player,t,a,function(e){return n(e,r,l)},o&&!u)};Array.from(this.player.elements.buttons.play).forEach(function(t){a(t,"click",e.player.togglePlay,"play")}),a(this.player.elements.buttons.restart,"click",this.player.restart,"restart"),a(this.player.elements.buttons.rewind,"click",this.player.rewind,"rewind"),a(this.player.elements.buttons.fastForward,"click",this.player.forward,"fastForward"),a(this.player.elements.buttons.mute,"click",function(){e.player.muted=!e.player.muted},"mute"),a(this.player.elements.buttons.captions,"click",function(){return e.player.toggleCaptions()}),a(this.player.elements.buttons.fullscreen,"click",function(){e.player.fullscreen.toggle()},"fullscreen"),a(this.player.elements.buttons.pip,"click",function(){e.player.pip="toggle"},"pip"),a(this.player.elements.buttons.airplay,"click",this.player.airplay,"airplay"),a(this.player.elements.buttons.settings,"click",function(t){Z.toggleMenu.call(e.player,t)}),a(this.player.elements.settings.popup,"click",function(t){t.stopPropagation();var i=function(){Z.showMenuPanel.call(e.player,"home")};E(t.target,e.player.config.selectors.inputs.language)?n(t,function(){e.player.currentTrack=Number(t.target.value),i()},"language"):E(t.target,e.player.config.selectors.inputs.quality)?n(t,function(){e.player.quality=t.target.value,i()},"quality"):E(t.target,e.player.config.selectors.inputs.speed)&&n(t,function(){e.player.speed=parseFloat(t.target.value),i()},"speed")}),a(this.player.elements.inputs.seek,"mousedown mousemove",function(t){var i=e.player.elements.progress.getBoundingClientRect(),n=100/i.width*(t.pageX-i.left);t.currentTarget.setAttribute("seek-value",n)}),a(this.player.elements.inputs.seek,"mousedown mouseup keydown keyup touchstart touchend",function(t){var i=t.currentTarget,n=t.keyCode?t.keyCode:t.which,a=t.type;if("keydown"!==a&&"keyup"!==a||39===n||37===n){var s=i.hasAttribute("play-on-seeked"),r=["mouseup","touchend","keyup"].includes(t.type);s&&r?(i.removeAttribute("play-on-seeked"),e.player.play()):!r&&e.player.playing&&(i.setAttribute("play-on-seeked",""),e.player.pause())}}),a(this.player.elements.inputs.seek,t,function(t){var n=t.currentTarget,a=n.getAttribute("seek-value");i.empty(a)&&(a=n.value),n.removeAttribute("seek-value"),e.player.currentTime=a/n.max*e.player.duration},"seek"),this.player.config.toggleInvert&&!i.element(this.player.elements.display.duration)&&a(this.player.elements.display.currentTime,"click",function(){0!==e.player.currentTime&&(e.player.config.invertTime=!e.player.config.invertTime,Z.timeUpdate.call(e.player))}),a(this.player.elements.inputs.volume,t,function(t){e.player.volume=t.target.value},"volume"),q.isWebkit&&Array.from(C.call(this.player,'input[type="range"]')).forEach(function(t){a(t,"input",function(t){return Z.updateRangeFill.call(e.player,t.target)})}),a(this.player.elements.progress,"mouseenter mouseleave mousemove",function(t){return Z.updateSeekTooltip.call(e.player,t)}),a(this.player.elements.controls,"mouseenter mouseleave",function(t){e.player.elements.controls.hover=!e.player.touch&&"mouseenter"===t.type}),a(this.player.elements.controls,"mousedown mouseup touchstart touchend touchcancel",function(t){e.player.elements.controls.pressed=["mousedown","touchstart"].includes(t.type)}),a(this.player.elements.controls,"focusin focusout",function(t){var i=e.player,n=i.config,a=i.elements,s=i.timers;if(T(a.controls,n.classNames.noTransition,"focusin"===t.type),pe.toggleControls.call(e.player,"focusin"===t.type),"focusin"===t.type){setTimeout(function(){T(a.controls,n.classNames.noTransition,!1)},0);var r=e.touch?3e3:4e3;clearTimeout(s.controls),s.controls=setTimeout(function(){return pe.toggleControls.call(e.player,!1)},r)}}),a(this.player.elements.inputs.volume,"wheel",function(t){var i=t.webkitDirectionInvertedFromDevice,n=0;(t.deltaY<0||t.deltaX>0)&&(i?(e.player.decreaseVolume(.02),n=-1):(e.player.increaseVolume(.02),n=1)),(t.deltaY>0||t.deltaX<0)&&(i?(e.player.increaseVolume(.02),n=1):(e.player.decreaseVolume(.02),n=-1)),(1===n&&e.player.media.volume<1||-1===n&&e.player.media.volume>0)&&t.preventDefault()},"volume",!1)}}]),e}();"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var me,fe=(function(e,t){var i;i=function(){var e=function(){},t={},i={},n={};function a(e,t){if(e){var a=n[e];if(i[e]=t,a)for(;a.length;)a[0](e,t),a.splice(0,1)}}function s(t,i){t.call&&(t={success:t}),i.length?(t.error||e)(i):(t.success||e)(t)}function r(t,i,n,a){var s,l,o=document,c=n.async,u=(n.numRetries||0)+1,d=n.before||e,p=t.replace(/^(css|img)!/,"");a=a||0,/(^css!|\.css$)/.test(t)?(s=!0,(l=o.createElement("link")).rel="stylesheet",l.href=p):/(^img!|\.(png|gif|jpg|svg)$)/.test(t)?(l=o.createElement("img")).src=p:((l=o.createElement("script")).src=t,l.async=void 0===c||c),l.onload=l.onerror=l.onbeforeload=function(e){var o=e.type[0];if(s&&"hideFocus"in l)try{l.sheet.cssText.length||(o="e")}catch(e){o="e"}if("e"==o&&(a+=1)<u)return r(t,i,n,a);i(t,o,e.defaultPrevented)},!1!==d(t,l)&&o.head.appendChild(l)}function l(e,i,n){var l,o;if(i&&i.trim&&(l=i),o=(l?n:i)||{},l){if(l in t)throw"LoadJS";t[l]=!0}!function(e,t,i){var n,a,s=(e=e.push?e:[e]).length,l=s,o=[];for(n=function(e,i,n){if("e"==i&&o.push(e),"b"==i){if(!n)return;o.push(e)}--s||t(o)},a=0;a<l;a++)r(e[a],n,i)}(e,function(e){s(o,e),a(l,e)},o)}return l.ready=function(e,t){return function(e,t){e=e.push?e:[e];var a,s,r,l=[],o=e.length,c=o;for(a=function(e,i){i.length&&l.push(e),--c||t(l)};o--;)s=e[o],(r=i[s])?a(s,r):(n[s]=n[s]||[]).push(a)}(e,function(e){s(t,e)}),l},l.done=function(e){a(e,[])},l.reset=function(){t={},i={},n={}},l.isDefined=function(e){return e in t},l},e.exports=i()}(me={exports:{}},me.exports),me.exports);function ge(e){return new Promise(function(t,i){fe(e,{success:t,error:i})})}function ye(e){e&&!this.embed.hasPlayed&&(this.embed.hasPlayed=!0),this.media.paused===e&&(this.media.paused=!e,o.call(this,this.media,e?"play":"pause"))}var ve={setup:function(){var e=this;T(this.elements.wrapper,this.config.classNames.embed,!0),ve.setAspectRatio.call(this),i.object(window.Vimeo)?ve.ready.call(this):ge(this.config.urls.vimeo.sdk).then(function(){ve.ready.call(e)}).catch(function(t){e.debug.warn("Vimeo API failed to load",t)})},setAspectRatio:function(e){var t=(i.string(e)?e:this.config.ratio).split(":"),n=p(t,2),a=100/n[0]*n[1];if(this.elements.wrapper.style.paddingBottom=a+"%",this.supported.ui){var s=(240-a)/4.8;this.media.style.transform="translateY(-"+s+"%)"}},ready:function(){var e=this,t=this,n=te({loop:t.config.loop.active,autoplay:t.autoplay,byline:!1,portrait:!1,title:!1,speed:!0,transparent:0,gesture:"media",playsinline:!this.config.fullscreen.iosNative}),a=t.media.getAttribute("src");i.empty(a)&&(a=t.media.getAttribute(t.config.attributes.embed.id));var s,r=(s=a,i.empty(s)?null:i.number(Number(s))?s:s.match(/^.*(vimeo.com\/|video\/)(\d+).*/)?RegExp.$2:s),l=f("iframe"),c=B(t.config.urls.vimeo.iframe,r,n);l.setAttribute("src",c),l.setAttribute("allowfullscreen",""),l.setAttribute("allowtransparency",""),l.setAttribute("allow","autoplay");var u=f("div",{poster:t.poster,class:t.config.classNames.embedContainer});u.appendChild(l),t.media=b(u,t.media),Y(B(t.config.urls.vimeo.api,r),"json").then(function(e){if(!i.empty(e)){var n=new URL(e[0].thumbnail_large);n.pathname=n.pathname.split("_")[0]+".jpg",pe.setPoster.call(t,n.href).catch(function(){})}}),t.embed=new window.Vimeo.Player(l,{autopause:t.config.autopause,muted:t.muted}),t.media.paused=!0,t.media.currentTime=0,t.supported.ui&&t.embed.disableTextTrack(),t.media.play=function(){return ye.call(t,!0),t.embed.play()},t.media.pause=function(){return ye.call(t,!1),t.embed.pause()},t.media.stop=function(){t.pause(),t.currentTime=0};var d=t.media.currentTime;Object.defineProperty(t.media,"currentTime",{get:function(){return d},set:function(e){var i=t.embed,n=t.media,a=t.paused,s=t.volume,r=a&&!i.hasPlayed;n.seeking=!0,o.call(t,n,"seeking"),Promise.resolve(r&&i.setVolume(0)).then(function(){return i.setCurrentTime(e)}).then(function(){return r&&i.pause()}).then(function(){return r&&i.setVolume(s)}).catch(function(){})}});var p=t.config.speed.selected;Object.defineProperty(t.media,"playbackRate",{get:function(){return p},set:function(e){t.embed.setPlaybackRate(e).then(function(){p=e,o.call(t,t.media,"ratechange")}).catch(function(e){"Error"===e.name&&Z.setSpeedMenu.call(t,[])})}});var h=t.config.volume;Object.defineProperty(t.media,"volume",{get:function(){return h},set:function(e){t.embed.setVolume(e).then(function(){h=e,o.call(t,t.media,"volumechange")})}});var m=t.config.muted;Object.defineProperty(t.media,"muted",{get:function(){return m},set:function(e){var n=!!i.boolean(e)&&e;t.embed.setVolume(n?0:t.config.volume).then(function(){m=n,o.call(t,t.media,"volumechange")})}});var g=t.config.loop;Object.defineProperty(t.media,"loop",{get:function(){return g},set:function(e){var n=i.boolean(e)?e:t.config.loop.active;t.embed.setLoop(n).then(function(){g=n})}});var y=void 0;t.embed.getVideoUrl().then(function(e){y=e}).catch(function(t){e.debug.warn(t)}),Object.defineProperty(t.media,"currentSrc",{get:function(){return y}}),Object.defineProperty(t.media,"ended",{get:function(){return t.currentTime===t.duration}}),Promise.all([t.embed.getVideoWidth(),t.embed.getVideoHeight()]).then(function(t){var i=function(e,t){var i=function e(t,i){return 0===i?t:e(i,t%i)}(e,t);return e/i+":"+t/i}(t[0],t[1]);ve.setAspectRatio.call(e,i)}),t.embed.setAutopause(t.config.autopause).then(function(e){t.config.autopause=e}),t.embed.getVideoTitle().then(function(i){t.config.title=i,pe.setTitle.call(e)}),t.embed.getCurrentTime().then(function(e){d=e,o.call(t,t.media,"timeupdate")}),t.embed.getDuration().then(function(e){t.media.duration=e,o.call(t,t.media,"durationchange")}),t.embed.getTextTracks().then(function(e){t.media.textTracks=e,ie.setup.call(t)}),t.embed.on("cuechange",function(e){var i=e.cues,n=(void 0===i?[]:i).map(function(e){return t=e.text,i=document.createDocumentFragment(),n=document.createElement("div"),i.appendChild(n),n.innerHTML=t,i.firstChild.innerText;var t,i,n});ie.updateCues.call(t,n)}),t.embed.on("loaded",function(){(t.embed.getPaused().then(function(e){ye.call(t,!e),e||o.call(t,t.media,"playing")}),i.element(t.embed.element)&&t.supported.ui)&&t.embed.element.setAttribute("tabindex",-1)}),t.embed.on("play",function(){ye.call(t,!0),o.call(t,t.media,"playing")}),t.embed.on("pause",function(){ye.call(t,!1)}),t.embed.on("timeupdate",function(e){t.media.seeking=!1,d=e.seconds,o.call(t,t.media,"timeupdate")}),t.embed.on("progress",function(e){t.media.buffered=e.percent,o.call(t,t.media,"progress"),1===parseInt(e.percent,10)&&o.call(t,t.media,"canplaythrough"),t.embed.getDuration().then(function(e){e!==t.media.duration&&(t.media.duration=e,o.call(t,t.media,"durationchange"))})}),t.embed.on("seeked",function(){t.media.seeking=!1,o.call(t,t.media,"seeked")}),t.embed.on("ended",function(){t.media.paused=!0,o.call(t,t.media,"ended")}),t.embed.on("error",function(e){t.media.error=e,o.call(t,t.media,"error")}),setTimeout(function(){return pe.build.call(t)},0)}};function be(e){var t=Object.entries({hd2160:2160,hd1440:1440,hd1080:1080,hd720:720,large:480,medium:360,small:240,tiny:144}).find(function(t){return t.includes(e)});return t?t.find(function(t){return t!==e}):"default"}function ke(e){e&&!this.embed.hasPlayed&&(this.embed.hasPlayed=!0),this.media.paused===e&&(this.media.paused=!e,o.call(this,this.media,e?"play":"pause"))}var we,Te={setup:function(){var e=this;T(this.elements.wrapper,this.config.classNames.embed,!0),Te.setAspectRatio.call(this),i.object(window.YT)&&i.function(window.YT.Player)?Te.ready.call(this):(ge(this.config.urls.youtube.sdk).catch(function(t){e.debug.warn("YouTube API failed to load",t)}),window.onYouTubeReadyCallbacks=window.onYouTubeReadyCallbacks||[],window.onYouTubeReadyCallbacks.push(function(){Te.ready.call(e)}),window.onYouTubeIframeAPIReady=function(){window.onYouTubeReadyCallbacks.forEach(function(e){e()})})},getTitle:function(e){var t=this;if(i.function(this.embed.getVideoData)){var n=this.embed.getVideoData().title;if(i.empty(n))return this.config.title=n,void pe.setTitle.call(this)}var a=this.config.keys.google;i.string(a)&&!i.empty(a)&&Y(B(this.config.urls.youtube.api,e,a)).then(function(e){i.object(e)&&(t.config.title=e.items[0].snippet.title,pe.setTitle.call(t))}).catch(function(){})},setAspectRatio:function(){var e=this.config.ratio.split(":");this.elements.wrapper.style.paddingBottom=100/e[0]*e[1]+"%"},ready:function(){var e=this,t=e.media.getAttribute("id");if(i.empty(t)||!t.startsWith("youtube-")){var n=e.media.getAttribute("src");i.empty(n)&&(n=e.media.getAttribute(this.config.attributes.embed.id));var a,s=(a=n,i.empty(a)?null:a.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/)?RegExp.$2:a),r=e.provider+"-"+Math.floor(1e4*Math.random()),l=f("div",{id:r,poster:e.poster});e.media=b(l,e.media);var c=function(e){return"https://img.youtube.com/vi/"+s+"/"+e+"default.jpg"};de(c("maxres"),121).catch(function(){return de(c("sd"),121)}).catch(function(){return de(c("hq"))}).then(function(t){return pe.setPoster.call(e,t.src)}).then(function(t){t.includes("maxres")||(e.elements.poster.style.backgroundSize="cover")}).catch(function(){}),e.embed=new window.YT.Player(r,{videoId:s,playerVars:{autoplay:e.config.autoplay?1:0,controls:e.supported.ui?0:1,rel:0,showinfo:0,iv_load_policy:3,modestbranding:1,disablekb:1,playsinline:1,widget_referrer:window?window.location.href:null,cc_load_policy:e.captions.active?1:0,cc_lang_pref:e.config.captions.language},events:{onError:function(t){if(!e.media.error){var i=t.data,n={2:"The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.",5:"The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.",100:"The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.",101:"The owner of the requested video does not allow it to be played in embedded players.",150:"The owner of the requested video does not allow it to be played in embedded players."}[i]||"An unknown error occured";e.media.error={code:i,message:n},o.call(e,e.media,"error")}},onPlaybackQualityChange:function(){o.call(e,e.media,"qualitychange",!1,{quality:e.media.quality})},onPlaybackRateChange:function(t){var i=t.target;e.media.playbackRate=i.getPlaybackRate(),o.call(e,e.media,"ratechange")},onReady:function(t){var n=t.target;Te.getTitle.call(e,s),e.media.play=function(){ke.call(e,!0),n.playVideo()},e.media.pause=function(){ke.call(e,!1),n.pauseVideo()},e.media.stop=function(){n.stopVideo()},e.media.duration=n.getDuration(),e.media.paused=!0,e.media.currentTime=0,Object.defineProperty(e.media,"currentTime",{get:function(){return Number(n.getCurrentTime())},set:function(t){e.paused&&e.embed.mute(),e.media.seeking=!0,o.call(e,e.media,"seeking"),n.seekTo(t)}}),Object.defineProperty(e.media,"playbackRate",{get:function(){return n.getPlaybackRate()},set:function(e){n.setPlaybackRate(e)}}),Object.defineProperty(e.media,"quality",{get:function(){return be(n.getPlaybackQuality())},set:function(e){n.setPlaybackQuality(be(e))}});var a=e.config.volume;Object.defineProperty(e.media,"volume",{get:function(){return a},set:function(t){a=t,n.setVolume(100*a),o.call(e,e.media,"volumechange")}});var r=e.config.muted;Object.defineProperty(e.media,"muted",{get:function(){return r},set:function(t){var a=i.boolean(t)?t:r;r=a,n[a?"mute":"unMute"](),o.call(e,e.media,"volumechange")}}),Object.defineProperty(e.media,"currentSrc",{get:function(){return n.getVideoUrl()}}),Object.defineProperty(e.media,"ended",{get:function(){return e.currentTime===e.duration}}),e.options.speed=n.getAvailablePlaybackRates(),e.supported.ui&&e.media.setAttribute("tabindex",-1),o.call(e,e.media,"timeupdate"),o.call(e,e.media,"durationchange"),clearInterval(e.timers.buffering),e.timers.buffering=setInterval(function(){e.media.buffered=n.getVideoLoadedFraction(),(null===e.media.lastBuffered||e.media.lastBuffered<e.media.buffered)&&o.call(e,e.media,"progress"),e.media.lastBuffered=e.media.buffered,1===e.media.buffered&&(clearInterval(e.timers.buffering),o.call(e,e.media,"canplaythrough"))},200),setTimeout(function(){return pe.build.call(e)},50)},onStateChange:function(t){var n,a=t.target;switch(clearInterval(e.timers.playing),e.media.seeking&&[1,2].includes(t.data)&&(e.media.seeking=!1,o.call(e,e.media,"seeked")),t.data){case-1:o.call(e,e.media,"timeupdate"),e.media.buffered=a.getVideoLoadedFraction(),o.call(e,e.media,"progress");break;case 0:ke.call(e,!1),e.media.loop?(a.stopVideo(),a.playVideo()):o.call(e,e.media,"ended");break;case 1:e.media.paused&&!e.embed.hasPlayed?e.media.pause():(ke.call(e,!0),o.call(e,e.media,"playing"),e.timers.playing=setInterval(function(){o.call(e,e.media,"timeupdate")},50),e.media.duration!==a.getDuration()&&(e.media.duration=a.getDuration(),o.call(e,e.media,"durationchange")),Z.setQualityMenu.call(e,(n=a.getAvailableQualityLevels(),i.empty(n)?n:W(n.map(function(e){return be(e)})))));break;case 2:e.muted||e.embed.unMute(),ke.call(e,!1)}o.call(e,e.elements.container,"statechange",!1,{code:t.data})}}})}}},Ae={setup:function(){this.media?(T(this.elements.container,this.config.classNames.type.replace("{0}",this.type),!0),T(this.elements.container,this.config.classNames.provider.replace("{0}",this.provider),!0),this.isEmbed&&T(this.elements.container,this.config.classNames.type.replace("{0}","video"),!0),this.isVideo&&(this.elements.wrapper=f("div",{class:this.config.classNames.video}),h(this.media,this.elements.wrapper),this.elements.poster=f("div",{class:this.config.classNames.poster}),this.elements.wrapper.appendChild(this.elements.poster)),this.isHTML5?j.extend.call(this):this.isYouTube?Te.setup.call(this):this.isVimeo&&ve.setup.call(this)):this.debug.warn("No media element found!")}},Ee=function(){function e(t){var i=this;c(this,e),this.player=t,this.publisherId=t.config.ads.publisherId,this.playing=!1,this.initialized=!1,this.elements={container:null,displayContainer:null},this.manager=null,this.loader=null,this.cuePoints=null,this.events={},this.safetyTimer=null,this.countdownTimer=null,this.managerPromise=new Promise(function(e,t){i.on("loaded",e),i.on("error",t)}),this.load()}return u(e,[{key:"load",value:function(){var e=this;this.enabled&&(i.object(window.google)&&i.object(window.google.ima)?this.ready():ge(this.player.config.urls.googleIMA.sdk).then(function(){e.ready()}).catch(function(){e.trigger("error",new Error("Google IMA SDK failed to load"))}))}},{key:"ready",value:function(){var e=this;this.startSafetyTimer(12e3,"ready()"),this.managerPromise.then(function(){e.clearSafetyTimer("onAdsManagerLoaded()")}),this.listeners(),this.setupIMA()}},{key:"setupIMA",value:function(){this.elements.container=f("div",{class:this.player.config.classNames.ads}),this.player.elements.container.appendChild(this.elements.container),google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED),google.ima.settings.setLocale(this.player.config.ads.language),this.elements.displayContainer=new google.ima.AdDisplayContainer(this.elements.container),this.requestAds()}},{key:"requestAds",value:function(){var e=this,t=this.player.elements.container;try{this.loader=new google.ima.AdsLoader(this.elements.displayContainer),this.loader.addEventListener(google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,function(t){return e.onAdsManagerLoaded(t)},!1),this.loader.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,function(t){return e.onAdError(t)},!1);var i=new google.ima.AdsRequest;i.adTagUrl=this.tagUrl,i.linearAdSlotWidth=t.offsetWidth,i.linearAdSlotHeight=t.offsetHeight,i.nonLinearAdSlotWidth=t.offsetWidth,i.nonLinearAdSlotHeight=t.offsetHeight,i.forceNonLinearFullSlot=!1,i.setAdWillPlayMuted(!this.player.muted),this.loader.requestAds(i)}catch(e){this.onAdError(e)}}},{key:"pollCountdown",value:function(){var e=this;if(!(arguments.length>0&&void 0!==arguments[0]&&arguments[0]))return clearInterval(this.countdownTimer),void this.elements.container.removeAttribute("data-badge-text");this.countdownTimer=setInterval(function(){var t=G(Math.max(e.manager.getRemainingTime(),0)),i=z("advertisement",e.player.config)+" - "+t;e.elements.container.setAttribute("data-badge-text",i)},100)}},{key:"onAdsManagerLoaded",value:function(e){var t=this,n=new google.ima.AdsRenderingSettings;n.restoreCustomPlaybackStateOnAdBreakComplete=!0,n.enablePreloading=!0,this.manager=e.getAdsManager(this.player,n),this.cuePoints=this.manager.getCuePoints(),i.empty(this.cuePoints)||this.cuePoints.forEach(function(e){if(0!==e&&-1!==e&&e<t.player.duration){var n=t.player.elements.progress;if(i.element(n)){var a=100/t.player.duration*e,s=f("span",{class:t.player.config.classNames.cues});s.style.left=a.toString()+"%",n.appendChild(s)}}}),this.manager.setVolume(this.player.volume),this.manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,function(e){return t.onAdError(e)}),Object.keys(google.ima.AdEvent.Type).forEach(function(e){t.manager.addEventListener(google.ima.AdEvent.Type[e],function(e){return t.onAdEvent(e)})}),this.trigger("loaded")}},{key:"onAdEvent",value:function(e){var t=this,i=this.player.elements.container,n=e.getAd(),a=function(e){var i="ads"+e.replace(/_/g,"").toLowerCase();o.call(t.player,t.player.media,i)};switch(e.type){case google.ima.AdEvent.Type.LOADED:this.trigger("loaded"),a(e.type),this.pollCountdown(!0),n.isLinear()||(n.width=i.offsetWidth,n.height=i.offsetHeight);break;case google.ima.AdEvent.Type.ALL_ADS_COMPLETED:a(e.type),this.loadAds();break;case google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED:a(e.type),this.pauseContent();break;case google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED:a(e.type),this.pollCountdown(),this.resumeContent();break;case google.ima.AdEvent.Type.STARTED:case google.ima.AdEvent.Type.MIDPOINT:case google.ima.AdEvent.Type.COMPLETE:case google.ima.AdEvent.Type.IMPRESSION:case google.ima.AdEvent.Type.CLICK:a(e.type)}}},{key:"onAdError",value:function(e){this.cancel(),this.player.debug.warn("Ads error",e)}},{key:"listeners",value:function(){var e=this,t=this.player.elements.container,n=void 0;this.player.on("ended",function(){e.loader.contentComplete()}),this.player.on("seeking",function(){return n=e.player.currentTime}),this.player.on("seeked",function(){var t=e.player.currentTime;i.empty(e.cuePoints)||e.cuePoints.forEach(function(i,a){n<i&&i<t&&(e.manager.discardAdBreak(),e.cuePoints.splice(a,1))})}),window.addEventListener("resize",function(){e.manager&&e.manager.resize(t.offsetWidth,t.offsetHeight,google.ima.ViewMode.NORMAL)})}},{key:"play",value:function(){var e=this,t=this.player.elements.container;this.managerPromise||this.resumeContent(),this.managerPromise.then(function(){e.elements.displayContainer.initialize();try{e.initialized||(e.manager.init(t.offsetWidth,t.offsetHeight,google.ima.ViewMode.NORMAL),e.manager.start()),e.initialized=!0}catch(t){e.onAdError(t)}}).catch(function(){})}},{key:"resumeContent",value:function(){this.elements.container.style.zIndex="",this.playing=!1,this.player.currentTime<this.player.duration&&this.player.play()}},{key:"pauseContent",value:function(){this.elements.container.style.zIndex=3,this.playing=!0,this.player.pause()}},{key:"cancel",value:function(){this.initialized&&this.resumeContent(),this.trigger("error"),this.loadAds()}},{key:"loadAds",value:function(){var e=this;this.managerPromise.then(function(){e.manager&&e.manager.destroy(),e.managerPromise=new Promise(function(t){e.on("loaded",t),e.player.debug.log(e.manager)}),e.requestAds()}).catch(function(){})}},{key:"trigger",value:function(e){for(var t=this,n=arguments.length,a=Array(n>1?n-1:0),s=1;s<n;s++)a[s-1]=arguments[s];var r=this.events[e];i.array(r)&&r.forEach(function(e){i.function(e)&&e.apply(t,a)})}},{key:"on",value:function(e,t){return i.array(this.events[e])||(this.events[e]=[]),this.events[e].push(t),this}},{key:"startSafetyTimer",value:function(e,t){var i=this;this.player.debug.log("Safety timer invoked from: "+t),this.safetyTimer=setTimeout(function(){i.cancel(),i.clearSafetyTimer("startSafetyTimer()")},e)}},{key:"clearSafetyTimer",value:function(e){i.nullOrUndefined(this.safetyTimer)||(this.player.debug.log("Safety timer cleared from: "+e),clearTimeout(this.safetyTimer),this.safetyTimer=null)}},{key:"enabled",get:function(){return this.player.isVideo&&this.player.config.ads.enabled&&!i.empty(this.publisherId)}},{key:"tagUrl",get:function(){return"https://go.aniview.com/api/adserver6/vast/?"+te({AV_PUBLISHERID:"58c25bb0073ef448b1087ad6",AV_CHANNELID:"5a0458dc28a06145e4519d21",AV_URL:location.hostname,cb:Date.now(),AV_WIDTH:640,AV_HEIGHT:480,AV_CDIM2:this.publisherId})}}]),e}(),Ce={insertElements:function(e,t){var n=this;i.string(t)?g(e,this.media,{src:t}):i.array(t)&&t.forEach(function(t){g(e,n.media,t)})},change:function(e){var t=this;R(e,"sources.length")?(j.cancelRequests.call(this),this.destroy.call(this,function(){t.options.quality=[],y(t.media),t.media=null,i.element(t.elements.container)&&t.elements.container.removeAttribute("class");var n=e.sources,a=e.type,s=p(n,1)[0],r=s.provider,l=void 0===r?ae.html5:r,o=s.src,c="html5"===l?a:"div",u="html5"===l?{}:{src:o};Object.assign(t,{provider:l,type:a,supported:O.check(a,l,t.config.playsinline),media:f(c,u)}),t.elements.container.appendChild(t.media),i.boolean(e.autoplay)&&(t.config.autoplay=e.autoplay),t.isHTML5&&(t.config.crossorigin&&t.media.setAttribute("crossorigin",""),t.config.autoplay&&t.media.setAttribute("autoplay",""),i.empty(e.poster)||(t.poster=e.poster),t.config.loop.active&&t.media.setAttribute("loop",""),t.config.muted&&t.media.setAttribute("muted",""),t.config.playsinline&&t.media.setAttribute("playsinline","")),pe.addStyleHook.call(t),t.isHTML5&&Ce.insertElements.call(t,"source",n),t.config.title=e.title,Ae.setup.call(t),t.isHTML5&&("tracks"in e&&Ce.insertElements.call(t,"track",e.tracks),t.media.load()),(t.isHTML5||t.isEmbed&&!t.supported.ui)&&pe.build.call(t),t.fullscreen.update()},!0)):this.debug.warn("Invalid source format")}},Pe=function(){function e(t,n){var a=this;if(c(this,e),this.timers={},this.ready=!1,this.loading=!1,this.failed=!1,this.touch=O.touch,this.media=t,i.string(this.media)&&(this.media=document.querySelectorAll(this.media)),(window.jQuery&&this.media instanceof jQuery||i.nodeList(this.media)||i.array(this.media))&&(this.media=this.media[0]),this.config=V({},ne,e.defaults,n||{},function(){try{return JSON.parse(a.media.getAttribute("data-plyr-config"))}catch(e){return{}}}()),this.elements={container:null,captions:null,buttons:{},display:{},progress:{},inputs:{},settings:{popup:null,menu:null,panels:{},buttons:{}}},this.captions={active:null,currentTrack:-1,meta:new WeakMap},this.fullscreen={active:!1},this.options={speed:[],quality:[]},this.debug=new le(this.config.debug),this.debug.log("Config",this.config),this.debug.log("Support",O),!i.nullOrUndefined(this.media)&&i.element(this.media))if(this.media.plyr)this.debug.warn("Target already setup");else if(this.config.enabled)if(O.check().api){var r=this.media.cloneNode(!0);r.autoplay=!1,this.elements.original=r;var l=this.media.tagName.toLowerCase(),o=null,u=null;switch(l){case"div":if(o=this.media.querySelector("iframe"),i.element(o)){if(u=ee(o.getAttribute("src")),this.provider=function(e){return/^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.?be)\/.+$/.test(e)?ae.youtube:/^https?:\/\/player.vimeo.com\/video\/\d{0,9}(?=\b|\/)/.test(e)?ae.vimeo:null}(u.toString()),this.elements.container=this.media,this.media=o,this.elements.container.className="",u.searchParams.length){var d=["1","true"];d.includes(u.searchParams.get("autoplay"))&&(this.config.autoplay=!0),d.includes(u.searchParams.get("loop"))&&(this.config.loop.active=!0),this.isYouTube?this.config.playsinline=d.includes(u.searchParams.get("playsinline")):this.config.playsinline=!0}}else this.provider=this.media.getAttribute(this.config.attributes.embed.provider),this.media.removeAttribute(this.config.attributes.embed.provider);if(i.empty(this.provider)||!Object.keys(ae).includes(this.provider))return void this.debug.error("Setup failed: Invalid provider");this.type=se.video;break;case"video":case"audio":this.type=l,this.provider=ae.html5,this.media.hasAttribute("crossorigin")&&(this.config.crossorigin=!0),this.media.hasAttribute("autoplay")&&(this.config.autoplay=!0),this.media.hasAttribute("playsinline")&&(this.config.playsinline=!0),this.media.hasAttribute("muted")&&(this.config.muted=!0),this.media.hasAttribute("loop")&&(this.config.loop.active=!0);break;default:return void this.debug.error("Setup failed: unsupported type")}this.supported=O.check(this.type,this.provider,this.config.playsinline),this.supported.api?(this.eventListeners=[],this.listeners=new he(this),this.storage=new K(this),this.media.plyr=this,i.element(this.elements.container)||(this.elements.container=f("div"),h(this.media,this.elements.container)),pe.addStyleHook.call(this),Ae.setup.call(this),this.config.debug&&s.call(this,this.elements.container,this.config.events.join(" "),function(e){a.debug.log("event: "+e.type)}),(this.isHTML5||this.isEmbed&&!this.supported.ui)&&pe.build.call(this),this.listeners.container(),this.listeners.global(),this.fullscreen=new ue(this),this.ads=new Ee(this),this.config.autoplay&&this.play()):this.debug.error("Setup failed: no support")}else this.debug.error("Setup failed: no support");else this.debug.error("Setup failed: disabled by config");else this.debug.error("Setup failed: no suitable element passed")}return u(e,[{key:"play",value:function(){return i.function(this.media.play)?this.media.play():null}},{key:"pause",value:function(){this.playing&&i.function(this.media.pause)&&this.media.pause()}},{key:"togglePlay",value:function(e){(i.boolean(e)?e:!this.playing)?this.play():this.pause()}},{key:"stop",value:function(){this.isHTML5?(this.pause(),this.restart()):i.function(this.media.stop)&&this.media.stop()}},{key:"restart",value:function(){this.currentTime=0}},{key:"rewind",value:function(e){this.currentTime=this.currentTime-(i.number(e)?e:this.config.seekTime)}},{key:"forward",value:function(e){this.currentTime=this.currentTime+(i.number(e)?e:this.config.seekTime)}},{key:"increaseVolume",value:function(e){var t=this.media.muted?0:this.volume;this.volume=t+(i.number(e)?e:1)}},{key:"decreaseVolume",value:function(e){var t=this.media.muted?0:this.volume;this.volume=t-(i.number(e)?e:1)}},{key:"toggleCaptions",value:function(e){ie.toggle.call(this,e,!1)}},{key:"airplay",value:function(){O.airplay&&this.media.webkitShowPlaybackTargetPicker()}},{key:"toggleControls",value:function(e){if(this.supported.ui&&!this.isAudio){var t=A(this.elements.container,this.config.classNames.hideControls),n=void 0===e?void 0:!e,a=T(this.elements.container,this.config.classNames.hideControls,n);if(a&&this.config.controls.includes("settings")&&!i.empty(this.config.settings)&&Z.toggleMenu.call(this,!1),a!==t){var s=a?"controlshidden":"controlsshown";o.call(this,this.media,s)}return!a}return!1}},{key:"on",value:function(e,t){s.call(this,this.elements.container,e,t)}},{key:"once",value:function(e,t){l.call(this,this.elements.container,e,t)}},{key:"off",value:function(e,t){r(this.elements.container,e,t)}},{key:"destroy",value:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(this.ready){var a=function(){document.body.style.overflow="",t.embed=null,n?(Object.keys(t.elements).length&&(y(t.elements.buttons.play),y(t.elements.captions),y(t.elements.controls),y(t.elements.wrapper),t.elements.buttons.play=null,t.elements.captions=null,t.elements.controls=null,t.elements.wrapper=null),i.function(e)&&e()):(function(){this&&this.eventListeners&&(this.eventListeners.forEach(function(e){var t=e.element,i=e.type,n=e.callback,a=e.options;t.removeEventListener(i,n,a)}),this.eventListeners=[])}.call(t),b(t.elements.original,t.elements.container),o.call(t,t.elements.original,"destroyed",!0),i.function(e)&&e.call(t.elements.original),t.ready=!1,setTimeout(function(){t.elements=null,t.media=null},200))};this.stop(),this.isHTML5?(clearTimeout(this.timers.loading),pe.toggleNativeControls.call(this,!0),a()):this.isYouTube?(clearInterval(this.timers.buffering),clearInterval(this.timers.playing),null!==this.embed&&i.function(this.embed.destroy)&&this.embed.destroy(),a()):this.isVimeo&&(null!==this.embed&&this.embed.unload().then(a),setTimeout(a,200))}}},{key:"supports",value:function(e){return O.mime.call(this,e)}},{key:"isHTML5",get:function(){return Boolean(this.provider===ae.html5)}},{key:"isEmbed",get:function(){return Boolean(this.isYouTube||this.isVimeo)}},{key:"isYouTube",get:function(){return Boolean(this.provider===ae.youtube)}},{key:"isVimeo",get:function(){return Boolean(this.provider===ae.vimeo)}},{key:"isVideo",get:function(){return Boolean(this.type===se.video)}},{key:"isAudio",get:function(){return Boolean(this.type===se.audio)}},{key:"playing",get:function(){return Boolean(this.ready&&!this.paused&&!this.ended)}},{key:"paused",get:function(){return Boolean(this.media.paused)}},{key:"stopped",get:function(){return Boolean(this.paused&&0===this.currentTime)}},{key:"ended",get:function(){return Boolean(this.media.ended)}},{key:"currentTime",set:function(e){if(this.duration){var t=i.number(e)&&e>0;this.media.currentTime=t?Math.min(e,this.duration):0,this.debug.log("Seeking to "+this.currentTime+" seconds")}},get:function(){return Number(this.media.currentTime)}},{key:"buffered",get:function(){var e=this.media.buffered;return i.number(e)?e:e&&e.length&&this.duration>0?e.end(0)/this.duration:0}},{key:"seeking",get:function(){return Boolean(this.media.seeking)}},{key:"duration",get:function(){var e=parseFloat(this.config.duration),t=(this.media||{}).duration||0;return e||t}},{key:"volume",set:function(e){var t=e;i.string(t)&&(t=Number(t)),i.number(t)||(t=this.storage.get("volume")),i.number(t)||(t=this.config.volume),t>1&&(t=1),t<0&&(t=0),this.config.volume=t,this.media.volume=t,!i.empty(e)&&this.muted&&t>0&&(this.muted=!1)},get:function(){return Number(this.media.volume)}},{key:"muted",set:function(e){var t=e;i.boolean(t)||(t=this.storage.get("muted")),i.boolean(t)||(t=this.config.muted),this.config.muted=t,this.media.muted=t},get:function(){return Boolean(this.media.muted)}},{key:"hasAudio",get:function(){return!this.isHTML5||(!!this.isAudio||(Boolean(this.media.mozHasAudio)||Boolean(this.media.webkitAudioDecodedByteCount)||Boolean(this.media.audioTracks&&this.media.audioTracks.length)))}},{key:"speed",set:function(e){var t=null;i.number(e)&&(t=e),i.number(t)||(t=this.storage.get("speed")),i.number(t)||(t=this.config.speed.selected),t<.1&&(t=.1),t>2&&(t=2),this.config.speed.options.includes(t)?(this.config.speed.selected=t,this.media.playbackRate=t):this.debug.warn("Unsupported speed ("+t+")")},get:function(){return Number(this.media.playbackRate)}},{key:"quality",set:function(e){var t=this.config.quality,n=this.options.quality;if(n.length){var a=[!i.empty(e)&&Number(e),this.storage.get("quality"),t.selected,t.default].find(i.number);if(!n.includes(a)){var s=function(e,t){return i.array(e)&&e.length?e.reduce(function(e,i){return Math.abs(i-t)<Math.abs(e-t)?i:e}):null}(n,a);this.debug.warn("Unsupported quality option: "+a+", using "+s+" instead"),a=s}o.call(this,this.media,"qualityrequested",!1,{quality:a}),t.selected=a,this.media.quality=a}},get:function(){return this.media.quality}},{key:"loop",set:function(e){var t=i.boolean(e)?e:this.config.loop.active;this.config.loop.active=t,this.media.loop=t},get:function(){return Boolean(this.media.loop)}},{key:"source",set:function(e){Ce.change.call(this,e)},get:function(){return this.media.currentSrc}},{key:"poster",set:function(e){this.isVideo?pe.setPoster.call(this,e,!1).catch(function(){}):this.debug.warn("Poster can only be set for video")},get:function(){return this.isVideo?this.media.getAttribute("poster"):null}},{key:"autoplay",set:function(e){var t=i.boolean(e)?e:this.config.autoplay;this.config.autoplay=t},get:function(){return Boolean(this.config.autoplay)}},{key:"currentTrack",set:function(e){ie.set.call(this,e,!1)},get:function(){var e=this.captions,t=e.toggled,i=e.currentTrack;return t?i:-1}},{key:"language",set:function(e){ie.setLanguage.call(this,e,!1)},get:function(){return(ie.getCurrentTrack.call(this)||{}).language}},{key:"pip",set:function(e){var t="picture-in-picture",n="inline";if(O.pip){var a=i.boolean(e)?e:this.pip===n;this.media.webkitSetPresentationMode(a?t:n)}},get:function(){return O.pip?this.media.webkitPresentationMode:null}}],[{key:"supported",value:function(e,t,i){return O.check(e,t,i)}},{key:"loadSprite",value:function(e,t){return Q(e,t)}},{key:"setup",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},a=null;return i.string(t)?a=Array.from(document.querySelectorAll(t)):i.nodeList(t)?a=Array.from(t):i.array(t)&&(a=t.filter(i.element)),i.empty(a)?null:a.map(function(t){return new e(t,n)})}}]),e}();return Pe.defaults=(we=ne,JSON.parse(JSON.stringify(we))),Pe}); //# sourceMappingURL=plyr.min.js.map diff --git a/dist/plyr.min.js.map b/dist/plyr.min.js.map index 28c9dd32..2adab1d7 100644 --- a/dist/plyr.min.js.map +++ b/dist/plyr.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["src/js/utils/is.js","src/js/utils/events.js","src/js/utils/elements.js","src/js/utils/animation.js","src/js/utils/browser.js","src/js/support.js","src/js/html5.js","src/js/utils/objects.js","src/js/utils/strings.js","src/js/i18n.js","src/js/utils/arrays.js","src/js/storage.js","src/js/utils/fetch.js","src/js/utils/loadSprite.js","src/js/utils/time.js","src/js/controls.js","src/js/utils/urls.js","src/js/captions.js","src/js/config/defaults.js","src/js/config/types.js","src/js/console.js","src/js/fullscreen.js","src/js/utils/loadImage.js","src/js/ui.js","src/js/listeners.js","node_modules/loadjs/dist/loadjs.umd.js","src/js/utils/loadScript.js","src/js/plugins/vimeo.js","src/js/plugins/youtube.js","src/js/media.js","src/js/plugins/ads.js","src/js/source.js","src/js/plyr.js"],"names":["getConstructor","input","constructor","instanceOf","Boolean","is","object","Object","number","Number","isNaN","string","String","boolean","function","Function","array","nullOrUndefined","Array","isArray","weakMap","WeakMap","nodeList","NodeList","element","Element","textNode","Text","event","Event","cue","window","TextTrackCue","VTTCue","track","TextTrack","kind","url","test","empty","length","keys","supportsPassiveListeners","supported","options","defineProperty","get","addEventListener","removeEventListener","e","toggleListener","callback","toggle","arguments","undefined","_this","this","passive","capture","events","split","forEach","type","eventListeners","push","on","call","off","once","onceCallback","_len","args","_key","apply","triggerEvent","bubbles","detail","CustomEvent","assign","plyr","dispatchEvent","wrap","elements","wrapper","targets","from","reverse","index","child","cloneNode","parent","parentNode","sibling","nextSibling","appendChild","insertBefore","setAttributes","attributes","entries","filter","_ref","value","slicedToArray","_ref3","_ref4","key","setAttribute","createElement","text","document","innerText","insertElement","removeElement","removeChild","emptyElement","childNodes","lastChild","replaceElement","newChild","oldChild","replaceChild","getAttributesFromSelector","sel","existingAttributes","existing","s","selector","trim","className","replace","parts","charAt","class","id","toggleHidden","hidden","hide","hasAttribute","removeAttribute","toggleClass","force","method","classList","contains","hasClass","matches","prototype","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","querySelectorAll","includes","getElements","container","getElement","querySelector","getFocusElement","focused","activeElement","body","transitionEndEvent","WebkitTransition","MozTransition","OTransition","transition","find","style","range","browser","isIE","documentMode","isWebkit","documentElement","navigator","userAgent","isIPhone","platform","isIos","defaultCodecs","audio/ogg","audio/wav","video/webm","video/mp4","video/ogg","support","audio","video","check","provider","playsinline","canPlayInline","api","ui","rangeInput","pip","webkitSetPresentationMode","airplay","WebKitPlaybackTargetAvailabilityEvent","mime","inputType","_inputType$split","mediaType","isHTML5","media","canPlayType","err","textTracks","touch","transitions","reducedMotion","matchMedia","html5","getSources","source","getAttribute","getQualityOptions","map","extend","player","_sources$filter","set","currentTime","playing","src","load","play","quality","cancelRequests","config","blankVideo","debug","log","getDeep","path","reduce","obj","target","sources","shift","concat","format","toString","match","i","replaceAll","RegExp","toTitleCase","toUpperCase","substr","toLowerCase","toCamelCase","toPascalCase","slice","getHTML","innerHTML","i18n","{seektime}","seekTime","{title}","title","_ref2","dedupe","item","indexOf","Storage","classCallCheck","enabled","storage","store","localStorage","getItem","json","JSON","parse","setItem","stringify","removeItem","fetch","responseType","Promise","resolve","reject","request","XMLHttpRequest","responseText","response","Error","status","open","send","loadSprite","hasId","exists","getElementById","update","data","insertAdjacentElement","useStorage","cached","prefix","content","then","result","catch","getHours","parseInt","getMinutes","getSeconds","formatTime","time","displayHours","inverted","hours","mins","secs","controls","getIconUrl","cors","URL","iconUrl","location","host","svg4everybody","findElements","selectors","buttons","pause","restart","rewind","fastForward","mute","settings","captions","fullscreen","progress","inputs","seek","volume","display","buffer","duration","seekTooltip","classNames","tooltip","error","warn","toggleNativeControls","createIcon","iconPath","iconPrefix","icon","createElementNS","role","focusable","use","setAttributeNS","createLabel","attr","join","createBadge","badge","menu","createButton","buttonType","button","label","labelPressed","iconPressed","control","controlPressed","enumerable","pressed","createRange","min","max","step","autocomplete","aria-label","aria-valuemin","aria-valuemax","aria-valuenow","updateRangeFill","createProgress","aria-hidden","suffixKey","played","suffix","createTime","createMenuItem","list","_ref$badge","_ref$checked","checked","aria-checked","children","node","updateTimeDisplay","updateVolume","setRange","muted","updateProgress","current","toFixed","getElementsByTagName","nodeValue","setProgress","buffered","percent","setProperty","updateSeekTooltip","_this2","tooltips","clientRect","getBoundingClientRect","visible","_toggle","width","pageX","left","parseFloat","timeUpdate","invert","invertTime","seeking","durationUpdate","hasDuration","displayDuration","paused","toggleMenuButton","setting","setQualityMenu","_this3","panels","checkMenu","sort","a","b","sorting","getLabel","getBadge","updateSetting","pane","currentTrack","default","setCaptionsMenu","_this4","tracks","getTracks","toggled","language","unshift","bind","setSpeedMenu","_this5","speed","isVimeo","values","some","toggleMenu","popup","show","isMenuItem","isButton","stopPropagation","getMenuSize","tab","clone","position","opacity","scrollWidth","height","scrollHeight","showMenuPanel","_this6","size","restore","propertyName","focus","create","_this7","aria-haspopup","aria-controls","aria-expanded","aria-labelled-by","inner","home","menuItem","flex","back","inject","_this8","Math","floor","random","props","seektime","insertAdjacentHTML","setTimeout","offsetHeight","_config","labels","parseUrl","parser","href","buildUrlParams","params","URLSearchParams","setup","isVideo","isYouTube","hostname","protocol","blob","createObjectURL","languages","userLanguage","active","trackEvents","_captions","meta","currentTrackNode","languageExists","mode","updateCues","setLanguage","activeClass","findTrack","toConsumableArray","embed","enableTextTrack","has","sortIsDefault","sorted","every","getCurrentTrack","cues","activeCues","getCueAsHTML","cueText","caption","defaults","autoplay","autopause","toggleInvert","ratio","clickToPlay","hideControls","resetOnEnd","disableContextMenu","loop","selected","keyboard","global","fallback","iosNative","seekLabel","unmute","enableCaptions","disableCaptions","enterFullscreen","exitFullscreen","frameTitle","menuBack","normal","start","end","all","reset","disabled","advertisement","qualityBadge","2160","1440","1080","720","576","480","urls","vimeo","sdk","iframe","youtube","googleIMA","listeners","editable","embedContainer","poster","posterEnabled","ads","stopped","loading","hover","isTouch","uiSupported","noTransition","tabFocus","google","publisherId","providers","types","noop","Console","console","onChange","first","last","keyCode","shiftKey","preventDefault","toggleFallback","scrollPosition","x","scrollX","y","scrollY","scrollTo","overflow","Fullscreen","property","native","webkitEnterFullscreen","requestFullscreen","webkitExitFullscreen","action","cancelFullScreen","exit","enter","fullscreenElement","fullscreenEnabled","webkitFullscreenEnabled","mozFullScreenEnabled","msFullscreenEnabled","pre","loadImage","minWidth","image","Image","handler","onload","onerror","naturalWidth","addStyleHook","build","checkPlaying","ready","setTitle","setPoster","isEmbed","togglePoster","enable","backgroundImage","backgroundSize","toggleControls","checkLoading","clearTimeout","timers","Listeners","lastKey","handleKey","firstTouch","code","which","repeat","altKey","ctrlKey","metaKey","togglePlay","increaseVolume","decreaseVolume","forward","toggleCaptions","delay","hasAudio","initialized","managerPromise","isAudio","ended","proxyEvents","_event$detail","inputEvent","proxy","defaultHandler","customHandlerKey","customHandler","returned","hasCustomHandler","showHomeTab","currentTarget","eventType","done","seekTo","_player","webkitDirectionInvertedFromDevice","direction","deltaY","deltaX","factory","devnull","bundleIdCache","bundleResultCache","bundleCallbackQueue","publish","bundleId","pathsNotFound","q","splice","executeCallbacks","depsNotFound","success","loadFile","callbackFn","numTries","isCss","doc","async","maxTries","numRetries","beforeCallbackFn","before","pathStripped","rel","onbeforeload","ev","sheet","cssText","defaultPrevented","head","loadjs","paths","arg1","arg2","fn","numWaiting","loadFiles","deps","bundleIds","r","subscribe","isDefined","module","exports","loadScript","assurePlaybackState","hasPlayed","setAspectRatio","Vimeo","_split","_split2","padding","paddingBottom","offset","transform","byline","portrait","transparent","gesture","$2","thumbnail_large","pathname","Player","disableTextTrack","stop","restorePause","setVolume","setCurrentTime","setPlaybackRate","name","setLoop","currentSrc","getVideoUrl","getVideoWidth","getVideoHeight","dimensions","getRatio","w","h","getAspectRatio","setAutopause","state","getVideoTitle","getCurrentTime","getDuration","getTextTracks","_ref$cues","strippedCues","fragment","createDocumentFragment","firstChild","getPaused","seconds","mapQualityUnit","entry","hd2160","hd1440","hd1080","hd720","large","medium","small","tiny","YT","onYouTubeReadyCallbacks","onYouTubeIframeAPIReady","getTitle","videoId","getVideoData","items","snippet","currentId","startsWith","posterSrc","format$$1","playerVars","showinfo","iv_load_policy","modestbranding","disablekb","widget_referrer","cc_load_policy","cc_lang_pref","onError","message","2","5","100","101","150","onPlaybackQualityChange","onPlaybackRateChange","instance","playbackRate","getPlaybackRate","onReady","playVideo","pauseVideo","stopVideo","getPlaybackQuality","setPlaybackQuality","getAvailablePlaybackRates","clearInterval","buffering","setInterval","getVideoLoadedFraction","lastBuffered","onStateChange","levels","getAvailableQualityLevels","level","unMute","Ads","displayContainer","manager","loader","cuePoints","safetyTimer","countdownTimer","ima","trigger","startSafetyTimer","clearSafetyTimer","setupIMA","setVpaidMode","ImaSdkSettings","VpaidMode","ENABLED","setLocale","AdDisplayContainer","requestAds","AdsLoader","AdsManagerLoadedEvent","Type","ADS_MANAGER_LOADED","onAdsManagerLoaded","AdErrorEvent","AD_ERROR","onAdError","AdsRequest","adTagUrl","tagUrl","linearAdSlotWidth","offsetWidth","linearAdSlotHeight","nonLinearAdSlotWidth","nonLinearAdSlotHeight","forceNonLinearFullSlot","setAdWillPlayMuted","getRemainingTime","AdsRenderingSettings","restoreCustomPlaybackStateOnAdBreakComplete","enablePreloading","getAdsManager","getCuePoints","cuePoint","seekElement","cuePercentage","AdEvent","onAdEvent","ad","getAd","LOADED","pollCountdown","isLinear","ALL_ADS_COMPLETED","loadAds","CONTENT_PAUSE_REQUESTED","pauseContent","CONTENT_RESUME_REQUESTED","resumeContent","STARTED","MIDPOINT","COMPLETE","IMPRESSION","CLICK","cancel","contentComplete","seekedTime","discardAdBreak","resize","ViewMode","NORMAL","_this9","initialize","init","adError","zIndex","_this10","destroy","_this11","handlers","_this12","base","AV_PUBLISHERID","AV_CHANNELID","AV_URL","cb","Date","now","AV_WIDTH","AV_HEIGHT","AV_CDIM2","insertElements","attribute","change","_sources$","_sources$$provider","tagName","crossorigin","Plyr","failed","jQuery","original","getProviderByUrl","searchParams","truthy","webkitShowPlaybackTargetPicker","isHidden","hiding","eventName","soft","unload","inputIsValid","fauxDuration","mozHasAudio","webkitAudioDecodedByteCount","audioTracks","prev","curr","abs","closest","states","webkitPresentationMode","inline","t"],"mappings":"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nE,SAAS,EACT+R,UAAU,EACVC,WAAW,GAIf/R,SACID,SAAS,EACTjK,IAAK,QAITkN,UACI,aAGA,OAEA,WACA,eACA,OACA,SACA,WACA,WACA,MACA,UACA,cAEJgB,UAAW,WAAY,UAAW,SAGlC5E,MACIwE,QAAS,UACTC,OAAQ,qBACRvG,KAAM,OACNqG,MAAO,QACPG,YAAa,sBACbO,KAAM,OACN2N,UAAW,8BACX1K,OAAQ,SACRqB,SAAU,WACVzL,YAAa,eACbuH,SAAU,WACVH,OAAQ,SACRP,KAAM,OACNkO,OAAQ,SACRC,eAAgB,kBAChBC,gBAAiB,mBACjBC,gBAAiB,mBACjBC,eAAgB,kBAChBC,WAAY,qBACZrO,SAAU,WACVD,SAAU,WACVuO,SAAU,2BACV5G,MAAO,QACP6G,OAAQ,SACRjV,QAAS,UACTmU,KAAM,OACNe,MAAO,QACPC,IAAK,MACLC,IAAK,MACLC,MAAO,QACPC,SAAU,WACV9S,QAAS,UACT+S,cAAe,KACfC,cACIC,KAAM,KACNC,KAAM,KACNC,KAAM,KACNC,IAAK,KACLC,IAAK,KACLC,IAAK,OAKbC,MACIC,OACIC,IAAK,yCACLC,OAAQ,yCACRrY,IAAK,2CAETsY,SACIF,IAAK,qCACLpY,IACI,yGAERuY,WACIH,IAAK,uDAKbI,WACIvP,KAAM,KACN/G,KAAM,KACNqG,MAAO,KACPC,QAAS,KACTC,OAAQ,KACRC,YAAa,KACbC,KAAM,KACNO,OAAQ,KACRL,SAAU,KACVC,WAAY,KACZ3I,IAAK,KACLE,QAAS,KACTkQ,MAAO,KACPpO,QAAS,KACTmU,KAAM,KACNpG,SAAU,MAIdtY,QAGI,QACA,WACA,UACA,UACA,UACA,UACA,iBACA,YACA,aACA,iBACA,aACA,eACA,OACA,QACA,QACA,UACA,SACA,UACA,aACA,YAGA,kBACA,iBACA,kBACA,mBACA,iBACA,iBACA,gBACA,QAGA,cACA,gBACA,mBAGA,YACA,kBACA,mBACA,YACA,cACA,cACA,iBACA,gBACA,YAKJyQ,WACIoQ,SAAU,6CACV/a,UAAW,QACXkK,UACIlK,UAAW,KACXtE,QAAS,m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","file":"plyr.min.js","sourcesContent":["// ==========================================================================\n// Type checking utils\n// ==========================================================================\n\nconst getConstructor = input => (input !== null && typeof input !== 'undefined' ? input.constructor : null);\n\nconst instanceOf = (input, constructor) => Boolean(input && constructor && input instanceof constructor);\n\nconst is = {\n object(input) {\n return getConstructor(input) === Object;\n },\n number(input) {\n return getConstructor(input) === Number && !Number.isNaN(input);\n },\n string(input) {\n return getConstructor(input) === String;\n },\n boolean(input) {\n return getConstructor(input) === Boolean;\n },\n function(input) {\n return getConstructor(input) === Function;\n },\n array(input) {\n return !is.nullOrUndefined(input) && Array.isArray(input);\n },\n weakMap(input) {\n return instanceOf(input, WeakMap);\n },\n nodeList(input) {\n return instanceOf(input, NodeList);\n },\n element(input) {\n return instanceOf(input, Element);\n },\n textNode(input) {\n return getConstructor(input) === Text;\n },\n event(input) {\n return instanceOf(input, Event);\n },\n cue(input) {\n return instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue);\n },\n track(input) {\n return instanceOf(input, TextTrack) || (!is.nullOrUndefined(input) && is.string(input.kind));\n },\n url(input) {\n return (\n !is.nullOrUndefined(input) &&\n /(ftp|http|https):\\/\\/(\\w+:{0,1}\\w*@)?(\\S+)(:[0-9]+)?(\\/|\\/([\\w#!:.?+=&%@!\\-/]))?/.test(input)\n );\n },\n nullOrUndefined(input) {\n return input === null || typeof input === 'undefined';\n },\n empty(input) {\n return (\n is.nullOrUndefined(input) ||\n ((is.string(input) || is.array(input) || is.nodeList(input)) && !input.length) ||\n (is.object(input) && !Object.keys(input).length)\n );\n },\n};\n\nexport default is;\n","// ==========================================================================\n// Event utils\n// ==========================================================================\n\nimport is from './is';\n\n// Check for passive event listener support\n// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md\n// https://www.youtube.com/watch?v=NPM6172J22g\nconst supportsPassiveListeners = (() => {\n // Test via a getter in the options object to see if the passive property is accessed\n let supported = false;\n try {\n const options = Object.defineProperty({}, 'passive', {\n get() {\n supported = true;\n return null;\n },\n });\n window.addEventListener('test', null, options);\n window.removeEventListener('test', null, options);\n } catch (e) {\n // Do nothing\n }\n\n return supported;\n})();\n\n// Toggle event listener\nexport function toggleListener(element, event, callback, toggle = false, passive = true, capture = false) {\n // Bail if no element, event, or callback\n if (!element || !('addEventListener' in element) || is.empty(event) || !is.function(callback)) {\n return;\n }\n\n // Allow multiple events\n const events = event.split(' ');\n\n // Build options\n // Default to just the capture boolean for browsers with no passive listener support\n let options = capture;\n\n // If passive events listeners are supported\n if (supportsPassiveListeners) {\n options = {\n // Whether the listener can be passive (i.e. default never prevented)\n passive,\n // Whether the listener is a capturing listener or not\n capture,\n };\n }\n\n // If a single node is passed, bind the event listener\n events.forEach(type => {\n if (this && this.eventListeners && toggle) {\n // Cache event listener\n this.eventListeners.push({ element, type, callback, options });\n }\n\n element[toggle ? 'addEventListener' : 'removeEventListener'](type, callback, options);\n });\n}\n\n// Bind event handler\nexport function on(element, events = '', callback, passive = true, capture = false) {\n toggleListener.call(this, element, events, callback, true, passive, capture);\n}\n\n// Unbind event handler\nexport function off(element, events = '', callback, passive = true, capture = false) {\n toggleListener.call(this, element, events, callback, false, passive, capture);\n}\n\n// Bind once-only event handler\nexport function once(element, events = '', callback, passive = true, capture = false) {\n function onceCallback(...args) {\n off(element, events, onceCallback, passive, capture);\n callback.apply(this, args);\n }\n\n toggleListener.call(this, element, events, onceCallback, true, passive, capture);\n}\n\n// Trigger event\nexport function triggerEvent(element, type = '', bubbles = false, detail = {}) {\n // Bail if no element\n if (!is.element(element) || is.empty(type)) {\n return;\n }\n\n // Create and dispatch the event\n const event = new CustomEvent(type, {\n bubbles,\n detail: Object.assign({}, detail, {\n plyr: this,\n }),\n });\n\n // Dispatch the event\n element.dispatchEvent(event);\n}\n\n// Unbind all cached event listeners\nexport function unbindListeners() {\n if (this && this.eventListeners) {\n this.eventListeners.forEach(item => {\n const { element, type, callback, options } = item;\n element.removeEventListener(type, callback, options);\n });\n\n this.eventListeners = [];\n }\n}\n\n// Run method when / if player is ready\nexport function ready() {\n return new Promise(\n resolve => (this.ready ? setTimeout(resolve, 0) : on.call(this, this.elements.container, 'ready', resolve)),\n ).then(() => {});\n}\n","// ==========================================================================\n// Element utils\n// ==========================================================================\n\nimport { toggleListener } from './events';\nimport is from './is';\n\n// Wrap an element\nexport function wrap(elements, wrapper) {\n // Convert `elements` to an array, if necessary.\n const targets = elements.length ? elements : [elements];\n\n // Loops backwards to prevent having to clone the wrapper on the\n // first element (see `child` below).\n Array.from(targets)\n .reverse()\n .forEach((element, index) => {\n const child = index > 0 ? wrapper.cloneNode(true) : wrapper;\n\n // Cache the current parent and sibling.\n const parent = element.parentNode;\n const sibling = element.nextSibling;\n\n // Wrap the element (is automatically removed from its current\n // parent).\n child.appendChild(element);\n\n // If the element had a sibling, insert the wrapper before\n // the sibling to maintain the HTML structure; otherwise, just\n // append it to the parent.\n if (sibling) {\n parent.insertBefore(child, sibling);\n } else {\n parent.appendChild(child);\n }\n });\n}\n\n// Set attributes\nexport function setAttributes(element, attributes) {\n if (!is.element(element) || is.empty(attributes)) {\n return;\n }\n\n // Assume null and undefined attributes should be left out,\n // Setting them would otherwise convert them to \"null\" and \"undefined\"\n Object.entries(attributes)\n .filter(([, value]) => !is.nullOrUndefined(value))\n .forEach(([key, value]) => element.setAttribute(key, value));\n}\n\n// Create a DocumentFragment\nexport function createElement(type, attributes, text) {\n // Create a new <element>\n const element = document.createElement(type);\n\n // Set all passed attributes\n if (is.object(attributes)) {\n setAttributes(element, attributes);\n }\n\n // Add text node\n if (is.string(text)) {\n element.innerText = text;\n }\n\n // Return built element\n return element;\n}\n\n// Inaert an element after another\nexport function insertAfter(element, target) {\n if (!is.element(element) || !is.element(target)) {\n return;\n }\n\n target.parentNode.insertBefore(element, target.nextSibling);\n}\n\n// Insert a DocumentFragment\nexport function insertElement(type, parent, attributes, text) {\n if (!is.element(parent)) {\n return;\n }\n\n parent.appendChild(createElement(type, attributes, text));\n}\n\n// Remove element(s)\nexport function removeElement(element) {\n if (is.nodeList(element) || is.array(element)) {\n Array.from(element).forEach(removeElement);\n return;\n }\n\n if (!is.element(element) || !is.element(element.parentNode)) {\n return;\n }\n\n element.parentNode.removeChild(element);\n}\n\n// Remove all child elements\nexport function emptyElement(element) {\n if (!is.element(element)) {\n return;\n }\n\n let { length } = element.childNodes;\n\n while (length > 0) {\n element.removeChild(element.lastChild);\n length -= 1;\n }\n}\n\n// Replace element\nexport function replaceElement(newChild, oldChild) {\n if (!is.element(oldChild) || !is.element(oldChild.parentNode) || !is.element(newChild)) {\n return null;\n }\n\n oldChild.parentNode.replaceChild(newChild, oldChild);\n\n return newChild;\n}\n\n// Get an attribute object from a string selector\nexport function getAttributesFromSelector(sel, existingAttributes) {\n // For example:\n // '.test' to { class: 'test' }\n // '#test' to { id: 'test' }\n // '[data-test=\"test\"]' to { 'data-test': 'test' }\n\n if (!is.string(sel) || is.empty(sel)) {\n return {};\n }\n\n const attributes = {};\n const existing = existingAttributes;\n\n sel.split(',').forEach(s => {\n // Remove whitespace\n const selector = s.trim();\n const className = selector.replace('.', '');\n const stripped = selector.replace(/[[\\]]/g, '');\n\n // Get the parts and value\n const parts = stripped.split('=');\n const key = parts[0];\n const value = parts.length > 1 ? parts[1].replace(/[\"']/g, '') : '';\n\n // Get the first character\n const start = selector.charAt(0);\n\n switch (start) {\n case '.':\n // Add to existing classname\n if (is.object(existing) && is.string(existing.class)) {\n existing.class += ` ${className}`;\n }\n\n attributes.class = className;\n break;\n\n case '#':\n // ID selector\n attributes.id = selector.replace('#', '');\n break;\n\n case '[':\n // Attribute selector\n attributes[key] = value;\n\n break;\n\n default:\n break;\n }\n });\n\n return attributes;\n}\n\n// Toggle hidden\nexport function toggleHidden(element, hidden) {\n if (!is.element(element)) {\n return;\n }\n\n let hide = hidden;\n\n if (!is.boolean(hide)) {\n hide = !element.hasAttribute('hidden');\n }\n\n if (hide) {\n element.setAttribute('hidden', '');\n } else {\n element.removeAttribute('hidden');\n }\n}\n\n// Mirror Element.classList.toggle, with IE compatibility for \"force\" argument\nexport function toggleClass(element, className, force) {\n if (is.element(element)) {\n let method = 'toggle';\n if (typeof force !== 'undefined') {\n method = force ? 'add' : 'remove';\n }\n\n element.classList[method](className);\n return element.classList.contains(className);\n }\n\n return null;\n}\n\n// Has class name\nexport function hasClass(element, className) {\n return is.element(element) && element.classList.contains(className);\n}\n\n// Element matches selector\nexport function matches(element, selector) {\n const prototype = { Element };\n\n function match() {\n return Array.from(document.querySelectorAll(selector)).includes(this);\n }\n\n const matches =\n prototype.matches ||\n prototype.webkitMatchesSelector ||\n prototype.mozMatchesSelector ||\n prototype.msMatchesSelector ||\n match;\n\n return matches.call(element, selector);\n}\n\n// Find all elements\nexport function getElements(selector) {\n return this.elements.container.querySelectorAll(selector);\n}\n\n// Find a single element\nexport function getElement(selector) {\n return this.elements.container.querySelector(selector);\n}\n\n// Get the focused element\nexport function getFocusElement() {\n let focused = document.activeElement;\n\n if (!focused || focused === document.body) {\n focused = null;\n } else {\n focused = document.querySelector(':focus');\n }\n\n return focused;\n}\n\n// Trap focus inside container\nexport function trapFocus(element = null, toggle = false) {\n if (!is.element(element)) {\n return;\n }\n\n const focusable = getElements.call(this, 'button:not(:disabled), input:not(:disabled), [tabindex]');\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n const trap = event => {\n // Bail if not tab key or not fullscreen\n if (event.key !== 'Tab' || event.keyCode !== 9) {\n return;\n }\n\n // Get the current focused element\n const focused = getFocusElement();\n\n if (focused === last && !event.shiftKey) {\n // Move focus to first element that can be tabbed if Shift isn't used\n first.focus();\n event.preventDefault();\n } else if (focused === first && event.shiftKey) {\n // Move focus to last element that can be tabbed if Shift is used\n last.focus();\n event.preventDefault();\n }\n };\n\n toggleListener.call(this, this.elements.container, 'keydown', trap, toggle, false);\n}\n","// ==========================================================================\n// Animation utils\n// ==========================================================================\n\nimport { toggleHidden } from './elements';\nimport is from './is';\n\nexport const transitionEndEvent = (() => {\n const element = document.createElement('span');\n\n const events = {\n WebkitTransition: 'webkitTransitionEnd',\n MozTransition: 'transitionend',\n OTransition: 'oTransitionEnd otransitionend',\n transition: 'transitionend',\n };\n\n const type = Object.keys(events).find(event => element.style[event] !== undefined);\n\n return is.string(type) ? events[type] : false;\n})();\n\n// Force repaint of element\nexport function repaint(element) {\n setTimeout(() => {\n toggleHidden(element, true);\n element.offsetHeight; // eslint-disable-line\n toggleHidden(element, false);\n }, 0);\n}\n","// ==========================================================================\n// Browser sniffing\n// Unfortunately, due to mixed support, UA sniffing is required\n// ==========================================================================\n\nconst browser = {\n isIE: /* @cc_on!@ */ false || !!document.documentMode,\n isWebkit: 'WebkitAppearance' in document.documentElement.style && !/Edge/.test(navigator.userAgent),\n isIPhone: /(iPhone|iPod)/gi.test(navigator.platform),\n isIos: /(iPad|iPhone|iPod)/gi.test(navigator.platform),\n};\n\nexport default browser;\n","// ==========================================================================\n// Plyr support checks\n// ==========================================================================\n\nimport { transitionEndEvent } from './utils/animation';\nimport browser from './utils/browser';\nimport { createElement } from './utils/elements';\nimport is from './utils/is';\n\n// Default codecs for checking mimetype support\nconst defaultCodecs = {\n 'audio/ogg': 'vorbis',\n 'audio/wav': '1',\n 'video/webm': 'vp8, vorbis',\n 'video/mp4': 'avc1.42E01E, mp4a.40.2',\n 'video/ogg': 'theora',\n};\n\n// Check for feature support\nconst support = {\n // Basic support\n audio: 'canPlayType' in document.createElement('audio'),\n video: 'canPlayType' in document.createElement('video'),\n\n // Check for support\n // Basic functionality vs full UI\n check(type, provider, playsinline) {\n const canPlayInline = browser.isIPhone && playsinline && support.playsinline;\n const api = support[type] || provider !== 'html5';\n const ui = api && support.rangeInput && (type !== 'video' || !browser.isIPhone || canPlayInline);\n\n return {\n api,\n ui,\n };\n },\n\n // Picture-in-picture support\n // Safari only currently\n pip: (() => !browser.isIPhone && is.function(createElement('video').webkitSetPresentationMode))(),\n\n // Airplay support\n // Safari only currently\n airplay: is.function(window.WebKitPlaybackTargetAvailabilityEvent),\n\n // Inline playback support\n // https://webkit.org/blog/6784/new-video-policies-for-ios/\n playsinline: 'playsInline' in document.createElement('video'),\n\n // Check for mime type support against a player instance\n // Credits: http://diveintohtml5.info/everything.html\n // Related: http://www.leanbackplayer.com/test/h5mt.html\n mime(inputType) {\n const [mediaType] = inputType.split('/');\n if (!this.isHTML5 || mediaType !== this.type) {\n return false;\n }\n\n let type;\n if (inputType && inputType.includes('codecs=')) {\n // Use input directly\n type = inputType;\n } else if (inputType === 'audio/mpeg') {\n // Skip codec\n type = 'audio/mpeg;';\n } else if (inputType in defaultCodecs) {\n // Use codec\n type = `${inputType}; codecs=\"${defaultCodecs[inputType]}\"`;\n }\n\n try {\n return Boolean(type && this.media.canPlayType(type).replace(/no/, ''));\n } catch (err) {\n return false;\n }\n },\n\n // Check for textTracks support\n textTracks: 'textTracks' in document.createElement('video'),\n\n // <input type=\"range\"> Sliders\n rangeInput: (() => {\n const range = document.createElement('input');\n range.type = 'range';\n return range.type === 'range';\n })(),\n\n // Touch\n // NOTE: Remember a device can be mouse + touch enabled so we check on first touch event\n touch: 'ontouchstart' in document.documentElement,\n\n // Detect transitions support\n transitions: transitionEndEvent !== false,\n\n // Reduced motion iOS & MacOS setting\n // https://webkit.org/blog/7551/responsive-design-for-motion/\n reducedMotion: 'matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches,\n};\n\nexport default support;\n","// ==========================================================================\n// Plyr HTML5 helpers\n// ==========================================================================\n\nimport support from './support';\nimport { removeElement } from './utils/elements';\nimport { triggerEvent } from './utils/events';\n\nconst html5 = {\n getSources() {\n if (!this.isHTML5) {\n return [];\n }\n\n const sources = Array.from(this.media.querySelectorAll('source'));\n\n // Filter out unsupported sources\n return sources.filter(source => support.mime.call(this, source.getAttribute('type')));\n },\n\n // Get quality levels\n getQualityOptions() {\n // Get sizes from <source> elements\n return html5.getSources\n .call(this)\n .map(source => Number(source.getAttribute('size')))\n .filter(Boolean);\n },\n\n extend() {\n if (!this.isHTML5) {\n return;\n }\n\n const player = this;\n\n // Quality\n Object.defineProperty(player.media, 'quality', {\n get() {\n // Get sources\n const sources = html5.getSources.call(player);\n const [source] = sources.filter(source => source.getAttribute('src') === player.source);\n\n // Return size, if match is found\n return source && Number(source.getAttribute('size'));\n },\n set(input) {\n // Get sources\n const sources = html5.getSources.call(player);\n\n // Get first match for requested size\n const source = sources.find(source => Number(source.getAttribute('size')) === input);\n\n // No matching source found\n if (!source) {\n return;\n }\n\n // Get current state\n const { currentTime, playing } = player;\n\n // Set new source\n player.media.src = source.getAttribute('src');\n\n // Restore time\n const onLoadedMetaData = () => {\n player.currentTime = currentTime;\n };\n player.once('loadedmetadata', onLoadedMetaData);\n\n // Load new source\n player.media.load();\n\n // Resume playing\n if (playing) {\n player.play();\n }\n\n // Trigger change event\n triggerEvent.call(player, player.media, 'qualitychange', false, {\n quality: input,\n });\n },\n });\n },\n\n // Cancel current network requests\n // See https://github.com/sampotts/plyr/issues/174\n cancelRequests() {\n if (!this.isHTML5) {\n return;\n }\n\n // Remove child sources\n removeElement(html5.getSources.call(this));\n\n // Set blank video src attribute\n // This is to prevent a MEDIA_ERR_SRC_NOT_SUPPORTED error\n // Info: http://stackoverflow.com/questions/32231579/how-to-properly-dispose-of-an-html5-video-and-close-socket-or-connection\n this.media.setAttribute('src', this.config.blankVideo);\n\n // Load the new empty source\n // This will cancel existing requests\n // See https://github.com/sampotts/plyr/issues/174\n this.media.load();\n\n // Debugging\n this.debug.log('Cancelled network requests');\n },\n};\n\nexport default html5;\n","// ==========================================================================\n// Object utils\n// ==========================================================================\n\nimport is from './is';\n\n// Clone nested objects\nexport function cloneDeep(object) {\n return JSON.parse(JSON.stringify(object));\n}\n\n// Get a nested value in an object\nexport function getDeep(object, path) {\n return path.split('.').reduce((obj, key) => obj && obj[key], object);\n}\n\n// Deep extend destination object with N more objects\nexport function extend(target = {}, ...sources) {\n if (!sources.length) {\n return target;\n }\n\n const source = sources.shift();\n\n if (!is.object(source)) {\n return target;\n }\n\n Object.keys(source).forEach(key => {\n if (is.object(source[key])) {\n if (!Object.keys(target).includes(key)) {\n Object.assign(target, { [key]: {} });\n }\n\n extend(target[key], source[key]);\n } else {\n Object.assign(target, { [key]: source[key] });\n }\n });\n\n return extend(target, ...sources);\n}\n","// ==========================================================================\n// String utils\n// ==========================================================================\n\nimport is from './is';\n\n// Generate a random ID\nexport function generateId(prefix) {\n return `${prefix}-${Math.floor(Math.random() * 10000)}`;\n}\n\n// Format string\nexport function format(input, ...args) {\n if (is.empty(input)) {\n return input;\n }\n\n return input.toString().replace(/{(\\d+)}/g, (match, i) => args[i].toString());\n}\n\n// Get percentage\nexport function getPercentage(current, max) {\n if (current === 0 || max === 0 || Number.isNaN(current) || Number.isNaN(max)) {\n return 0;\n }\n\n return (current / max * 100).toFixed(2);\n}\n\n// Replace all occurances of a string in a string\nexport function replaceAll(input = '', find = '', replace = '') {\n return input.replace(\n new RegExp(find.toString().replace(/([.*+?^=!:${}()|[\\]/\\\\])/g, '\\\\$1'), 'g'),\n replace.toString(),\n );\n}\n\n// Convert to title case\nexport function toTitleCase(input = '') {\n return input.toString().replace(/\\w\\S*/g, text => text.charAt(0).toUpperCase() + text.substr(1).toLowerCase());\n}\n\n// Convert string to pascalCase\nexport function toPascalCase(input = '') {\n let string = input.toString();\n\n // Convert kebab case\n string = replaceAll(string, '-', ' ');\n\n // Convert snake case\n string = replaceAll(string, '_', ' ');\n\n // Convert to title case\n string = toTitleCase(string);\n\n // Convert to pascal case\n return replaceAll(string, ' ', '');\n}\n\n// Convert string to pascalCase\nexport function toCamelCase(input = '') {\n let string = input.toString();\n\n // Convert to pascal case\n string = toPascalCase(string);\n\n // Convert first character to lowercase\n return string.charAt(0).toLowerCase() + string.slice(1);\n}\n\n// Remove HTML from a string\nexport function stripHTML(source) {\n const fragment = document.createDocumentFragment();\n const element = document.createElement('div');\n fragment.appendChild(element);\n element.innerHTML = source;\n return fragment.firstChild.innerText;\n}\n\n// Like outerHTML, but also works for DocumentFragment\nexport function getHTML(element) {\n const wrapper = document.createElement('div');\n wrapper.appendChild(element);\n return wrapper.innerHTML;\n}\n","// ==========================================================================\n// Plyr internationalization\n// ==========================================================================\n\nimport is from './utils/is';\nimport { getDeep } from './utils/objects';\nimport { replaceAll } from './utils/strings';\n\nconst i18n = {\n get(key = '', config = {}) {\n if (is.empty(key) || is.empty(config)) {\n return '';\n }\n\n let string = getDeep(config.i18n, key);\n\n if (is.empty(string)) {\n return '';\n }\n\n const replace = {\n '{seektime}': config.seekTime,\n '{title}': config.title,\n };\n\n Object.entries(replace).forEach(([key, value]) => {\n string = replaceAll(string, key, value);\n });\n\n return string;\n },\n};\n\nexport default i18n;\n","// ==========================================================================\n// Array utils\n// ==========================================================================\n\nimport is from './is';\n\n// Remove duplicates in an array\nexport function dedupe(array) {\n if (!is.array(array)) {\n return array;\n }\n\n return array.filter((item, index) => array.indexOf(item) === index);\n}\n\n// Get the closest value in an array\nexport function closest(array, value) {\n if (!is.array(array) || !array.length) {\n return null;\n }\n\n return array.reduce((prev, curr) => (Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev));\n}\n","// ==========================================================================\n// Plyr storage\n// ==========================================================================\n\nimport is from './utils/is';\nimport { extend } from './utils/objects';\n\nclass Storage {\n constructor(player) {\n this.enabled = player.config.storage.enabled;\n this.key = player.config.storage.key;\n }\n\n // Check for actual support (see if we can use it)\n static get supported() {\n try {\n if (!('localStorage' in window)) {\n return false;\n }\n\n const test = '___test';\n\n // Try to use it (it might be disabled, e.g. user is in private mode)\n // see: https://github.com/sampotts/plyr/issues/131\n window.localStorage.setItem(test, test);\n window.localStorage.removeItem(test);\n\n return true;\n } catch (e) {\n return false;\n }\n }\n\n get(key) {\n if (!Storage.supported || !this.enabled) {\n return null;\n }\n\n const store = window.localStorage.getItem(this.key);\n\n if (is.empty(store)) {\n return null;\n }\n\n const json = JSON.parse(store);\n\n return is.string(key) && key.length ? json[key] : json;\n }\n\n set(object) {\n // Bail if we don't have localStorage support or it's disabled\n if (!Storage.supported || !this.enabled) {\n return;\n }\n\n // Can only store objectst\n if (!is.object(object)) {\n return;\n }\n\n // Get current storage\n let storage = this.get();\n\n // Default to empty object\n if (is.empty(storage)) {\n storage = {};\n }\n\n // Update the working copy of the values\n extend(storage, object);\n\n // Update storage\n window.localStorage.setItem(this.key, JSON.stringify(storage));\n }\n}\n\nexport default Storage;\n","// ==========================================================================\n// Fetch wrapper\n// Using XHR to avoid issues with older browsers\n// ==========================================================================\n\nexport default function fetch(url, responseType = 'text') {\n return new Promise((resolve, reject) => {\n try {\n const request = new XMLHttpRequest();\n\n // Check for CORS support\n if (!('withCredentials' in request)) {\n return;\n }\n\n request.addEventListener('load', () => {\n if (responseType === 'text') {\n try {\n resolve(JSON.parse(request.responseText));\n } catch (e) {\n resolve(request.responseText);\n }\n } else {\n resolve(request.response);\n }\n });\n\n request.addEventListener('error', () => {\n throw new Error(request.status);\n });\n\n request.open('GET', url, true);\n\n // Set the required response type\n request.responseType = responseType;\n\n request.send();\n } catch (e) {\n reject(e);\n }\n });\n}\n","// ==========================================================================\n// Sprite loader\n// ==========================================================================\n\nimport Storage from './../storage';\nimport fetch from './fetch';\nimport is from './is';\n\n// Load an external SVG sprite\nexport default function loadSprite(url, id) {\n if (!is.string(url)) {\n return;\n }\n\n const prefix = 'cache';\n const hasId = is.string(id);\n let isCached = false;\n\n const exists = () => document.getElementById(id) !== null;\n\n const update = (container, data) => {\n container.innerHTML = data;\n\n // Check again incase of race condition\n if (hasId && exists()) {\n return;\n }\n\n // Inject the SVG to the body\n document.body.insertAdjacentElement('afterbegin', container);\n };\n\n // Only load once if ID set\n if (!hasId || !exists()) {\n const useStorage = Storage.supported;\n\n // Create container\n const container = document.createElement('div');\n container.setAttribute('hidden', '');\n\n if (hasId) {\n container.setAttribute('id', id);\n }\n\n // Check in cache\n if (useStorage) {\n const cached = window.localStorage.getItem(`${prefix}-${id}`);\n isCached = cached !== null;\n\n if (isCached) {\n const data = JSON.parse(cached);\n update(container, data.content);\n }\n }\n\n // Get the sprite\n fetch(url)\n .then(result => {\n if (is.empty(result)) {\n return;\n }\n\n if (useStorage) {\n window.localStorage.setItem(\n `${prefix}-${id}`,\n JSON.stringify({\n content: result,\n }),\n );\n }\n\n update(container, result);\n })\n .catch(() => {});\n }\n}\n","// ==========================================================================\n// Time utils\n// ==========================================================================\n\nimport is from './is';\n\n// Time helpers\nexport const getHours = value => parseInt((value / 60 / 60) % 60, 10);\nexport const getMinutes = value => parseInt((value / 60) % 60, 10);\nexport const getSeconds = value => parseInt(value % 60, 10);\n\n// Format time to UI friendly string\nexport function formatTime(time = 0, displayHours = false, inverted = false) {\n // Bail if the value isn't a number\n if (!is.number(time)) {\n return formatTime(null, displayHours, inverted);\n }\n\n // Format time component to add leading zero\n const format = value => `0${value}`.slice(-2);\n\n // Breakdown to hours, mins, secs\n let hours = getHours(time);\n const mins = getMinutes(time);\n const secs = getSeconds(time);\n\n // Do we need to display hours?\n if (displayHours || hours > 0) {\n hours = `${hours}:`;\n } else {\n hours = '';\n }\n\n // Render\n return `${inverted && time > 0 ? '-' : ''}${hours}${format(mins)}:${format(secs)}`;\n}\n","// ==========================================================================\n// Plyr controls\n// ==========================================================================\n\nimport captions from './captions';\nimport html5 from './html5';\nimport i18n from './i18n';\nimport support from './support';\nimport { repaint, transitionEndEvent } from './utils/animation';\nimport { dedupe } from './utils/arrays';\nimport browser from './utils/browser';\nimport { createElement, emptyElement, getAttributesFromSelector, getElement, getElements, hasClass, matches, removeElement, setAttributes, toggleClass, toggleHidden } from './utils/elements';\nimport { off, on } from './utils/events';\nimport is from './utils/is';\nimport loadSprite from './utils/loadSprite';\nimport { extend } from './utils/objects';\nimport { getPercentage, replaceAll, toCamelCase, toTitleCase } from './utils/strings';\nimport { formatTime, getHours } from './utils/time';\n\n// TODO: Don't export a massive object - break down and create class\nconst controls = {\n // Get icon URL\n getIconUrl() {\n const url = new URL(this.config.iconUrl, window.location);\n const cors = url.host !== window.location.host || (browser.isIE && !window.svg4everybody);\n\n return {\n url: this.config.iconUrl,\n cors,\n };\n },\n\n // Find the UI controls\n findElements() {\n try {\n this.elements.controls = getElement.call(this, this.config.selectors.controls.wrapper);\n\n // Buttons\n this.elements.buttons = {\n play: getElements.call(this, this.config.selectors.buttons.play),\n pause: getElement.call(this, this.config.selectors.buttons.pause),\n restart: getElement.call(this, this.config.selectors.buttons.restart),\n rewind: getElement.call(this, this.config.selectors.buttons.rewind),\n fastForward: getElement.call(this, this.config.selectors.buttons.fastForward),\n mute: getElement.call(this, this.config.selectors.buttons.mute),\n pip: getElement.call(this, this.config.selectors.buttons.pip),\n airplay: getElement.call(this, this.config.selectors.buttons.airplay),\n settings: getElement.call(this, this.config.selectors.buttons.settings),\n captions: getElement.call(this, this.config.selectors.buttons.captions),\n fullscreen: getElement.call(this, this.config.selectors.buttons.fullscreen),\n };\n\n // Progress\n this.elements.progress = getElement.call(this, this.config.selectors.progress);\n\n // Inputs\n this.elements.inputs = {\n seek: getElement.call(this, this.config.selectors.inputs.seek),\n volume: getElement.call(this, this.config.selectors.inputs.volume),\n };\n\n // Display\n this.elements.display = {\n buffer: getElement.call(this, this.config.selectors.display.buffer),\n currentTime: getElement.call(this, this.config.selectors.display.currentTime),\n duration: getElement.call(this, this.config.selectors.display.duration),\n };\n\n // Seek tooltip\n if (is.element(this.elements.progress)) {\n this.elements.display.seekTooltip = this.elements.progress.querySelector(\n `.${this.config.classNames.tooltip}`,\n );\n }\n\n return true;\n } catch (error) {\n // Log it\n this.debug.warn('It looks like there is a problem with your custom controls HTML', error);\n\n // Restore native video controls\n this.toggleNativeControls(true);\n\n return false;\n }\n },\n\n // Create <svg> icon\n createIcon(type, attributes) {\n const namespace = 'http://www.w3.org/2000/svg';\n const iconUrl = controls.getIconUrl.call(this);\n const iconPath = `${!iconUrl.cors ? iconUrl.url : ''}#${this.config.iconPrefix}`;\n\n // Create <svg>\n const icon = document.createElementNS(namespace, 'svg');\n setAttributes(\n icon,\n extend(attributes, {\n role: 'presentation',\n focusable: 'false',\n }),\n );\n\n // Create the <use> to reference sprite\n const use = document.createElementNS(namespace, 'use');\n const path = `${iconPath}-${type}`;\n\n // Set `href` attributes\n // https://github.com/sampotts/plyr/issues/460\n // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href\n if ('href' in use) {\n use.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);\n } else {\n use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', path);\n }\n\n // Add <use> to <svg>\n icon.appendChild(use);\n\n return icon;\n },\n\n // Create hidden text label\n createLabel(type, attr = {}) {\n // Skip i18n for abbreviations and brand names\n const universals = {\n pip: 'PIP',\n airplay: 'AirPlay',\n };\n const text = universals[type] || i18n.get(type, this.config);\n\n const attributes = Object.assign({}, attr, {\n class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' '),\n });\n return createElement('span', attributes, text);\n },\n\n // Create a badge\n createBadge(text) {\n if (is.empty(text)) {\n return null;\n }\n\n const badge = createElement('span', {\n class: this.config.classNames.menu.value,\n });\n\n badge.appendChild(\n createElement(\n 'span',\n {\n class: this.config.classNames.menu.badge,\n },\n text,\n ),\n );\n\n return badge;\n },\n\n // Create a <button>\n createButton(buttonType, attr) {\n const button = createElement('button');\n const attributes = Object.assign({}, attr);\n let type = toCamelCase(buttonType);\n\n let toggle = false;\n let label;\n let icon;\n let labelPressed;\n let iconPressed;\n\n if (!('type' in attributes)) {\n attributes.type = 'button';\n }\n\n if ('class' in attributes) {\n if (attributes.class.includes(this.config.classNames.control)) {\n attributes.class += ` ${this.config.classNames.control}`;\n }\n } else {\n attributes.class = this.config.classNames.control;\n }\n\n // Large play button\n switch (buttonType) {\n case 'play':\n toggle = true;\n label = 'play';\n labelPressed = 'pause';\n icon = 'play';\n iconPressed = 'pause';\n break;\n\n case 'mute':\n toggle = true;\n label = 'mute';\n labelPressed = 'unmute';\n icon = 'volume';\n iconPressed = 'muted';\n break;\n\n case 'captions':\n toggle = true;\n label = 'enableCaptions';\n labelPressed = 'disableCaptions';\n icon = 'captions-off';\n iconPressed = 'captions-on';\n break;\n\n case 'fullscreen':\n toggle = true;\n label = 'enterFullscreen';\n labelPressed = 'exitFullscreen';\n icon = 'enter-fullscreen';\n iconPressed = 'exit-fullscreen';\n break;\n\n case 'play-large':\n attributes.class += ` ${this.config.classNames.control}--overlaid`;\n type = 'play';\n label = 'play';\n icon = 'play';\n break;\n\n default:\n label = type;\n icon = buttonType;\n }\n\n // Setup toggle icon and labels\n if (toggle) {\n // Icon\n button.appendChild(controls.createIcon.call(this, iconPressed, { class: 'icon--pressed' }));\n button.appendChild(controls.createIcon.call(this, icon, { class: 'icon--not-pressed' }));\n\n // Label/Tooltip\n button.appendChild(controls.createLabel.call(this, labelPressed, { class: 'label--pressed' }));\n button.appendChild(controls.createLabel.call(this, label, { class: 'label--not-pressed' }));\n } else {\n button.appendChild(controls.createIcon.call(this, icon));\n button.appendChild(controls.createLabel.call(this, label));\n }\n\n // Merge attributes\n extend(attributes, getAttributesFromSelector(this.config.selectors.buttons[type], attributes));\n\n setAttributes(button, attributes);\n\n // We have multiple play buttons\n if (type === 'play') {\n if (!is.array(this.elements.buttons[type])) {\n this.elements.buttons[type] = [];\n }\n\n this.elements.buttons[type].push(button);\n } else {\n this.elements.buttons[type] = button;\n }\n\n // Toggle classname when pressed property is set\n const className = this.config.classNames.controlPressed;\n Object.defineProperty(button, 'pressed', {\n enumerable: true,\n get() {\n return hasClass(button, className);\n },\n set(pressed = false) {\n toggleClass(button, className, pressed);\n },\n });\n\n return button;\n },\n\n // Create an <input type='range'>\n createRange(type, attributes) {\n // Seek input\n const input = createElement(\n 'input',\n extend(\n getAttributesFromSelector(this.config.selectors.inputs[type]),\n {\n type: 'range',\n min: 0,\n max: 100,\n step: 0.01,\n value: 0,\n autocomplete: 'off',\n // A11y fixes for https://github.com/sampotts/plyr/issues/905\n role: 'slider',\n 'aria-label': i18n.get(type, this.config),\n 'aria-valuemin': 0,\n 'aria-valuemax': 100,\n 'aria-valuenow': 0,\n },\n attributes,\n ),\n );\n\n this.elements.inputs[type] = input;\n\n // Set the fill for webkit now\n controls.updateRangeFill.call(this, input);\n\n return input;\n },\n\n // Create a <progress>\n createProgress(type, attributes) {\n const progress = createElement(\n 'progress',\n extend(\n getAttributesFromSelector(this.config.selectors.display[type]),\n {\n min: 0,\n max: 100,\n value: 0,\n role: 'presentation',\n 'aria-hidden': true,\n },\n attributes,\n ),\n );\n\n // Create the label inside\n if (type !== 'volume') {\n progress.appendChild(createElement('span', null, '0'));\n\n const suffixKey = {\n played: 'played',\n buffer: 'buffered',\n }[type];\n const suffix = suffixKey ? i18n.get(suffixKey, this.config) : '';\n\n progress.innerText = `% ${suffix.toLowerCase()}`;\n }\n\n this.elements.display[type] = progress;\n\n return progress;\n },\n\n // Create time display\n createTime(type) {\n const attributes = getAttributesFromSelector(this.config.selectors.display[type]);\n\n const container = createElement(\n 'div',\n extend(attributes, {\n class: `${this.config.classNames.display.time} ${attributes.class ? attributes.class : ''}`.trim(),\n 'aria-label': i18n.get(type, this.config),\n }),\n '00:00',\n );\n\n // Reference for updates\n this.elements.display[type] = container;\n\n return container;\n },\n\n // Create a settings menu item\n createMenuItem({ value, list, type, title, badge = null, checked = false }) {\n const attributes = getAttributesFromSelector(this.config.selectors.inputs[type]);\n\n const item = createElement(\n 'button',\n extend(attributes, {\n type: 'button',\n role: 'menuitemradio',\n class: `${this.config.classNames.control} ${attributes.class ? attributes.class : ''}`.trim(),\n value,\n 'aria-checked': checked,\n })\n );\n\n // We have to set as HTML incase of special characters\n item.innerHTML = title;\n\n if (is.element(badge)) {\n item.appendChild(badge);\n }\n\n Object.defineProperty(item, 'checked', {\n enumerable: true,\n get() {\n return item.getAttribute('aria-checked') === 'true';\n },\n set(checked) {\n // Ensure exclusivity\n if (checked) {\n Array.from(item.parentNode.children)\n .filter(node => matches(node, '[role=\"menuitemradio\"]'))\n .forEach(node => node.setAttribute('aria-checked', 'false'));\n }\n\n item.setAttribute('aria-checked', checked ? 'true' : 'false');\n },\n });\n\n list.appendChild(item);\n },\n\n // Format a time for display\n formatTime(time = 0, inverted = false) {\n // Bail if the value isn't a number\n if (!is.number(time)) {\n return time;\n }\n\n // Always display hours if duration is over an hour\n const forceHours = getHours(this.duration) > 0;\n\n return formatTime(time, forceHours, inverted);\n },\n\n // Update the displayed time\n updateTimeDisplay(target = null, time = 0, inverted = false) {\n // Bail if there's no element to display or the value isn't a number\n if (!is.element(target) || !is.number(time)) {\n return;\n }\n\n // eslint-disable-next-line no-param-reassign\n target.innerText = controls.formatTime(time, inverted);\n },\n\n // Update volume UI and storage\n updateVolume() {\n if (!this.supported.ui) {\n return;\n }\n\n // Update range\n if (is.element(this.elements.inputs.volume)) {\n controls.setRange.call(this, this.elements.inputs.volume, this.muted ? 0 : this.volume);\n }\n\n // Update mute state\n if (is.element(this.elements.buttons.mute)) {\n this.elements.buttons.mute.pressed = this.muted || this.volume === 0;\n }\n },\n\n // Update seek value and lower fill\n setRange(target, value = 0) {\n if (!is.element(target)) {\n return;\n }\n\n // eslint-disable-next-line\n target.value = value;\n\n // Webkit range fill\n controls.updateRangeFill.call(this, target);\n },\n\n // Update <progress> elements\n updateProgress(event) {\n if (!this.supported.ui || !is.event(event)) {\n return;\n }\n\n let value = 0;\n\n const setProgress = (target, input) => {\n const value = is.number(input) ? input : 0;\n const progress = is.element(target) ? target : this.elements.display.buffer;\n\n // Update value and label\n if (is.element(progress)) {\n progress.value = value;\n\n // Update text label inside\n const label = progress.getElementsByTagName('span')[0];\n if (is.element(label)) {\n label.childNodes[0].nodeValue = value;\n }\n }\n };\n\n if (event) {\n switch (event.type) {\n // Video playing\n case 'timeupdate':\n case 'seeking':\n case 'seeked':\n value = getPercentage(this.currentTime, this.duration);\n\n // Set seek range value only if it's a 'natural' time event\n if (event.type === 'timeupdate') {\n controls.setRange.call(this, this.elements.inputs.seek, value);\n }\n\n break;\n\n // Check buffer status\n case 'playing':\n case 'progress':\n setProgress(this.elements.display.buffer, this.buffered * 100);\n\n break;\n\n default:\n break;\n }\n }\n },\n\n // Webkit polyfill for lower fill range\n updateRangeFill(target) {\n // Get range from event if event passed\n const range = is.event(target) ? target.target : target;\n\n // Needs to be a valid <input type='range'>\n if (!is.element(range) || range.getAttribute('type') !== 'range') {\n return;\n }\n\n // Set aria values for https://github.com/sampotts/plyr/issues/905\n if (matches(range, this.config.selectors.inputs.seek)) {\n range.setAttribute('aria-valuenow', this.currentTime);\n const currentTime = controls.formatTime(this.currentTime);\n const duration = controls.formatTime(this.duration);\n const format = i18n.get('seekLabel', this.config);\n range.setAttribute(\n 'aria-valuetext',\n format.replace('{currentTime}', currentTime).replace('{duration}', duration),\n );\n } else if (matches(range, this.config.selectors.inputs.volume)) {\n const percent = range.value * 100;\n range.setAttribute('aria-valuenow', percent);\n range.setAttribute('aria-valuetext', `${percent}%`);\n } else {\n range.setAttribute('aria-valuenow', range.value);\n }\n\n // WebKit only\n if (!browser.isWebkit) {\n return;\n }\n\n // Set CSS custom property\n range.style.setProperty('--value', `${range.value / range.max * 100}%`);\n },\n\n // Update hover tooltip for seeking\n updateSeekTooltip(event) {\n // Bail if setting not true\n if (\n !this.config.tooltips.seek ||\n !is.element(this.elements.inputs.seek) ||\n !is.element(this.elements.display.seekTooltip) ||\n this.duration === 0\n ) {\n return;\n }\n\n // Calculate percentage\n let percent = 0;\n const clientRect = this.elements.progress.getBoundingClientRect();\n const visible = `${this.config.classNames.tooltip}--visible`;\n\n const toggle = toggle => {\n toggleClass(this.elements.display.seekTooltip, visible, toggle);\n };\n\n // Hide on touch\n if (this.touch) {\n toggle(false);\n return;\n }\n\n // Determine percentage, if already visible\n if (is.event(event)) {\n percent = 100 / clientRect.width * (event.pageX - clientRect.left);\n } else if (hasClass(this.elements.display.seekTooltip, visible)) {\n percent = parseFloat(this.elements.display.seekTooltip.style.left, 10);\n } else {\n return;\n }\n\n // Set bounds\n if (percent < 0) {\n percent = 0;\n } else if (percent > 100) {\n percent = 100;\n }\n\n // Display the time a click would seek to\n controls.updateTimeDisplay.call(this, this.elements.display.seekTooltip, this.duration / 100 * percent);\n\n // Set position\n this.elements.display.seekTooltip.style.left = `${percent}%`;\n\n // Show/hide the tooltip\n // If the event is a moues in/out and percentage is inside bounds\n if (is.event(event) && ['mouseenter', 'mouseleave'].includes(event.type)) {\n toggle(event.type === 'mouseenter');\n }\n },\n\n // Handle time change event\n timeUpdate(event) {\n // Only invert if only one time element is displayed and used for both duration and currentTime\n const invert = !is.element(this.elements.display.duration) && this.config.invertTime;\n\n // Duration\n controls.updateTimeDisplay.call(\n this,\n this.elements.display.currentTime,\n invert ? this.duration - this.currentTime : this.currentTime,\n invert,\n );\n\n // Ignore updates while seeking\n if (event && event.type === 'timeupdate' && this.media.seeking) {\n return;\n }\n\n // Playing progress\n controls.updateProgress.call(this, event);\n },\n\n // Show the duration on metadataloaded or durationchange events\n durationUpdate() {\n // Bail if no UI or durationchange event triggered after playing/seek when invertTime is false\n if (!this.supported.ui || (!this.config.invertTime && this.currentTime)) {\n return;\n }\n\n // Update ARIA values\n if (is.element(this.elements.inputs.seek)) {\n this.elements.inputs.seek.setAttribute('aria-valuemax', this.duration);\n }\n\n // If there's a spot to display duration\n const hasDuration = is.element(this.elements.display.duration);\n\n // If there's only one time display, display duration there\n if (!hasDuration && this.config.displayDuration && this.paused) {\n controls.updateTimeDisplay.call(this, this.elements.display.currentTime, this.duration);\n }\n\n // If there's a duration element, update content\n if (hasDuration) {\n controls.updateTimeDisplay.call(this, this.elements.display.duration, this.duration);\n }\n\n // Update the tooltip (if visible)\n controls.updateSeekTooltip.call(this);\n },\n\n // Hide/show a tab\n toggleMenuButton(setting, toggle) {\n toggleHidden(this.elements.settings.buttons[setting], !toggle);\n },\n\n // Set the quality menu\n setQualityMenu(options) {\n // Menu required\n if (!is.element(this.elements.settings.panels.quality)) {\n return;\n }\n\n const type = 'quality';\n const list = this.elements.settings.panels.quality.querySelector('[role=\"menu\"]');\n\n // Set options if passed and filter based on uniqueness and config\n if (is.array(options)) {\n this.options.quality = dedupe(options).filter(quality => this.config.quality.options.includes(quality));\n }\n\n // Toggle the pane and tab\n const toggle = !is.empty(this.options.quality) && this.options.quality.length > 1;\n controls.toggleMenuButton.call(this, type, toggle);\n\n // Check if we need to toggle the parent\n controls.checkMenu.call(this);\n\n // If we're hiding, nothing more to do\n if (!toggle) {\n return;\n }\n\n // Empty the menu\n emptyElement(list);\n\n // Get the badge HTML for HD, 4K etc\n const getBadge = quality => {\n const label = i18n.get(`qualityBadge.${quality}`, this.config);\n\n if (!label.length) {\n return null;\n }\n\n return controls.createBadge.call(this, label);\n };\n\n // Sort options by the config and then render options\n this.options.quality\n .sort((a, b) => {\n const sorting = this.config.quality.options;\n return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;\n })\n .forEach(quality => {\n controls.createMenuItem.call(this, {\n value: quality,\n list,\n type,\n title: controls.getLabel.call(this, 'quality', quality),\n badge: getBadge(quality),\n });\n });\n\n controls.updateSetting.call(this, type, list);\n },\n\n // Translate a value into a nice label\n getLabel(setting, value) {\n switch (setting) {\n case 'speed':\n return value === 1 ? i18n.get('normal', this.config) : `${value}×`;\n\n case 'quality':\n if (is.number(value)) {\n const label = i18n.get(`qualityLabel.${value}`, this.config);\n\n if (!label.length) {\n return `${value}p`;\n }\n\n return label;\n }\n\n return toTitleCase(value);\n\n case 'captions':\n return captions.getLabel.call(this);\n\n default:\n return null;\n }\n },\n\n // Update the selected setting\n updateSetting(setting, container, input) {\n const pane = this.elements.settings.panels[setting];\n let value = null;\n let list = container;\n\n if (setting === 'captions') {\n value = this.currentTrack;\n } else {\n value = !is.empty(input) ? input : this[setting];\n\n // Get default\n if (is.empty(value)) {\n value = this.config[setting].default;\n }\n\n // Unsupported value\n if (!is.empty(this.options[setting]) && !this.options[setting].includes(value)) {\n this.debug.warn(`Unsupported value of '${value}' for ${setting}`);\n return;\n }\n\n // Disabled value\n if (!this.config[setting].options.includes(value)) {\n this.debug.warn(`Disabled value of '${value}' for ${setting}`);\n return;\n }\n }\n\n // Get the list if we need to\n if (!is.element(list)) {\n list = pane && pane.querySelector('[role=\"menu\"]');\n }\n\n // If there's no list it means it's not been rendered...\n if (!is.element(list)) {\n return;\n }\n\n // Update the label\n const label = this.elements.settings.buttons[setting].querySelector(`.${this.config.classNames.menu.value}`);\n label.innerHTML = controls.getLabel.call(this, setting, value);\n\n // Find the radio option and check it\n const target = list && list.querySelector(`[value=\"${value}\"]`);\n\n if (is.element(target)) {\n target.checked = true;\n }\n },\n\n // Set the looping options\n /* setLoopMenu() {\n // Menu required\n if (!is.element(this.elements.settings.panels.loop)) {\n return;\n }\n\n const options = ['start', 'end', 'all', 'reset'];\n const list = this.elements.settings.panels.loop.querySelector('[role=\"menu\"]');\n\n // Show the pane and tab\n toggleHidden(this.elements.settings.buttons.loop, false);\n toggleHidden(this.elements.settings.panels.loop, false);\n\n // Toggle the pane and tab\n const toggle = !is.empty(this.loop.options);\n controls.toggleMenuButton.call(this, 'loop', toggle);\n\n // Empty the menu\n emptyElement(list);\n\n options.forEach(option => {\n const item = createElement('li');\n\n const button = createElement(\n 'button',\n extend(getAttributesFromSelector(this.config.selectors.buttons.loop), {\n type: 'button',\n class: this.config.classNames.control,\n 'data-plyr-loop-action': option,\n }),\n i18n.get(option, this.config)\n );\n\n if (['start', 'end'].includes(option)) {\n const badge = controls.createBadge.call(this, '00:00');\n button.appendChild(badge);\n }\n\n item.appendChild(button);\n list.appendChild(item);\n });\n }, */\n\n // Get current selected caption language\n // TODO: rework this to user the getter in the API?\n\n // Set a list of available captions languages\n setCaptionsMenu() {\n // TODO: Captions or language? Currently it's mixed\n const type = 'captions';\n const list = this.elements.settings.panels.captions.querySelector('[role=\"menu\"]');\n const tracks = captions.getTracks.call(this);\n\n // Toggle the pane and tab\n controls.toggleMenuButton.call(this, type, tracks.length);\n\n // Empty the menu\n emptyElement(list);\n\n // Check if we need to toggle the parent\n controls.checkMenu.call(this);\n\n // If there's no captions, bail\n if (!tracks.length) {\n return;\n }\n\n // Generate options data\n const options = tracks.map((track, value) => ({\n value,\n checked: this.captions.toggled && this.currentTrack === value,\n title: captions.getLabel.call(this, track),\n badge: track.language && controls.createBadge.call(this, track.language.toUpperCase()),\n list,\n type: 'language',\n }));\n\n // Add the \"Disabled\" option to turn off captions\n options.unshift({\n value: -1,\n checked: !this.captions.toggled,\n title: i18n.get('disabled', this.config),\n list,\n type: 'language',\n });\n\n // Generate options\n options.forEach(controls.createMenuItem.bind(this));\n\n controls.updateSetting.call(this, type, list);\n },\n\n // Set a list of available captions languages\n setSpeedMenu(options) {\n // Do nothing if not selected\n if (!this.config.controls.includes('settings') || !this.config.settings.includes('speed')) {\n return;\n }\n\n // Menu required\n if (!is.element(this.elements.settings.panels.speed)) {\n return;\n }\n\n const type = 'speed';\n\n // Set the speed options\n if (is.array(options)) {\n this.options.speed = options;\n } else if (this.isHTML5 || this.isVimeo) {\n this.options.speed = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];\n }\n\n // Set options if passed and filter based on config\n this.options.speed = this.options.speed.filter(speed => this.config.speed.options.includes(speed));\n\n // Toggle the pane and tab\n const toggle = !is.empty(this.options.speed) && this.options.speed.length > 1;\n controls.toggleMenuButton.call(this, type, toggle);\n\n // Check if we need to toggle the parent\n controls.checkMenu.call(this);\n\n // If we're hiding, nothing more to do\n if (!toggle) {\n return;\n }\n\n // Get the list to populate\n const list = this.elements.settings.panels.speed.querySelector('[role=\"menu\"]');\n\n // Empty the menu\n emptyElement(list);\n\n // Create items\n this.options.speed.forEach(speed => {\n controls.createMenuItem.call(this, {\n value: speed,\n list,\n type,\n title: controls.getLabel.call(this, 'speed', speed),\n });\n });\n\n controls.updateSetting.call(this, type, list);\n },\n\n // Check if we need to hide/show the settings menu\n checkMenu() {\n const { buttons } = this.elements.settings;\n const visible = !is.empty(buttons) && Object.values(buttons).some(button => !button.hidden);\n\n toggleHidden(this.elements.settings.menu, !visible);\n },\n\n // Show/hide menu\n toggleMenu(event) {\n const { popup } = this.elements.settings;\n const button = this.elements.buttons.settings;\n\n // Menu and button are required\n if (!is.element(popup) || !is.element(button)) {\n return;\n }\n\n const show = is.boolean(event) ? event : is.element(popup) && popup.hasAttribute('hidden');\n\n if (is.event(event)) {\n const isMenuItem = is.element(popup) && popup.contains(event.target);\n const isButton = event.target === this.elements.buttons.settings;\n\n // If the click was inside the form or if the click\n // wasn't the button or menu item and we're trying to\n // show the menu (a doc click shouldn't show the menu)\n if (isMenuItem || (!isMenuItem && !isButton && show)) {\n return;\n }\n\n // Prevent the toggle being caught by the doc listener\n if (isButton) {\n event.stopPropagation();\n }\n }\n\n // Set form and button attributes\n if (is.element(button)) {\n button.setAttribute('aria-expanded', show);\n }\n\n if (is.element(popup)) {\n toggleHidden(popup, !show);\n toggleClass(this.elements.container, this.config.classNames.menu.open, show);\n\n if (show) {\n popup.removeAttribute('tabindex');\n } else {\n popup.setAttribute('tabindex', -1);\n }\n }\n },\n\n // Get the natural size of a menu panel\n getMenuSize(tab) {\n const clone = tab.cloneNode(true);\n clone.style.position = 'absolute';\n clone.style.opacity = 0;\n clone.removeAttribute('hidden');\n\n // Append to parent so we get the \"real\" size\n tab.parentNode.appendChild(clone);\n\n // Get the sizes before we remove\n const width = clone.scrollWidth;\n const height = clone.scrollHeight;\n\n // Remove from the DOM\n removeElement(clone);\n\n return {\n width,\n height,\n };\n },\n\n // Show a panel in the menu\n showMenuPanel(type = '') {\n const target = document.getElementById(`plyr-settings-${this.id}-${type}`);\n\n // Nothing to show, bail\n if (!is.element(target)) {\n return;\n }\n\n // Hide all other panels\n const container = target.parentNode;\n const current = Array.from(container.children).find(node => !node.hidden);\n\n // If we can do fancy animations, we'll animate the height/width\n if (support.transitions && !support.reducedMotion) {\n // Set the current width as a base\n container.style.width = `${current.scrollWidth}px`;\n container.style.height = `${current.scrollHeight}px`;\n\n // Get potential sizes\n const size = controls.getMenuSize.call(this, target);\n\n // Restore auto height/width\n const restore = event => {\n // We're only bothered about height and width on the container\n if (event.target !== container || !['width', 'height'].includes(event.propertyName)) {\n return;\n }\n\n // Revert back to auto\n container.style.width = '';\n container.style.height = '';\n\n // Only listen once\n off.call(this, container, transitionEndEvent, restore);\n };\n\n // Listen for the transition finishing and restore auto height/width\n on.call(this, container, transitionEndEvent, restore);\n\n // Set dimensions to target\n container.style.width = `${size.width}px`;\n container.style.height = `${size.height}px`;\n }\n\n // Set attributes on current tab\n toggleHidden(current, true);\n // current.setAttribute('tabindex', -1);\n\n // Set attributes on target\n toggleHidden(target, false);\n\n // Focus the first item\n target.querySelectorAll('[role^=\"menuitem\"]')[0].focus();\n },\n\n // Build the default HTML\n // TODO: Set order based on order in the config.controls array?\n create(data) {\n // Do nothing if we want no controls\n if (is.empty(this.config.controls)) {\n return null;\n }\n\n // Create the container\n const container = createElement('div', getAttributesFromSelector(this.config.selectors.controls.wrapper));\n\n // Restart button\n if (this.config.controls.includes('restart')) {\n container.appendChild(controls.createButton.call(this, 'restart'));\n }\n\n // Rewind button\n if (this.config.controls.includes('rewind')) {\n container.appendChild(controls.createButton.call(this, 'rewind'));\n }\n\n // Play/Pause button\n if (this.config.controls.includes('play')) {\n container.appendChild(controls.createButton.call(this, 'play'));\n }\n\n // Fast forward button\n if (this.config.controls.includes('fast-forward')) {\n container.appendChild(controls.createButton.call(this, 'fast-forward'));\n }\n\n // Progress\n if (this.config.controls.includes('progress')) {\n const progress = createElement('div', getAttributesFromSelector(this.config.selectors.progress));\n\n // Seek range slider\n progress.appendChild(\n controls.createRange.call(this, 'seek', {\n id: `plyr-seek-${data.id}`,\n }),\n );\n\n // Buffer progress\n progress.appendChild(controls.createProgress.call(this, 'buffer'));\n\n // TODO: Add loop display indicator\n\n // Seek tooltip\n if (this.config.tooltips.seek) {\n const tooltip = createElement(\n 'span',\n {\n class: this.config.classNames.tooltip,\n },\n '00:00',\n );\n\n progress.appendChild(tooltip);\n this.elements.display.seekTooltip = tooltip;\n }\n\n this.elements.progress = progress;\n container.appendChild(this.elements.progress);\n }\n\n // Media current time display\n if (this.config.controls.includes('current-time')) {\n container.appendChild(controls.createTime.call(this, 'currentTime'));\n }\n\n // Media duration display\n if (this.config.controls.includes('duration')) {\n container.appendChild(controls.createTime.call(this, 'duration'));\n }\n\n // Toggle mute button\n if (this.config.controls.includes('mute')) {\n container.appendChild(controls.createButton.call(this, 'mute'));\n }\n\n // Volume range control\n if (this.config.controls.includes('volume')) {\n const volume = createElement('div', {\n class: 'plyr__volume',\n });\n\n // Set the attributes\n const attributes = {\n max: 1,\n step: 0.05,\n value: this.config.volume,\n };\n\n // Create the volume range slider\n volume.appendChild(\n controls.createRange.call(\n this,\n 'volume',\n extend(attributes, {\n id: `plyr-volume-${data.id}`,\n }),\n ),\n );\n\n this.elements.volume = volume;\n\n container.appendChild(volume);\n }\n\n // Toggle captions button\n if (this.config.controls.includes('captions')) {\n container.appendChild(controls.createButton.call(this, 'captions'));\n }\n\n // Settings button / menu\n if (this.config.controls.includes('settings') && !is.empty(this.config.settings)) {\n const control = createElement('div', {\n class: 'plyr__menu',\n hidden: '',\n });\n\n control.appendChild(\n controls.createButton.call(this, 'settings', {\n id: `plyr-settings-toggle-${data.id}`,\n 'aria-haspopup': true,\n 'aria-controls': `plyr-settings-${data.id}`,\n 'aria-expanded': false,\n }),\n );\n\n const popup = createElement('div', {\n class: 'plyr__menu__container',\n id: `plyr-settings-${data.id}`,\n hidden: '',\n 'aria-labelled-by': `plyr-settings-toggle-${data.id}`,\n });\n\n const inner = createElement('div');\n\n const home = createElement('div', {\n id: `plyr-settings-${data.id}-home`,\n });\n\n // Create the menu\n const menu = createElement('div', {\n role: 'menu',\n });\n\n // Build the menu items\n this.config.settings.forEach(type => {\n const menuItem = createElement(\n 'button',\n extend(getAttributesFromSelector(this.config.selectors.buttons.settings), {\n type: 'button',\n class: `${this.config.classNames.control} ${this.config.classNames.control}--forward`,\n role: 'menuitem',\n 'aria-haspopup': true,\n }),\n );\n\n const flex = createElement('span', null, i18n.get(type, this.config));\n\n const value = createElement('span', {\n class: this.config.classNames.menu.value,\n });\n\n // Speed contains HTML entities\n value.innerHTML = data[type];\n\n flex.appendChild(value);\n menuItem.appendChild(flex);\n menu.appendChild(menuItem);\n\n // Build the panes\n const pane = createElement('div', {\n id: `plyr-settings-${data.id}-${type}`,\n hidden: '',\n });\n\n // Back button\n const back = createElement(\n 'button',\n {\n type: 'button',\n class: `${this.config.classNames.control} ${this.config.classNames.control}--back`,\n },\n i18n.get(type, this.config),\n );\n back.addEventListener('click', () => {\n controls.showMenuPanel.call(this, 'home');\n });\n pane.appendChild(back);\n\n // Menu\n pane.appendChild(\n createElement('div', {\n role: 'menu',\n }),\n );\n\n inner.appendChild(pane);\n\n menuItem.addEventListener('click', () => {\n controls.showMenuPanel.call(this, type);\n });\n\n this.elements.settings.buttons[type] = menuItem;\n this.elements.settings.panels[type] = pane;\n });\n\n home.appendChild(menu);\n inner.appendChild(home);\n\n popup.appendChild(inner);\n control.appendChild(popup);\n container.appendChild(control);\n\n this.elements.settings.popup = popup;\n this.elements.settings.menu = control;\n }\n\n // Picture in picture button\n if (this.config.controls.includes('pip') && support.pip) {\n container.appendChild(controls.createButton.call(this, 'pip'));\n }\n\n // Airplay button\n if (this.config.controls.includes('airplay') && support.airplay) {\n container.appendChild(controls.createButton.call(this, 'airplay'));\n }\n\n // Toggle fullscreen button\n if (this.config.controls.includes('fullscreen')) {\n container.appendChild(controls.createButton.call(this, 'fullscreen'));\n }\n\n // Larger overlaid play button\n if (this.config.controls.includes('play-large')) {\n this.elements.container.appendChild(controls.createButton.call(this, 'play-large'));\n }\n\n this.elements.controls = container;\n\n if (this.isHTML5) {\n controls.setQualityMenu.call(this, html5.getQualityOptions.call(this));\n }\n\n controls.setSpeedMenu.call(this);\n\n return container;\n },\n\n // Insert controls\n inject() {\n // Sprite\n if (this.config.loadSprite) {\n const icon = controls.getIconUrl.call(this);\n\n // Only load external sprite using AJAX\n if (icon.cors) {\n loadSprite(icon.url, 'sprite-plyr');\n }\n }\n\n // Create a unique ID\n this.id = Math.floor(Math.random() * 10000);\n\n // Null by default\n let container = null;\n this.elements.controls = null;\n\n // Set template properties\n const props = {\n id: this.id,\n seektime: this.config.seekTime,\n title: this.config.title,\n };\n let update = true;\n\n if (is.string(this.config.controls) || is.element(this.config.controls)) {\n // String or HTMLElement passed as the option\n container = this.config.controls;\n } else if (is.function(this.config.controls)) {\n // A custom function to build controls\n // The function can return a HTMLElement or String\n container = this.config.controls.call(this, props);\n } else {\n // Create controls\n container = controls.create.call(this, {\n id: this.id,\n seektime: this.config.seekTime,\n speed: this.speed,\n quality: this.quality,\n captions: captions.getLabel.call(this),\n // TODO: Looping\n // loop: 'None',\n });\n update = false;\n }\n\n // Replace props with their value\n const replace = input => {\n let result = input;\n\n Object.entries(props).forEach(([key, value]) => {\n result = replaceAll(result, `{${key}}`, value);\n });\n\n return result;\n };\n\n // Update markup\n if (update) {\n if (is.string(this.config.controls)) {\n container = replace(container);\n } else if (is.element(container)) {\n container.innerHTML = replace(container.innerHTML);\n }\n }\n\n // Controls container\n let target;\n\n // Inject to custom location\n if (is.string(this.config.selectors.controls.container)) {\n target = document.querySelector(this.config.selectors.controls.container);\n }\n\n // Inject into the container by default\n if (!is.element(target)) {\n target = this.elements.container;\n }\n\n // Inject controls HTML\n if (is.element(container)) {\n target.appendChild(container);\n } else if (container) {\n target.insertAdjacentHTML('beforeend', container);\n }\n\n // Find the elements if need be\n if (!is.element(this.elements.controls)) {\n controls.findElements.call(this);\n }\n\n // Edge sometimes doesn't finish the paint so force a redraw\n if (window.navigator.userAgent.includes('Edge')) {\n repaint(target);\n }\n\n // Setup tooltips\n if (this.config.tooltips.controls) {\n const { classNames, selectors } = this.config;\n const selector = `${selectors.controls.wrapper} ${selectors.labels} .${classNames.hidden}`;\n const labels = getElements.call(this, selector);\n\n Array.from(labels).forEach(label => {\n toggleClass(label, this.config.classNames.hidden, false);\n toggleClass(label, this.config.classNames.tooltip, true);\n });\n }\n },\n};\n\nexport default controls;\n","// ==========================================================================\n// URL utils\n// ==========================================================================\n\nimport is from './is';\n\n/**\n * Parse a string to a URL object\n * @param {string} input - the URL to be parsed\n * @param {boolean} safe - failsafe parsing\n */\nexport function parseUrl(input, safe = true) {\n let url = input;\n\n if (safe) {\n const parser = document.createElement('a');\n parser.href = url;\n url = parser.href;\n }\n\n try {\n return new URL(url);\n } catch (e) {\n return null;\n }\n}\n\n// Convert object to URLSearchParams\nexport function buildUrlParams(input) {\n const params = new URLSearchParams();\n\n if (is.object(input)) {\n Object.entries(input).forEach(([key, value]) => {\n params.set(key, value);\n });\n }\n\n return params;\n}\n","// ==========================================================================\n// Plyr Captions\n// TODO: Create as class\n// ==========================================================================\n\nimport controls from './controls';\nimport i18n from './i18n';\nimport support from './support';\nimport { dedupe } from './utils/arrays';\nimport browser from './utils/browser';\nimport {\n createElement,\n emptyElement,\n getAttributesFromSelector,\n insertAfter,\n removeElement,\n toggleClass,\n} from './utils/elements';\nimport { on, triggerEvent } from './utils/events';\nimport fetch from './utils/fetch';\nimport is from './utils/is';\nimport { getHTML } from './utils/strings';\nimport { parseUrl } from './utils/urls';\n\nconst captions = {\n // Setup captions\n setup() {\n // Requires UI support\n if (!this.supported.ui) {\n return;\n }\n\n // Only Vimeo and HTML5 video supported at this point\n if (!this.isVideo || this.isYouTube || (this.isHTML5 && !support.textTracks)) {\n // Clear menu and hide\n if (\n is.array(this.config.controls) &&\n this.config.controls.includes('settings') &&\n this.config.settings.includes('captions')\n ) {\n controls.setCaptionsMenu.call(this);\n }\n\n return;\n }\n\n // Inject the container\n if (!is.element(this.elements.captions)) {\n this.elements.captions = createElement('div', getAttributesFromSelector(this.config.selectors.captions));\n\n insertAfter(this.elements.captions, this.elements.wrapper);\n }\n\n // Fix IE captions if CORS is used\n // Fetch captions and inject as blobs instead (data URIs not supported!)\n if (browser.isIE && window.URL) {\n const elements = this.media.querySelectorAll('track');\n\n Array.from(elements).forEach(track => {\n const src = track.getAttribute('src');\n const url = parseUrl(src);\n\n if (\n url !== null &&\n url.hostname !== window.location.href.hostname &&\n ['http:', 'https:'].includes(url.protocol)\n ) {\n fetch(src, 'blob')\n .then(blob => {\n track.setAttribute('src', window.URL.createObjectURL(blob));\n })\n .catch(() => {\n removeElement(track);\n });\n }\n });\n }\n\n // Get and set initial data\n // The \"preferred\" options are not realized unless / until the wanted language has a match\n // * languages: Array of user's browser languages.\n // * language: The language preferred by user settings or config\n // * active: The state preferred by user settings or config\n // * toggled: The real captions state\n\n const languages = dedupe(\n Array.from(navigator.languages || navigator.userLanguage).map(language => language.split('-')[0]),\n );\n\n let language = (this.storage.get('language') || this.config.captions.language || 'auto').toLowerCase();\n\n // Use first browser language when language is 'auto'\n if (language === 'auto') {\n [language] = languages;\n }\n\n let active = this.storage.get('captions');\n if (!is.boolean(active)) {\n ({ active } = this.config.captions);\n }\n\n Object.assign(this.captions, {\n toggled: false,\n active,\n language,\n languages,\n });\n\n // Watch changes to textTracks and update captions menu\n if (this.isHTML5) {\n const trackEvents = this.config.captions.update ? 'addtrack removetrack' : 'removetrack';\n on.call(this, this.media.textTracks, trackEvents, captions.update.bind(this));\n }\n\n // Update available languages in list next tick (the event must not be triggered before the listeners)\n setTimeout(captions.update.bind(this), 0);\n },\n\n // Update available language options in settings based on tracks\n update() {\n const tracks = captions.getTracks.call(this, true);\n // Get the wanted language\n const { active, language, meta, currentTrackNode } = this.captions;\n const languageExists = Boolean(tracks.find(track => track.language === language));\n\n // Handle tracks (add event listener and \"pseudo\"-default)\n if (this.isHTML5 && this.isVideo) {\n tracks.filter(track => !meta.get(track)).forEach(track => {\n this.debug.log('Track added', track);\n // Attempt to store if the original dom element was \"default\"\n meta.set(track, {\n default: track.mode === 'showing',\n });\n\n // Turn off native caption rendering to avoid double captions\n track.mode = 'hidden';\n\n // Add event listener for cue changes\n on.call(this, track, 'cuechange', () => captions.updateCues.call(this));\n });\n }\n\n // Update language first time it matches, or if the previous matching track was removed\n if ((languageExists && this.language !== language) || !tracks.includes(currentTrackNode)) {\n captions.setLanguage.call(this, language);\n captions.toggle.call(this, active && languageExists);\n }\n\n // Enable or disable captions based on track length\n toggleClass(this.elements.container, this.config.classNames.captions.enabled, !is.empty(tracks));\n\n // Update available languages in list\n if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) {\n controls.setCaptionsMenu.call(this);\n }\n },\n\n // Toggle captions display\n // Used internally for the toggleCaptions method, with the passive option forced to false\n toggle(input, passive = true) {\n // If there's no full support\n if (!this.supported.ui) {\n return;\n }\n\n const { toggled } = this.captions; // Current state\n const activeClass = this.config.classNames.captions.active;\n\n // Get the next state\n // If the method is called without parameter, toggle based on current value\n const active = is.nullOrUndefined(input) ? !toggled : input;\n\n // Update state and trigger event\n if (active !== toggled) {\n // When passive, don't override user preferences\n if (!passive) {\n this.captions.active = active;\n this.storage.set({ captions: active });\n }\n\n // Force language if the call isn't passive and there is no matching language to toggle to\n if (!this.language && active && !passive) {\n const tracks = captions.getTracks.call(this);\n const track = captions.findTrack.call(this, [this.captions.language, ...this.captions.languages], true);\n\n // Override user preferences to avoid switching languages if a matching track is added\n this.captions.language = track.language;\n\n // Set caption, but don't store in localStorage as user preference\n captions.set.call(this, tracks.indexOf(track));\n return;\n }\n\n // Toggle state\n this.elements.buttons.captions.pressed = active;\n\n // Add class hook\n toggleClass(this.elements.container, activeClass, active);\n\n this.captions.toggled = active;\n\n // Update settings menu\n controls.updateSetting.call(this, 'captions');\n\n // Trigger event (not used internally)\n triggerEvent.call(this, this.media, active ? 'captionsenabled' : 'captionsdisabled');\n }\n },\n\n // Set captions by track index\n // Used internally for the currentTrack setter with the passive option forced to false\n set(index, passive = true) {\n const tracks = captions.getTracks.call(this);\n\n // Disable captions if setting to -1\n if (index === -1) {\n captions.toggle.call(this, false, passive);\n return;\n }\n\n if (!is.number(index)) {\n this.debug.warn('Invalid caption argument', index);\n return;\n }\n\n if (!(index in tracks)) {\n this.debug.warn('Track not found', index);\n return;\n }\n\n if (this.captions.currentTrack !== index) {\n this.captions.currentTrack = index;\n const track = tracks[index];\n const { language } = track || {};\n\n // Store reference to node for invalidation on remove\n this.captions.currentTrackNode = track;\n\n // Update settings menu\n controls.updateSetting.call(this, 'captions');\n\n // When passive, don't override user preferences\n if (!passive) {\n this.captions.language = language;\n this.storage.set({ language });\n }\n\n // Handle Vimeo captions\n if (this.isVimeo) {\n this.embed.enableTextTrack(language);\n }\n\n // Trigger event\n triggerEvent.call(this, this.media, 'languagechange');\n }\n\n // Show captions\n captions.toggle.call(this, true, passive);\n\n if (this.isHTML5 && this.isVideo) {\n // If we change the active track while a cue is already displayed we need to update it\n captions.updateCues.call(this);\n }\n },\n\n // Set captions by language\n // Used internally for the language setter with the passive option forced to false\n setLanguage(input, passive = true) {\n if (!is.string(input)) {\n this.debug.warn('Invalid language argument', input);\n return;\n }\n // Normalize\n const language = input.toLowerCase();\n this.captions.language = language;\n\n // Set currentTrack\n const tracks = captions.getTracks.call(this);\n const track = captions.findTrack.call(this, [language]);\n captions.set.call(this, tracks.indexOf(track), passive);\n },\n\n // Get current valid caption tracks\n // If update is false it will also ignore tracks without metadata\n // This is used to \"freeze\" the language options when captions.update is false\n getTracks(update = false) {\n // Handle media or textTracks missing or null\n const tracks = Array.from((this.media || {}).textTracks || []);\n // For HTML5, use cache instead of current tracks when it exists (if captions.update is false)\n // Filter out removed tracks and tracks that aren't captions/subtitles (for example metadata)\n return tracks\n .filter(track => !this.isHTML5 || update || this.captions.meta.has(track))\n .filter(track => ['captions', 'subtitles'].includes(track.kind));\n },\n\n // Match tracks based on languages and get the first\n findTrack(languages, force = false) {\n const tracks = captions.getTracks.call(this);\n const sortIsDefault = track => Number((this.captions.meta.get(track) || {}).default);\n const sorted = Array.from(tracks).sort((a, b) => sortIsDefault(b) - sortIsDefault(a));\n let track;\n languages.every(language => {\n track = sorted.find(track => track.language === language);\n return !track; // Break iteration if there is a match\n });\n // If no match is found but is required, get first\n return track || (force ? sorted[0] : undefined);\n },\n\n // Get the current track\n getCurrentTrack() {\n return captions.getTracks.call(this)[this.currentTrack];\n },\n\n // Get UI label for track\n getLabel(track) {\n let currentTrack = track;\n\n if (!is.track(currentTrack) && support.textTracks && this.captions.toggled) {\n currentTrack = captions.getCurrentTrack.call(this);\n }\n\n if (is.track(currentTrack)) {\n if (!is.empty(currentTrack.label)) {\n return currentTrack.label;\n }\n\n if (!is.empty(currentTrack.language)) {\n return track.language.toUpperCase();\n }\n\n return i18n.get('enabled', this.config);\n }\n\n return i18n.get('disabled', this.config);\n },\n\n // Update captions using current track's active cues\n // Also optional array argument in case there isn't any track (ex: vimeo)\n updateCues(input) {\n // Requires UI\n if (!this.supported.ui) {\n return;\n }\n\n if (!is.element(this.elements.captions)) {\n this.debug.warn('No captions element to render to');\n return;\n }\n\n // Only accept array or empty input\n if (!is.nullOrUndefined(input) && !Array.isArray(input)) {\n this.debug.warn('updateCues: Invalid input', input);\n return;\n }\n\n let cues = input;\n\n // Get cues from track\n if (!cues) {\n const track = captions.getCurrentTrack.call(this);\n cues = Array.from((track || {}).activeCues || [])\n .map(cue => cue.getCueAsHTML())\n .map(getHTML);\n }\n\n // Set new caption text\n const content = cues.map(cueText => cueText.trim()).join('\\n');\n const changed = content !== this.elements.captions.innerHTML;\n\n if (changed) {\n // Empty the container and create a new child element\n emptyElement(this.elements.captions);\n const caption = createElement('span', getAttributesFromSelector(this.config.selectors.caption));\n caption.innerHTML = content;\n this.elements.captions.appendChild(caption);\n\n // Trigger event\n triggerEvent.call(this, this.media, 'cuechange');\n }\n },\n};\n\nexport default captions;\n","// ==========================================================================\n// Plyr default config\n// ==========================================================================\n\nconst defaults = {\n // Disable\n enabled: true,\n\n // Custom media title\n title: '',\n\n // Logging to console\n debug: false,\n\n // Auto play (if supported)\n autoplay: false,\n\n // Only allow one media playing at once (vimeo only)\n autopause: true,\n\n // Allow inline playback on iOS (this effects YouTube/Vimeo - HTML5 requires the attribute present)\n // TODO: Remove iosNative fullscreen option in favour of this (logic needs work)\n playsinline: true,\n\n // Default time to skip when rewind/fast forward\n seekTime: 10,\n\n // Default volume\n volume: 1,\n muted: false,\n\n // Pass a custom duration\n duration: null,\n\n // Display the media duration on load in the current time position\n // If you have opted to display both duration and currentTime, this is ignored\n displayDuration: true,\n\n // Invert the current time to be a countdown\n invertTime: true,\n\n // Clicking the currentTime inverts it's value to show time left rather than elapsed\n toggleInvert: true,\n\n // Aspect ratio (for embeds)\n ratio: '16:9',\n\n // Click video container to play/pause\n clickToPlay: true,\n\n // Auto hide the controls\n hideControls: true,\n\n // Reset to start when playback ended\n resetOnEnd: false,\n\n // Disable the standard context menu\n disableContextMenu: true,\n\n // Sprite (for icons)\n loadSprite: true,\n iconPrefix: 'plyr',\n iconUrl: 'https://cdn.plyr.io/3.3.12/plyr.svg',\n\n // Blank video (used to prevent errors on source change)\n blankVideo: 'https://cdn.plyr.io/static/blank.mp4',\n\n // Quality default\n quality: {\n default: 576,\n options: [\n 4320,\n 2880,\n 2160,\n 1440,\n 1080,\n 720,\n 576,\n 480,\n 360,\n 240,\n 'default', // YouTube's \"auto\"\n ],\n },\n\n // Set loops\n loop: {\n active: false,\n // start: null,\n // end: null,\n },\n\n // Speed default and options to display\n speed: {\n selected: 1,\n options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],\n },\n\n // Keyboard shortcut settings\n keyboard: {\n focused: true,\n global: false,\n },\n\n // Display tooltips\n tooltips: {\n controls: false,\n seek: true,\n },\n\n // Captions settings\n captions: {\n active: false,\n language: 'auto',\n // Listen to new tracks added after Plyr is initialized.\n // This is needed for streaming captions, but may result in unselectable options\n update: false,\n },\n\n // Fullscreen settings\n fullscreen: {\n enabled: true, // Allow fullscreen?\n fallback: true, // Fallback for vintage browsers\n iosNative: false, // Use the native fullscreen in iOS (disables custom controls)\n },\n\n // Local storage\n storage: {\n enabled: true,\n key: 'plyr',\n },\n\n // Default controls\n controls: [\n 'play-large',\n // 'restart',\n // 'rewind',\n 'play',\n // 'fast-forward',\n 'progress',\n 'current-time',\n 'mute',\n 'volume',\n 'captions',\n 'settings',\n 'pip',\n 'airplay',\n 'fullscreen',\n ],\n settings: ['captions', 'quality', 'speed'],\n\n // Localisation\n i18n: {\n restart: 'Restart',\n rewind: 'Rewind {seektime}s',\n play: 'Play',\n pause: 'Pause',\n fastForward: 'Forward {seektime}s',\n seek: 'Seek',\n seekLabel: '{currentTime} of {duration}',\n played: 'Played',\n buffered: 'Buffered',\n currentTime: 'Current time',\n duration: 'Duration',\n volume: 'Volume',\n mute: 'Mute',\n unmute: 'Unmute',\n enableCaptions: 'Enable captions',\n disableCaptions: 'Disable captions',\n enterFullscreen: 'Enter fullscreen',\n exitFullscreen: 'Exit fullscreen',\n frameTitle: 'Player for {title}',\n captions: 'Captions',\n settings: 'Settings',\n menuBack: 'Go back to previous menu',\n speed: 'Speed',\n normal: 'Normal',\n quality: 'Quality',\n loop: 'Loop',\n start: 'Start',\n end: 'End',\n all: 'All',\n reset: 'Reset',\n disabled: 'Disabled',\n enabled: 'Enabled',\n advertisement: 'Ad',\n qualityBadge: {\n 2160: '4K',\n 1440: 'HD',\n 1080: 'HD',\n 720: 'HD',\n 576: 'SD',\n 480: 'SD',\n },\n },\n\n // URLs\n urls: {\n vimeo: {\n sdk: 'https://player.vimeo.com/api/player.js',\n iframe: 'https://player.vimeo.com/video/{0}?{1}',\n api: 'https://vimeo.com/api/v2/video/{0}.json',\n },\n youtube: {\n sdk: 'https://www.youtube.com/iframe_api',\n api:\n 'https://www.googleapis.com/youtube/v3/videos?id={0}&key={1}&fields=items(snippet(title))&part=snippet',\n },\n googleIMA: {\n sdk: 'https://imasdk.googleapis.com/js/sdkloader/ima3.js',\n },\n },\n\n // Custom control listeners\n listeners: {\n seek: null,\n play: null,\n pause: null,\n restart: null,\n rewind: null,\n fastForward: null,\n mute: null,\n volume: null,\n captions: null,\n fullscreen: null,\n pip: null,\n airplay: null,\n speed: null,\n quality: null,\n loop: null,\n language: null,\n },\n\n // Events to watch and bubble\n events: [\n // Events to watch on HTML5 media elements and bubble\n // https://developer.mozilla.org/en/docs/Web/Guide/Events/Media_events\n 'ended',\n 'progress',\n 'stalled',\n 'playing',\n 'waiting',\n 'canplay',\n 'canplaythrough',\n 'loadstart',\n 'loadeddata',\n 'loadedmetadata',\n 'timeupdate',\n 'volumechange',\n 'play',\n 'pause',\n 'error',\n 'seeking',\n 'seeked',\n 'emptied',\n 'ratechange',\n 'cuechange',\n\n // Custom events\n 'enterfullscreen',\n 'exitfullscreen',\n 'captionsenabled',\n 'captionsdisabled',\n 'languagechange',\n 'controlshidden',\n 'controlsshown',\n 'ready',\n\n // YouTube\n 'statechange',\n 'qualitychange',\n 'qualityrequested',\n\n // Ads\n 'adsloaded',\n 'adscontentpause',\n 'adscontentresume',\n 'adstarted',\n 'adsmidpoint',\n 'adscomplete',\n 'adsallcomplete',\n 'adsimpression',\n 'adsclick',\n ],\n\n // Selectors\n // Change these to match your template if using custom HTML\n selectors: {\n editable: 'input, textarea, select, [contenteditable]',\n container: '.plyr',\n controls: {\n container: null,\n wrapper: '.plyr__controls',\n },\n labels: '[data-plyr]',\n buttons: {\n play: '[data-plyr=\"play\"]',\n pause: '[data-plyr=\"pause\"]',\n restart: '[data-plyr=\"restart\"]',\n rewind: '[data-plyr=\"rewind\"]',\n fastForward: '[data-plyr=\"fast-forward\"]',\n mute: '[data-plyr=\"mute\"]',\n captions: '[data-plyr=\"captions\"]',\n fullscreen: '[data-plyr=\"fullscreen\"]',\n pip: '[data-plyr=\"pip\"]',\n airplay: '[data-plyr=\"airplay\"]',\n settings: '[data-plyr=\"settings\"]',\n loop: '[data-plyr=\"loop\"]',\n },\n inputs: {\n seek: '[data-plyr=\"seek\"]',\n volume: '[data-plyr=\"volume\"]',\n speed: '[data-plyr=\"speed\"]',\n language: '[data-plyr=\"language\"]',\n quality: '[data-plyr=\"quality\"]',\n },\n display: {\n currentTime: '.plyr__time--current',\n duration: '.plyr__time--duration',\n buffer: '.plyr__progress__buffer',\n loop: '.plyr__progress__loop', // Used later\n volume: '.plyr__volume--display',\n },\n progress: '.plyr__progress',\n captions: '.plyr__captions',\n caption: '.plyr__caption',\n menu: {\n quality: '.js-plyr__menu__list--quality',\n },\n },\n\n // Class hooks added to the player in different states\n classNames: {\n type: 'plyr--{0}',\n provider: 'plyr--{0}',\n video: 'plyr__video-wrapper',\n embed: 'plyr__video-embed',\n embedContainer: 'plyr__video-embed__container',\n poster: 'plyr__poster',\n posterEnabled: 'plyr__poster-enabled',\n ads: 'plyr__ads',\n control: 'plyr__control',\n controlPressed: 'plyr__control--pressed',\n playing: 'plyr--playing',\n paused: 'plyr--paused',\n stopped: 'plyr--stopped',\n loading: 'plyr--loading',\n hover: 'plyr--hover',\n tooltip: 'plyr__tooltip',\n cues: 'plyr__cues',\n hidden: 'plyr__sr-only',\n hideControls: 'plyr--hide-controls',\n isIos: 'plyr--is-ios',\n isTouch: 'plyr--is-touch',\n uiSupported: 'plyr--full-ui',\n noTransition: 'plyr--no-transition',\n display: {\n time: 'plyr__time',\n },\n menu: {\n value: 'plyr__menu__value',\n badge: 'plyr__badge',\n open: 'plyr--menu-open',\n },\n captions: {\n enabled: 'plyr--captions-enabled',\n active: 'plyr--captions-active',\n },\n fullscreen: {\n enabled: 'plyr--fullscreen-enabled',\n fallback: 'plyr--fullscreen-fallback',\n },\n pip: {\n supported: 'plyr--pip-supported',\n active: 'plyr--pip-active',\n },\n airplay: {\n supported: 'plyr--airplay-supported',\n active: 'plyr--airplay-active',\n },\n tabFocus: 'plyr__tab-focus',\n },\n\n // Embed attributes\n attributes: {\n embed: {\n provider: 'data-plyr-provider',\n id: 'data-plyr-embed-id',\n },\n },\n\n // API keys\n keys: {\n google: null,\n },\n\n // Advertisements plugin\n // Register for an account here: http://vi.ai/publisher-video-monetization/?aid=plyrio\n ads: {\n enabled: false,\n publisherId: '',\n },\n};\n\nexport default defaults;\n","// ==========================================================================\n// Plyr supported types and providers\n// ==========================================================================\n\nexport const providers = {\n html5: 'html5',\n youtube: 'youtube',\n vimeo: 'vimeo',\n};\n\nexport const types = {\n audio: 'audio',\n video: 'video',\n};\n\n/**\n * Get provider by URL\n * @param {string} url\n */\nexport function getProviderByUrl(url) {\n // YouTube\n if (/^(https?:\\/\\/)?(www\\.)?(youtube\\.com|youtu\\.?be)\\/.+$/.test(url)) {\n return providers.youtube;\n }\n\n // Vimeo\n if (/^https?:\\/\\/player.vimeo.com\\/video\\/\\d{0,9}(?=\\b|\\/)/.test(url)) {\n return providers.vimeo;\n }\n\n return null;\n}\n\nexport default { providers, types };\n","// ==========================================================================\n// Console wrapper\n// ==========================================================================\n\nconst noop = () => {};\n\nexport default class Console {\n constructor(enabled = false) {\n this.enabled = window.console && enabled;\n\n if (this.enabled) {\n this.log('Debugging enabled');\n }\n }\n\n get log() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.log, console) : noop;\n }\n get warn() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.warn, console) : noop;\n }\n get error() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.error, console) : noop;\n }\n}\n","// ==========================================================================\n// Fullscreen wrapper\n// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API#prefixing\n// ==========================================================================\n\nimport browser from './utils/browser';\nimport { hasClass, toggleClass, trapFocus } from './utils/elements';\nimport { on, triggerEvent } from './utils/events';\nimport is from './utils/is';\n\nfunction onChange() {\n if (!this.enabled) {\n return;\n }\n\n // Update toggle button\n const button = this.player.elements.buttons.fullscreen;\n if (is.element(button)) {\n button.pressed = this.active;\n }\n\n // Trigger an event\n triggerEvent.call(this.player, this.target, this.active ? 'enterfullscreen' : 'exitfullscreen', true);\n\n // Trap focus in container\n if (!browser.isIos) {\n trapFocus.call(this.player, this.target, this.active);\n }\n}\n\nfunction toggleFallback(toggle = false) {\n // Store or restore scroll position\n if (toggle) {\n this.scrollPosition = {\n x: window.scrollX || 0,\n y: window.scrollY || 0,\n };\n } else {\n window.scrollTo(this.scrollPosition.x, this.scrollPosition.y);\n }\n\n // Toggle scroll\n document.body.style.overflow = toggle ? 'hidden' : '';\n\n // Toggle class hook\n toggleClass(this.target, this.player.config.classNames.fullscreen.fallback, toggle);\n\n // Toggle button and fire events\n onChange.call(this);\n}\n\nclass Fullscreen {\n constructor(player) {\n // Keep reference to parent\n this.player = player;\n\n // Get prefix\n this.prefix = Fullscreen.prefix;\n this.property = Fullscreen.property;\n\n // Scroll position\n this.scrollPosition = { x: 0, y: 0 };\n\n // Register event listeners\n // Handle event (incase user presses escape etc)\n on.call(\n this.player,\n document,\n this.prefix === 'ms' ? 'MSFullscreenChange' : `${this.prefix}fullscreenchange`,\n () => {\n // TODO: Filter for target??\n onChange.call(this);\n },\n );\n\n // Fullscreen toggle on double click\n on.call(this.player, this.player.elements.container, 'dblclick', event => {\n // Ignore double click in controls\n if (is.element(this.player.elements.controls) && this.player.elements.controls.contains(event.target)) {\n return;\n }\n\n this.toggle();\n });\n\n // Update the UI\n this.update();\n }\n\n // Determine if native supported\n static get native() {\n return !!(\n document.fullscreenEnabled ||\n document.webkitFullscreenEnabled ||\n document.mozFullScreenEnabled ||\n document.msFullscreenEnabled\n );\n }\n\n // Get the prefix for handlers\n static get prefix() {\n // No prefix\n if (is.function(document.exitFullscreen)) {\n return '';\n }\n\n // Check for fullscreen support by vendor prefix\n let value = '';\n const prefixes = ['webkit', 'moz', 'ms'];\n\n prefixes.some(pre => {\n if (is.function(document[`${pre}ExitFullscreen`]) || is.function(document[`${pre}CancelFullScreen`])) {\n value = pre;\n return true;\n }\n\n return false;\n });\n\n return value;\n }\n\n static get property() {\n return this.prefix === 'moz' ? 'FullScreen' : 'Fullscreen';\n }\n\n // Determine if fullscreen is enabled\n get enabled() {\n return (\n (Fullscreen.native || this.player.config.fullscreen.fallback) &&\n this.player.config.fullscreen.enabled &&\n this.player.supported.ui &&\n this.player.isVideo\n );\n }\n\n // Get active state\n get active() {\n if (!this.enabled) {\n return false;\n }\n\n // Fallback using classname\n if (!Fullscreen.native) {\n return hasClass(this.target, this.player.config.classNames.fullscreen.fallback);\n }\n\n const element = !this.prefix ? document.fullscreenElement : document[`${this.prefix}${this.property}Element`];\n\n return element === this.target;\n }\n\n // Get target element\n get target() {\n return browser.isIos && this.player.config.fullscreen.iosNative\n ? this.player.media\n : this.player.elements.container;\n }\n\n // Update UI\n update() {\n if (this.enabled) {\n this.player.debug.log(`${Fullscreen.native ? 'Native' : 'Fallback'} fullscreen enabled`);\n } else {\n this.player.debug.log('Fullscreen not supported and fallback disabled');\n }\n\n // Add styling hook to show button\n toggleClass(this.player.elements.container, this.player.config.classNames.fullscreen.enabled, this.enabled);\n }\n\n // Make an element fullscreen\n enter() {\n if (!this.enabled) {\n return;\n }\n\n // iOS native fullscreen doesn't need the request step\n if (browser.isIos && this.player.config.fullscreen.iosNative) {\n if (this.player.playing) {\n this.target.webkitEnterFullscreen();\n }\n } else if (!Fullscreen.native) {\n toggleFallback.call(this, true);\n } else if (!this.prefix) {\n this.target.requestFullscreen();\n } else if (!is.empty(this.prefix)) {\n this.target[`${this.prefix}Request${this.property}`]();\n }\n }\n\n // Bail from fullscreen\n exit() {\n if (!this.enabled) {\n return;\n }\n\n // iOS native fullscreen\n if (browser.isIos && this.player.config.fullscreen.iosNative) {\n this.target.webkitExitFullscreen();\n this.player.play();\n } else if (!Fullscreen.native) {\n toggleFallback.call(this, false);\n } else if (!this.prefix) {\n (document.cancelFullScreen || document.exitFullscreen).call(document);\n } else if (!is.empty(this.prefix)) {\n const action = this.prefix === 'moz' ? 'Cancel' : 'Exit';\n document[`${this.prefix}${action}${this.property}`]();\n }\n }\n\n // Toggle state\n toggle() {\n if (!this.active) {\n this.enter();\n } else {\n this.exit();\n }\n }\n}\n\nexport default Fullscreen;\n","// ==========================================================================\n// Load image avoiding xhr/fetch CORS issues\n// Server status can't be obtained this way unfortunately, so this uses \"naturalWidth\" to determine if the image has loaded\n// By default it checks if it is at least 1px, but you can add a second argument to change this\n// ==========================================================================\n\nexport default function loadImage(src, minWidth = 1) {\n return new Promise((resolve, reject) => {\n const image = new Image();\n\n const handler = () => {\n delete image.onload;\n delete image.onerror;\n (image.naturalWidth >= minWidth ? resolve : reject)(image);\n };\n\n Object.assign(image, { onload: handler, onerror: handler, src });\n });\n}\n","// ==========================================================================\n// Plyr UI\n// ==========================================================================\n\nimport captions from './captions';\nimport controls from './controls';\nimport i18n from './i18n';\nimport support from './support';\nimport browser from './utils/browser';\nimport { getElement, toggleClass } from './utils/elements';\nimport { ready, triggerEvent } from './utils/events';\nimport is from './utils/is';\nimport loadImage from './utils/loadImage';\n\nconst ui = {\n addStyleHook() {\n toggleClass(this.elements.container, this.config.selectors.container.replace('.', ''), true);\n toggleClass(this.elements.container, this.config.classNames.uiSupported, this.supported.ui);\n },\n\n // Toggle native HTML5 media controls\n toggleNativeControls(toggle = false) {\n if (toggle && this.isHTML5) {\n this.media.setAttribute('controls', '');\n } else {\n this.media.removeAttribute('controls');\n }\n },\n\n // Setup the UI\n build() {\n // Re-attach media element listeners\n // TODO: Use event bubbling?\n this.listeners.media();\n\n // Don't setup interface if no support\n if (!this.supported.ui) {\n this.debug.warn(`Basic support only for ${this.provider} ${this.type}`);\n\n // Restore native controls\n ui.toggleNativeControls.call(this, true);\n\n // Bail\n return;\n }\n\n // Inject custom controls if not present\n if (!is.element(this.elements.controls)) {\n // Inject custom controls\n controls.inject.call(this);\n\n // Re-attach control listeners\n this.listeners.controls();\n }\n\n // Remove native controls\n ui.toggleNativeControls.call(this);\n\n // Setup captions for HTML5\n if (this.isHTML5) {\n captions.setup.call(this);\n }\n\n // Reset volume\n this.volume = null;\n\n // Reset mute state\n this.muted = null;\n\n // Reset speed\n this.speed = null;\n\n // Reset loop state\n this.loop = null;\n\n // Reset quality setting\n this.quality = null;\n\n // Reset volume display\n controls.updateVolume.call(this);\n\n // Reset time display\n controls.timeUpdate.call(this);\n\n // Update the UI\n ui.checkPlaying.call(this);\n\n // Check for picture-in-picture support\n toggleClass(\n this.elements.container,\n this.config.classNames.pip.supported,\n support.pip && this.isHTML5 && this.isVideo,\n );\n\n // Check for airplay support\n toggleClass(this.elements.container, this.config.classNames.airplay.supported, support.airplay && this.isHTML5);\n\n // Add iOS class\n toggleClass(this.elements.container, this.config.classNames.isIos, browser.isIos);\n\n // Add touch class\n toggleClass(this.elements.container, this.config.classNames.isTouch, this.touch);\n\n // Ready for API calls\n this.ready = true;\n\n // Ready event at end of execution stack\n setTimeout(() => {\n triggerEvent.call(this, this.media, 'ready');\n }, 0);\n\n // Set the title\n ui.setTitle.call(this);\n\n // Assure the poster image is set, if the property was added before the element was created\n if (this.poster) {\n ui.setPoster.call(this, this.poster, false).catch(() => {});\n }\n\n // Manually set the duration if user has overridden it.\n // The event listeners for it doesn't get called if preload is disabled (#701)\n if (this.config.duration) {\n controls.durationUpdate.call(this);\n }\n },\n\n // Setup aria attribute for play and iframe title\n setTitle() {\n // Find the current text\n let label = i18n.get('play', this.config);\n\n // If there's a media title set, use that for the label\n if (is.string(this.config.title) && !is.empty(this.config.title)) {\n label += `, ${this.config.title}`;\n }\n\n // If there's a play button, set label\n if (is.nodeList(this.elements.buttons.play)) {\n Array.from(this.elements.buttons.play).forEach(button => {\n button.setAttribute('aria-label', label);\n });\n }\n\n // Set iframe title\n // https://github.com/sampotts/plyr/issues/124\n if (this.isEmbed) {\n const iframe = getElement.call(this, 'iframe');\n\n if (!is.element(iframe)) {\n return;\n }\n\n // Default to media type\n const title = !is.empty(this.config.title) ? this.config.title : 'video';\n const format = i18n.get('frameTitle', this.config);\n\n iframe.setAttribute('title', format.replace('{title}', title));\n }\n },\n\n // Toggle poster\n togglePoster(enable) {\n toggleClass(this.elements.container, this.config.classNames.posterEnabled, enable);\n },\n\n // Set the poster image (async)\n // Used internally for the poster setter, with the passive option forced to false\n setPoster(poster, passive = true) {\n // Don't override if call is passive\n if (passive && this.poster) {\n return Promise.reject(new Error('Poster already set'));\n }\n\n // Set property synchronously to respect the call order\n this.media.setAttribute('poster', poster);\n\n // Wait until ui is ready\n return (\n ready\n .call(this)\n // Load image\n .then(() => loadImage(poster))\n .catch(err => {\n // Hide poster on error unless it's been set by another call\n if (poster === this.poster) {\n ui.togglePoster.call(this, false);\n }\n // Rethrow\n throw err;\n })\n .then(() => {\n // Prevent race conditions\n if (poster !== this.poster) {\n throw new Error('setPoster cancelled by later call to setPoster');\n }\n })\n .then(() => {\n Object.assign(this.elements.poster.style, {\n backgroundImage: `url('${poster}')`,\n // Reset backgroundSize as well (since it can be set to \"cover\" for padded thumbnails for youtube)\n backgroundSize: '',\n });\n ui.togglePoster.call(this, true);\n return poster;\n })\n );\n },\n\n // Check playing state\n checkPlaying(event) {\n // Class hooks\n toggleClass(this.elements.container, this.config.classNames.playing, this.playing);\n toggleClass(this.elements.container, this.config.classNames.paused, this.paused);\n toggleClass(this.elements.container, this.config.classNames.stopped, this.stopped);\n\n // Set state\n if (is.nodeList(this.elements.buttons.play)) {\n Array.from(this.elements.buttons.play).forEach(target => {\n target.pressed = this.playing;\n });\n }\n\n // Only update controls on non timeupdate events\n if (is.event(event) && event.type === 'timeupdate') {\n return;\n }\n\n // Toggle controls\n ui.toggleControls.call(this);\n },\n\n // Check if media is loading\n checkLoading(event) {\n this.loading = ['stalled', 'waiting'].includes(event.type);\n\n // Clear timer\n clearTimeout(this.timers.loading);\n\n // Timer to prevent flicker when seeking\n this.timers.loading = setTimeout(() => {\n // Update progress bar loading class state\n toggleClass(this.elements.container, this.config.classNames.loading, this.loading);\n\n // Update controls visibility\n ui.toggleControls.call(this);\n }, this.loading ? 250 : 0);\n },\n\n // Toggle controls based on state and `force` argument\n toggleControls(force) {\n const { controls } = this.elements;\n\n if (controls && this.config.hideControls) {\n // Show controls if force, loading, paused, or button interaction, otherwise hide\n this.toggleControls(Boolean(force || this.loading || this.paused || controls.pressed || controls.hover));\n }\n },\n};\n\nexport default ui;\n","// ==========================================================================\n// Plyr Event Listeners\n// ==========================================================================\n\nimport controls from './controls';\nimport ui from './ui';\nimport browser from './utils/browser';\nimport { getElement, getElements, getFocusElement, matches, toggleClass, toggleHidden } from './utils/elements';\nimport { on, once, toggleListener, triggerEvent } from './utils/events';\nimport is from './utils/is';\n\nclass Listeners {\n constructor(player) {\n this.player = player;\n this.lastKey = null;\n\n this.handleKey = this.handleKey.bind(this);\n this.toggleMenu = this.toggleMenu.bind(this);\n this.firstTouch = this.firstTouch.bind(this);\n }\n\n // Handle key presses\n handleKey(event) {\n const code = event.keyCode ? event.keyCode : event.which;\n const pressed = event.type === 'keydown';\n const repeat = pressed && code === this.lastKey;\n\n // Bail if a modifier key is set\n if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {\n return;\n }\n\n // If the event is bubbled from the media element\n // Firefox doesn't get the keycode for whatever reason\n if (!is.number(code)) {\n return;\n }\n\n // Seek by the number keys\n const seekByKey = () => {\n // Divide the max duration into 10th's and times by the number value\n this.player.currentTime = this.player.duration / 10 * (code - 48);\n };\n\n // Handle the key on keydown\n // Reset on keyup\n if (pressed) {\n // Which keycodes should we prevent default\n const preventDefault = [32, 37, 38, 39, 40, 48, 49, 50, 51, 52, 53, 54, 56, 57, 67, 70, 73, 75, 76, 77, 79];\n\n // Check focused element\n // and if the focused element is not editable (e.g. text input)\n // and any that accept key input http://webaim.org/techniques/keyboard/\n const focused = getFocusElement();\n if (\n is.element(focused) &&\n (focused !== this.player.elements.inputs.seek &&\n matches(focused, this.player.config.selectors.editable))\n ) {\n return;\n }\n\n // If the code is found prevent default (e.g. prevent scrolling for arrows)\n if (preventDefault.includes(code)) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n switch (code) {\n case 48:\n case 49:\n case 50:\n case 51:\n case 52:\n case 53:\n case 54:\n case 55:\n case 56:\n case 57:\n // 0-9\n if (!repeat) {\n seekByKey();\n }\n break;\n\n case 32:\n case 75:\n // Space and K key\n if (!repeat) {\n this.player.togglePlay();\n }\n break;\n\n case 38:\n // Arrow up\n this.player.increaseVolume(0.1);\n break;\n\n case 40:\n // Arrow down\n this.player.decreaseVolume(0.1);\n break;\n\n case 77:\n // M key\n if (!repeat) {\n this.player.muted = !this.player.muted;\n }\n break;\n\n case 39:\n // Arrow forward\n this.player.forward();\n break;\n\n case 37:\n // Arrow back\n this.player.rewind();\n break;\n\n case 70:\n // F key\n this.player.fullscreen.toggle();\n break;\n\n case 67:\n // C key\n if (!repeat) {\n this.player.toggleCaptions();\n }\n break;\n\n case 76:\n // L key\n this.player.loop = !this.player.loop;\n break;\n\n /* case 73:\n this.setLoop('start');\n break;\n\n case 76:\n this.setLoop();\n break;\n\n case 79:\n this.setLoop('end');\n break; */\n\n default:\n break;\n }\n\n // Escape is handle natively when in full screen\n // So we only need to worry about non native\n if (!this.player.fullscreen.enabled && this.player.fullscreen.active && code === 27) {\n this.player.fullscreen.toggle();\n }\n\n // Store last code for next cycle\n this.lastKey = code;\n } else {\n this.lastKey = null;\n }\n }\n\n // Toggle menu\n toggleMenu(event) {\n controls.toggleMenu.call(this.player, event);\n }\n\n // Device is touch enabled\n firstTouch() {\n this.player.touch = true;\n\n // Add touch class\n toggleClass(this.player.elements.container, this.player.config.classNames.isTouch, true);\n }\n\n // Global window & document listeners\n global(toggle = true) {\n // Keyboard shortcuts\n if (this.player.config.keyboard.global) {\n toggleListener.call(this.player, window, 'keydown keyup', this.handleKey, toggle, false);\n }\n\n // Click anywhere closes menu\n toggleListener.call(this.player, document.body, 'click', this.toggleMenu, toggle);\n\n // Detect touch by events\n once.call(this.player, document.body, 'touchstart', this.firstTouch);\n }\n\n // Container listeners\n container() {\n // Keyboard shortcuts\n if (!this.player.config.keyboard.global && this.player.config.keyboard.focused) {\n on.call(this.player, this.player.elements.container, 'keydown keyup', this.handleKey, false);\n }\n\n // Detect tab focus\n // Remove class on blur/focusout\n on.call(this.player, this.player.elements.container, 'focusout', event => {\n toggleClass(event.target, this.player.config.classNames.tabFocus, false);\n });\n // Add classname to tabbed elements\n on.call(this.player, this.player.elements.container, 'keydown', event => {\n if (event.keyCode !== 9) {\n return;\n }\n\n // Delay the adding of classname until the focus has changed\n // This event fires before the focusin event\n setTimeout(() => {\n toggleClass(getFocusElement(), this.player.config.classNames.tabFocus, true);\n }, 0);\n });\n\n // Toggle controls on mouse events and entering fullscreen\n on.call(\n this.player,\n this.player.elements.container,\n 'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen',\n event => {\n const { controls } = this.player.elements;\n\n // Remove button states for fullscreen\n if (event.type === 'enterfullscreen') {\n controls.pressed = false;\n controls.hover = false;\n }\n\n // Show, then hide after a timeout unless another control event occurs\n const show = ['touchstart', 'touchmove', 'mousemove'].includes(event.type);\n\n let delay = 0;\n\n if (show) {\n ui.toggleControls.call(this.player, true);\n // Use longer timeout for touch devices\n delay = this.player.touch ? 3000 : 2000;\n }\n\n // Clear timer\n clearTimeout(this.player.timers.controls);\n // Timer to prevent flicker when seeking\n this.player.timers.controls = setTimeout(() => ui.toggleControls.call(this.player, false), delay);\n },\n );\n }\n\n // Listen for media events\n media() {\n // Time change on media\n on.call(this.player, this.player.media, 'timeupdate seeking seeked', event =>\n controls.timeUpdate.call(this.player, event),\n );\n\n // Display duration\n on.call(this.player, this.player.media, 'durationchange loadeddata loadedmetadata', event =>\n controls.durationUpdate.call(this.player, event),\n );\n\n // Check for audio tracks on load\n // We can't use `loadedmetadata` as it doesn't seem to have audio tracks at that point\n on.call(this.player, this.player.media, 'canplay', () => {\n toggleHidden(this.player.elements.volume, !this.player.hasAudio);\n toggleHidden(this.player.elements.buttons.mute, !this.player.hasAudio);\n });\n\n // Handle the media finishing\n on.call(this.player, this.player.media, 'ended', () => {\n // Show poster on end\n if (this.player.isHTML5 && this.player.isVideo && this.player.config.resetOnEnd) {\n // Restart\n this.player.restart();\n }\n });\n\n // Check for buffer progress\n on.call(this.player, this.player.media, 'progress playing seeking seeked', event =>\n controls.updateProgress.call(this.player, event),\n );\n\n // Handle volume changes\n on.call(this.player, this.player.media, 'volumechange', event =>\n controls.updateVolume.call(this.player, event),\n );\n\n // Handle play/pause\n on.call(this.player, this.player.media, 'playing play pause ended emptied timeupdate', event =>\n ui.checkPlaying.call(this.player, event),\n );\n\n // Loading state\n on.call(this.player, this.player.media, 'waiting canplay seeked playing', event =>\n ui.checkLoading.call(this.player, event),\n );\n\n // If autoplay, then load advertisement if required\n // TODO: Show some sort of loading state while the ad manager loads else there's a delay before ad shows\n on.call(this.player, this.player.media, 'playing', () => {\n if (!this.player.ads) {\n return;\n }\n\n // If ads are enabled, wait for them first\n if (this.player.ads.enabled && !this.player.ads.initialized) {\n // Wait for manager response\n this.player.ads.managerPromise.then(() => this.player.ads.play()).catch(() => this.player.play());\n }\n });\n\n // Click video\n if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) {\n // Re-fetch the wrapper\n const wrapper = getElement.call(this.player, `.${this.player.config.classNames.video}`);\n\n // Bail if there's no wrapper (this should never happen)\n if (!is.element(wrapper)) {\n return;\n }\n\n // On click play, pause ore restart\n on.call(this.player, wrapper, 'click', () => {\n // Touch devices will just show controls (if we're hiding controls)\n if (this.player.config.hideControls && this.player.touch && !this.player.paused) {\n return;\n }\n\n if (this.player.paused) {\n this.player.play();\n } else if (this.player.ended) {\n this.player.restart();\n this.player.play();\n } else {\n this.player.pause();\n }\n });\n }\n\n // Disable right click\n if (this.player.supported.ui && this.player.config.disableContextMenu) {\n on.call(\n this.player,\n this.player.elements.wrapper,\n 'contextmenu',\n event => {\n event.preventDefault();\n },\n false,\n );\n }\n\n // Volume change\n on.call(this.player, this.player.media, 'volumechange', () => {\n // Save to storage\n this.player.storage.set({ volume: this.player.volume, muted: this.player.muted });\n });\n\n // Speed change\n on.call(this.player, this.player.media, 'ratechange', () => {\n // Update UI\n controls.updateSetting.call(this.player, 'speed');\n\n // Save to storage\n this.player.storage.set({ speed: this.player.speed });\n });\n\n // Quality request\n on.call(this.player, this.player.media, 'qualityrequested', event => {\n // Save to storage\n this.player.storage.set({ quality: event.detail.quality });\n });\n\n // Quality change\n on.call(this.player, this.player.media, 'qualitychange', event => {\n // Update UI\n controls.updateSetting.call(this.player, 'quality', null, event.detail.quality);\n });\n\n // Proxy events to container\n // Bubble up key events for Edge\n const proxyEvents = this.player.config.events.concat(['keyup', 'keydown']).join(' ');\n on.call(this.player, this.player.media, proxyEvents, event => {\n let { detail = {} } = event;\n\n // Get error details from media\n if (event.type === 'error') {\n detail = this.player.media.error;\n }\n\n triggerEvent.call(this.player, this.player.elements.container, event.type, true, detail);\n });\n }\n\n // Listen for control events\n controls() {\n // IE doesn't support input event, so we fallback to change\n const inputEvent = browser.isIE ? 'change' : 'input';\n\n // Run default and custom handlers\n const proxy = (event, defaultHandler, customHandlerKey) => {\n const customHandler = this.player.config.listeners[customHandlerKey];\n const hasCustomHandler = is.function(customHandler);\n let returned = true;\n\n // Execute custom handler\n if (hasCustomHandler) {\n returned = customHandler.call(this.player, event);\n }\n\n // Only call default handler if not prevented in custom handler\n if (returned && is.function(defaultHandler)) {\n defaultHandler.call(this.player, event);\n }\n };\n\n // Trigger custom and default handlers\n const bind = (element, type, defaultHandler, customHandlerKey, passive = true) => {\n const customHandler = this.player.config.listeners[customHandlerKey];\n const hasCustomHandler = is.function(customHandler);\n\n on.call(\n this.player,\n element,\n type,\n event => proxy(event, defaultHandler, customHandlerKey),\n passive && !hasCustomHandler,\n );\n };\n\n // Play/pause toggle\n Array.from(this.player.elements.buttons.play).forEach(button => {\n bind(button, 'click', this.player.togglePlay, 'play');\n });\n\n // Pause\n bind(this.player.elements.buttons.restart, 'click', this.player.restart, 'restart');\n\n // Rewind\n bind(this.player.elements.buttons.rewind, 'click', this.player.rewind, 'rewind');\n\n // Rewind\n bind(this.player.elements.buttons.fastForward, 'click', this.player.forward, 'fastForward');\n\n // Mute toggle\n bind(\n this.player.elements.buttons.mute,\n 'click',\n () => {\n this.player.muted = !this.player.muted;\n },\n 'mute',\n );\n\n // Captions toggle\n bind(this.player.elements.buttons.captions, 'click', () => this.player.toggleCaptions());\n\n // Fullscreen toggle\n bind(\n this.player.elements.buttons.fullscreen,\n 'click',\n () => {\n this.player.fullscreen.toggle();\n },\n 'fullscreen',\n );\n\n // Picture-in-Picture\n bind(\n this.player.elements.buttons.pip,\n 'click',\n () => {\n this.player.pip = 'toggle';\n },\n 'pip',\n );\n\n // Airplay\n bind(this.player.elements.buttons.airplay, 'click', this.player.airplay, 'airplay');\n\n // Settings menu\n bind(this.player.elements.buttons.settings, 'click', event => {\n controls.toggleMenu.call(this.player, event);\n });\n\n // Settings menu\n bind(this.player.elements.settings.popup, 'click', event => {\n event.stopPropagation();\n\n // Go back to home tab on click\n const showHomeTab = () => {\n controls.showMenuPanel.call(this.player, 'home');\n };\n\n // Settings menu items - use event delegation as items are added/removed\n if (matches(event.target, this.player.config.selectors.inputs.language)) {\n proxy(\n event,\n () => {\n this.player.currentTrack = Number(event.target.value);\n showHomeTab();\n },\n 'language',\n );\n } else if (matches(event.target, this.player.config.selectors.inputs.quality)) {\n proxy(\n event,\n () => {\n this.player.quality = event.target.value;\n showHomeTab();\n },\n 'quality',\n );\n } else if (matches(event.target, this.player.config.selectors.inputs.speed)) {\n proxy(\n event,\n () => {\n this.player.speed = parseFloat(event.target.value);\n showHomeTab();\n },\n 'speed',\n );\n }\n });\n\n // Set range input alternative \"value\", which matches the tooltip time (#954)\n bind(this.player.elements.inputs.seek, 'mousedown mousemove', event => {\n const clientRect = this.player.elements.progress.getBoundingClientRect();\n const percent = 100 / clientRect.width * (event.pageX - clientRect.left);\n event.currentTarget.setAttribute('seek-value', percent);\n });\n\n // Pause while seeking\n bind(this.player.elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', event => {\n const seek = event.currentTarget;\n\n const code = event.keyCode ? event.keyCode : event.which;\n const eventType = event.type;\n\n if ((eventType === 'keydown' || eventType === 'keyup') && (code !== 39 && code !== 37)) {\n return;\n }\n // Was playing before?\n const play = seek.hasAttribute('play-on-seeked');\n\n // Done seeking\n const done = ['mouseup', 'touchend', 'keyup'].includes(event.type);\n\n // If we're done seeking and it was playing, resume playback\n if (play && done) {\n seek.removeAttribute('play-on-seeked');\n this.player.play();\n } else if (!done && this.player.playing) {\n seek.setAttribute('play-on-seeked', '');\n this.player.pause();\n }\n });\n\n // Seek\n bind(\n this.player.elements.inputs.seek,\n inputEvent,\n event => {\n const seek = event.currentTarget;\n\n // If it exists, use seek-value instead of \"value\" for consistency with tooltip time (#954)\n let seekTo = seek.getAttribute('seek-value');\n\n if (is.empty(seekTo)) {\n seekTo = seek.value;\n }\n\n seek.removeAttribute('seek-value');\n\n this.player.currentTime = seekTo / seek.max * this.player.duration;\n },\n 'seek',\n );\n\n // Current time invert\n // Only if one time element is used for both currentTime and duration\n if (this.player.config.toggleInvert && !is.element(this.player.elements.display.duration)) {\n bind(this.player.elements.display.currentTime, 'click', () => {\n // Do nothing if we're at the start\n if (this.player.currentTime === 0) {\n return;\n }\n\n this.player.config.invertTime = !this.player.config.invertTime;\n\n controls.timeUpdate.call(this.player);\n });\n }\n\n // Volume\n bind(\n this.player.elements.inputs.volume,\n inputEvent,\n event => {\n this.player.volume = event.target.value;\n },\n 'volume',\n );\n\n // Polyfill for lower fill in <input type=\"range\"> for webkit\n if (browser.isWebkit) {\n Array.from(getElements.call(this.player, 'input[type=\"range\"]')).forEach(element => {\n bind(element, 'input', event => controls.updateRangeFill.call(this.player, event.target));\n });\n }\n\n // Seek tooltip\n bind(this.player.elements.progress, 'mouseenter mouseleave mousemove', event =>\n controls.updateSeekTooltip.call(this.player, event),\n );\n\n // Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)\n bind(this.player.elements.controls, 'mouseenter mouseleave', event => {\n this.player.elements.controls.hover = !this.player.touch && event.type === 'mouseenter';\n });\n\n // Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)\n bind(this.player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {\n this.player.elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);\n });\n\n // Focus in/out on controls\n bind(this.player.elements.controls, 'focusin focusout', event => {\n const { config, elements, timers } = this.player;\n\n // Skip transition to prevent focus from scrolling the parent element\n toggleClass(elements.controls, config.classNames.noTransition, event.type === 'focusin');\n\n // Toggle\n ui.toggleControls.call(this.player, event.type === 'focusin');\n\n // If focusin, hide again after delay\n if (event.type === 'focusin') {\n // Restore transition\n setTimeout(() => {\n toggleClass(elements.controls, config.classNames.noTransition, false);\n }, 0);\n\n // Delay a little more for keyboard users\n const delay = this.touch ? 3000 : 4000;\n\n // Clear timer\n clearTimeout(timers.controls);\n // Hide\n timers.controls = setTimeout(() => ui.toggleControls.call(this.player, false), delay);\n }\n });\n\n // Mouse wheel for volume\n bind(\n this.player.elements.inputs.volume,\n 'wheel',\n event => {\n // Detect \"natural\" scroll - suppored on OS X Safari only\n // Other browsers on OS X will be inverted until support improves\n const inverted = event.webkitDirectionInvertedFromDevice;\n const step = 1 / 50;\n let direction = 0;\n\n // Scroll down (or up on natural) to decrease\n if (event.deltaY < 0 || event.deltaX > 0) {\n if (inverted) {\n this.player.decreaseVolume(step);\n direction = -1;\n } else {\n this.player.increaseVolume(step);\n direction = 1;\n }\n }\n\n // Scroll up (or down on natural) to increase\n if (event.deltaY > 0 || event.deltaX < 0) {\n if (inverted) {\n this.player.increaseVolume(step);\n direction = 1;\n } else {\n this.player.decreaseVolume(step);\n direction = -1;\n }\n }\n\n // Don't break page scrolling at max and min\n if (\n (direction === 1 && this.player.media.volume < 1) ||\n (direction === -1 && this.player.media.volume > 0)\n ) {\n event.preventDefault();\n }\n },\n 'volume',\n false,\n );\n }\n}\n\nexport default Listeners;\n","(function(root, factory) {\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.loadjs = factory();\n }\n}(this, function() {\n/**\n * Global dependencies.\n * @global {Object} document - DOM\n */\n\nvar devnull = function() {},\n bundleIdCache = {},\n bundleResultCache = {},\n bundleCallbackQueue = {};\n\n\n/**\n * Subscribe to bundle load event.\n * @param {string[]} bundleIds - Bundle ids\n * @param {Function} callbackFn - The callback function\n */\nfunction subscribe(bundleIds, callbackFn) {\n // listify\n bundleIds = bundleIds.push ? bundleIds : [bundleIds];\n\n var depsNotFound = [],\n i = bundleIds.length,\n numWaiting = i,\n fn,\n bundleId,\n r,\n q;\n\n // define callback function\n fn = function (bundleId, pathsNotFound) {\n if (pathsNotFound.length) depsNotFound.push(bundleId);\n\n numWaiting--;\n if (!numWaiting) callbackFn(depsNotFound);\n };\n\n // register callback\n while (i--) {\n bundleId = bundleIds[i];\n\n // execute callback if in result cache\n r = bundleResultCache[bundleId];\n if (r) {\n fn(bundleId, r);\n continue;\n }\n\n // add to callback queue\n q = bundleCallbackQueue[bundleId] = bundleCallbackQueue[bundleId] || [];\n q.push(fn);\n }\n}\n\n\n/**\n * Publish bundle load event.\n * @param {string} bundleId - Bundle id\n * @param {string[]} pathsNotFound - List of files not found\n */\nfunction publish(bundleId, pathsNotFound) {\n // exit if id isn't defined\n if (!bundleId) return;\n\n var q = bundleCallbackQueue[bundleId];\n\n // cache result\n bundleResultCache[bundleId] = pathsNotFound;\n\n // exit if queue is empty\n if (!q) return;\n\n // empty callback queue\n while (q.length) {\n q[0](bundleId, pathsNotFound);\n q.splice(0, 1);\n }\n}\n\n\n/**\n * Execute callbacks.\n * @param {Object or Function} args - The callback args\n * @param {string[]} depsNotFound - List of dependencies not found\n */\nfunction executeCallbacks(args, depsNotFound) {\n // accept function as argument\n if (args.call) args = {success: args};\n\n // success and error callbacks\n if (depsNotFound.length) (args.error || devnull)(depsNotFound);\n else (args.success || devnull)(args);\n}\n\n\n/**\n * Load individual file.\n * @param {string} path - The file path\n * @param {Function} callbackFn - The callback function\n */\nfunction loadFile(path, callbackFn, args, numTries) {\n var doc = document,\n async = args.async,\n maxTries = (args.numRetries || 0) + 1,\n beforeCallbackFn = args.before || devnull,\n pathStripped = path.replace(/^(css|img)!/, ''),\n isCss,\n e;\n\n numTries = numTries || 0;\n\n if (/(^css!|\\.css$)/.test(path)) {\n isCss = true;\n\n // css\n e = doc.createElement('link');\n e.rel = 'stylesheet';\n e.href = pathStripped; //.replace(/^css!/, ''); // remove \"css!\" prefix\n } else if (/(^img!|\\.(png|gif|jpg|svg)$)/.test(path)) {\n // image\n e = doc.createElement('img');\n e.src = pathStripped; \n } else {\n // javascript\n e = doc.createElement('script');\n e.src = path;\n e.async = async === undefined ? true : async;\n }\n\n e.onload = e.onerror = e.onbeforeload = function (ev) {\n var result = ev.type[0];\n\n // Note: The following code isolates IE using `hideFocus` and treats empty\n // stylesheets as failures to get around lack of onerror support\n if (isCss && 'hideFocus' in e) {\n try {\n if (!e.sheet.cssText.length) result = 'e';\n } catch (x) {\n // sheets objects created from load errors don't allow access to\n // `cssText`\n result = 'e';\n }\n }\n\n // handle retries in case of load failure\n if (result == 'e') {\n // increment counter\n numTries += 1;\n\n // exit function and try again\n if (numTries < maxTries) {\n return loadFile(path, callbackFn, args, numTries);\n }\n }\n\n // execute callback\n callbackFn(path, result, ev.defaultPrevented);\n };\n\n // add to document (unless callback returns `false`)\n if (beforeCallbackFn(path, e) !== false) doc.head.appendChild(e);\n}\n\n\n/**\n * Load multiple files.\n * @param {string[]} paths - The file paths\n * @param {Function} callbackFn - The callback function\n */\nfunction loadFiles(paths, callbackFn, args) {\n // listify paths\n paths = paths.push ? paths : [paths];\n\n var numWaiting = paths.length,\n x = numWaiting,\n pathsNotFound = [],\n fn,\n i;\n\n // define callback function\n fn = function(path, result, defaultPrevented) {\n // handle error\n if (result == 'e') pathsNotFound.push(path);\n\n // handle beforeload event. If defaultPrevented then that means the load\n // will be blocked (ex. Ghostery/ABP on Safari)\n if (result == 'b') {\n if (defaultPrevented) pathsNotFound.push(path);\n else return;\n }\n\n numWaiting--;\n if (!numWaiting) callbackFn(pathsNotFound);\n };\n\n // load scripts\n for (i=0; i < x; i++) loadFile(paths[i], fn, args);\n}\n\n\n/**\n * Initiate script load and register bundle.\n * @param {(string|string[])} paths - The file paths\n * @param {(string|Function)} [arg1] - The bundleId or success callback\n * @param {Function} [arg2] - The success or error callback\n * @param {Function} [arg3] - The error callback\n */\nfunction loadjs(paths, arg1, arg2) {\n var bundleId,\n args;\n\n // bundleId (if string)\n if (arg1 && arg1.trim) bundleId = arg1;\n\n // args (default is {})\n args = (bundleId ? arg2 : arg1) || {};\n\n // throw error if bundle is already defined\n if (bundleId) {\n if (bundleId in bundleIdCache) {\n throw \"LoadJS\";\n } else {\n bundleIdCache[bundleId] = true;\n }\n }\n\n // load scripts\n loadFiles(paths, function (pathsNotFound) {\n // execute callbacks\n executeCallbacks(args, pathsNotFound);\n\n // publish bundle load event\n publish(bundleId, pathsNotFound);\n }, args);\n}\n\n\n/**\n * Execute callbacks when dependencies have been satisfied.\n * @param {(string|string[])} deps - List of bundle ids\n * @param {Object} args - success/error arguments\n */\nloadjs.ready = function ready(deps, args) {\n // subscribe to bundle load event\n subscribe(deps, function (depsNotFound) {\n // execute callbacks\n executeCallbacks(args, depsNotFound);\n });\n\n return loadjs;\n};\n\n\n/**\n * Manually satisfy bundle dependencies.\n * @param {string} bundleId - The bundle id\n */\nloadjs.done = function done(bundleId) {\n publish(bundleId, []);\n};\n\n\n/**\n * Reset loadjs dependencies statuses\n */\nloadjs.reset = function reset() {\n bundleIdCache = {};\n bundleResultCache = {};\n bundleCallbackQueue = {};\n};\n\n\n/**\n * Determine if bundle has already been defined\n * @param String} bundleId - The bundle id\n */\nloadjs.isDefined = function isDefined(bundleId) {\n return bundleId in bundleIdCache;\n};\n\n\n// export\nreturn loadjs;\n\n}));\n","// ==========================================================================\n// Load an external script\n// ==========================================================================\n\nimport loadjs from 'loadjs';\n\nexport default function loadScript(url) {\n return new Promise((resolve, reject) => {\n loadjs(url, {\n success: resolve,\n error: reject,\n });\n });\n}\n","// ==========================================================================\n// Vimeo plugin\n// ==========================================================================\n\nimport captions from './../captions';\nimport controls from './../controls';\nimport ui from './../ui';\nimport { createElement, replaceElement, toggleClass } from './../utils/elements';\nimport { triggerEvent } from './../utils/events';\nimport fetch from './../utils/fetch';\nimport is from './../utils/is';\nimport loadScript from './../utils/loadScript';\nimport { format, stripHTML } from './../utils/strings';\nimport { buildUrlParams } from './../utils/urls';\n\n// Parse Vimeo ID from URL\nfunction parseId(url) {\n if (is.empty(url)) {\n return null;\n }\n\n if (is.number(Number(url))) {\n return url;\n }\n\n const regex = /^.*(vimeo.com\\/|video\\/)(\\d+).*/;\n return url.match(regex) ? RegExp.$2 : url;\n}\n\n// Get aspect ratio for dimensions\nfunction getAspectRatio(width, height) {\n const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h));\n const ratio = getRatio(width, height);\n return `${width / ratio}:${height / ratio}`;\n}\n\n// Set playback state and trigger change (only on actual change)\nfunction assurePlaybackState(play) {\n if (play && !this.embed.hasPlayed) {\n this.embed.hasPlayed = true;\n }\n if (this.media.paused === play) {\n this.media.paused = !play;\n triggerEvent.call(this, this.media, play ? 'play' : 'pause');\n }\n}\n\nconst vimeo = {\n setup() {\n // Add embed class for responsive\n toggleClass(this.elements.wrapper, this.config.classNames.embed, true);\n\n // Set intial ratio\n vimeo.setAspectRatio.call(this);\n\n // Load the API if not already\n if (!is.object(window.Vimeo)) {\n loadScript(this.config.urls.vimeo.sdk)\n .then(() => {\n vimeo.ready.call(this);\n })\n .catch(error => {\n this.debug.warn('Vimeo API failed to load', error);\n });\n } else {\n vimeo.ready.call(this);\n }\n },\n\n // Set aspect ratio\n // For Vimeo we have an extra 300% height <div> to hide the standard controls and UI\n setAspectRatio(input) {\n const [x, y] = (is.string(input) ? input : this.config.ratio).split(':');\n const padding = 100 / x * y;\n this.elements.wrapper.style.paddingBottom = `${padding}%`;\n\n if (this.supported.ui) {\n const height = 240;\n const offset = (height - padding) / (height / 50);\n\n this.media.style.transform = `translateY(-${offset}%)`;\n }\n },\n\n // API Ready\n ready() {\n const player = this;\n\n // Get Vimeo params for the iframe\n const options = {\n loop: player.config.loop.active,\n autoplay: player.autoplay,\n // muted: player.muted,\n byline: false,\n portrait: false,\n title: false,\n speed: true,\n transparent: 0,\n gesture: 'media',\n playsinline: !this.config.fullscreen.iosNative,\n };\n const params = buildUrlParams(options);\n\n // Get the source URL or ID\n let source = player.media.getAttribute('src');\n\n // Get from <div> if needed\n if (is.empty(source)) {\n source = player.media.getAttribute(player.config.attributes.embed.id);\n }\n\n const id = parseId(source);\n\n // Build an iframe\n const iframe = createElement('iframe');\n const src = format(player.config.urls.vimeo.iframe, id, params);\n iframe.setAttribute('src', src);\n iframe.setAttribute('allowfullscreen', '');\n iframe.setAttribute('allowtransparency', '');\n iframe.setAttribute('allow', 'autoplay');\n\n // Get poster, if already set\n const { poster } = player;\n\n // Inject the package\n const wrapper = createElement('div', { poster, class: player.config.classNames.embedContainer });\n wrapper.appendChild(iframe);\n player.media = replaceElement(wrapper, player.media);\n\n // Get poster image\n fetch(format(player.config.urls.vimeo.api, id), 'json').then(response => {\n if (is.empty(response)) {\n return;\n }\n\n // Get the URL for thumbnail\n const url = new URL(response[0].thumbnail_large);\n\n // Get original image\n url.pathname = `${url.pathname.split('_')[0]}.jpg`;\n\n // Set and show poster\n ui.setPoster.call(player, url.href).catch(() => {});\n });\n\n // Setup instance\n // https://github.com/vimeo/player.js\n player.embed = new window.Vimeo.Player(iframe, {\n autopause: player.config.autopause,\n muted: player.muted,\n });\n\n player.media.paused = true;\n player.media.currentTime = 0;\n\n // Disable native text track rendering\n if (player.supported.ui) {\n player.embed.disableTextTrack();\n }\n\n // Create a faux HTML5 API using the Vimeo API\n player.media.play = () => {\n assurePlaybackState.call(player, true);\n return player.embed.play();\n };\n\n player.media.pause = () => {\n assurePlaybackState.call(player, false);\n return player.embed.pause();\n };\n\n player.media.stop = () => {\n player.pause();\n player.currentTime = 0;\n };\n\n // Seeking\n let { currentTime } = player.media;\n Object.defineProperty(player.media, 'currentTime', {\n get() {\n return currentTime;\n },\n set(time) {\n // Vimeo will automatically play on seek if the video hasn't been played before\n\n // Get current paused state and volume etc\n const { embed, media, paused, volume } = player;\n const restorePause = paused && !embed.hasPlayed;\n\n // Set seeking state and trigger event\n media.seeking = true;\n triggerEvent.call(player, media, 'seeking');\n\n // If paused, mute until seek is complete\n Promise.resolve(restorePause && embed.setVolume(0))\n // Seek\n .then(() => embed.setCurrentTime(time))\n // Restore paused\n .then(() => restorePause && embed.pause())\n // Restore volume\n .then(() => restorePause && embed.setVolume(volume))\n .catch(() => {\n // Do nothing\n });\n },\n });\n\n // Playback speed\n let speed = player.config.speed.selected;\n Object.defineProperty(player.media, 'playbackRate', {\n get() {\n return speed;\n },\n set(input) {\n player.embed\n .setPlaybackRate(input)\n .then(() => {\n speed = input;\n triggerEvent.call(player, player.media, 'ratechange');\n })\n .catch(error => {\n // Hide menu item (and menu if empty)\n if (error.name === 'Error') {\n controls.setSpeedMenu.call(player, []);\n }\n });\n },\n });\n\n // Volume\n let { volume } = player.config;\n Object.defineProperty(player.media, 'volume', {\n get() {\n return volume;\n },\n set(input) {\n player.embed.setVolume(input).then(() => {\n volume = input;\n triggerEvent.call(player, player.media, 'volumechange');\n });\n },\n });\n\n // Muted\n let { muted } = player.config;\n Object.defineProperty(player.media, 'muted', {\n get() {\n return muted;\n },\n set(input) {\n const toggle = is.boolean(input) ? input : false;\n\n player.embed.setVolume(toggle ? 0 : player.config.volume).then(() => {\n muted = toggle;\n triggerEvent.call(player, player.media, 'volumechange');\n });\n },\n });\n\n // Loop\n let { loop } = player.config;\n Object.defineProperty(player.media, 'loop', {\n get() {\n return loop;\n },\n set(input) {\n const toggle = is.boolean(input) ? input : player.config.loop.active;\n\n player.embed.setLoop(toggle).then(() => {\n loop = toggle;\n });\n },\n });\n\n // Source\n let currentSrc;\n player.embed\n .getVideoUrl()\n .then(value => {\n currentSrc = value;\n })\n .catch(error => {\n this.debug.warn(error);\n });\n\n Object.defineProperty(player.media, 'currentSrc', {\n get() {\n return currentSrc;\n },\n });\n\n // Ended\n Object.defineProperty(player.media, 'ended', {\n get() {\n return player.currentTime === player.duration;\n },\n });\n\n // Set aspect ratio based on video size\n Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then(dimensions => {\n const ratio = getAspectRatio(dimensions[0], dimensions[1]);\n vimeo.setAspectRatio.call(this, ratio);\n });\n\n // Set autopause\n player.embed.setAutopause(player.config.autopause).then(state => {\n player.config.autopause = state;\n });\n\n // Get title\n player.embed.getVideoTitle().then(title => {\n player.config.title = title;\n ui.setTitle.call(this);\n });\n\n // Get current time\n player.embed.getCurrentTime().then(value => {\n currentTime = value;\n triggerEvent.call(player, player.media, 'timeupdate');\n });\n\n // Get duration\n player.embed.getDuration().then(value => {\n player.media.duration = value;\n triggerEvent.call(player, player.media, 'durationchange');\n });\n\n // Get captions\n player.embed.getTextTracks().then(tracks => {\n player.media.textTracks = tracks;\n captions.setup.call(player);\n });\n\n player.embed.on('cuechange', ({ cues = [] }) => {\n const strippedCues = cues.map(cue => stripHTML(cue.text));\n captions.updateCues.call(player, strippedCues);\n });\n\n player.embed.on('loaded', () => {\n // Assure state and events are updated on autoplay\n player.embed.getPaused().then(paused => {\n assurePlaybackState.call(player, !paused);\n if (!paused) {\n triggerEvent.call(player, player.media, 'playing');\n }\n });\n\n if (is.element(player.embed.element) && player.supported.ui) {\n const frame = player.embed.element;\n\n // Fix keyboard focus issues\n // https://github.com/sampotts/plyr/issues/317\n frame.setAttribute('tabindex', -1);\n }\n });\n\n player.embed.on('play', () => {\n assurePlaybackState.call(player, true);\n triggerEvent.call(player, player.media, 'playing');\n });\n\n player.embed.on('pause', () => {\n assurePlaybackState.call(player, false);\n });\n\n player.embed.on('timeupdate', data => {\n player.media.seeking = false;\n currentTime = data.seconds;\n triggerEvent.call(player, player.media, 'timeupdate');\n });\n\n player.embed.on('progress', data => {\n player.media.buffered = data.percent;\n triggerEvent.call(player, player.media, 'progress');\n\n // Check all loaded\n if (parseInt(data.percent, 10) === 1) {\n triggerEvent.call(player, player.media, 'canplaythrough');\n }\n\n // Get duration as if we do it before load, it gives an incorrect value\n // https://github.com/sampotts/plyr/issues/891\n player.embed.getDuration().then(value => {\n if (value !== player.media.duration) {\n player.media.duration = value;\n triggerEvent.call(player, player.media, 'durationchange');\n }\n });\n });\n\n player.embed.on('seeked', () => {\n player.media.seeking = false;\n triggerEvent.call(player, player.media, 'seeked');\n });\n\n player.embed.on('ended', () => {\n player.media.paused = true;\n triggerEvent.call(player, player.media, 'ended');\n });\n\n player.embed.on('error', detail => {\n player.media.error = detail;\n triggerEvent.call(player, player.media, 'error');\n });\n\n // Rebuild UI\n setTimeout(() => ui.build.call(player), 0);\n },\n};\n\nexport default vimeo;\n","// ==========================================================================\n// YouTube plugin\n// ==========================================================================\n\nimport controls from './../controls';\nimport ui from './../ui';\nimport { dedupe } from './../utils/arrays';\nimport { createElement, replaceElement, toggleClass } from './../utils/elements';\nimport { triggerEvent } from './../utils/events';\nimport fetch from './../utils/fetch';\nimport is from './../utils/is';\nimport loadImage from './../utils/loadImage';\nimport loadScript from './../utils/loadScript';\nimport { format, generateId } from './../utils/strings';\n\n// Parse YouTube ID from URL\nfunction parseId(url) {\n if (is.empty(url)) {\n return null;\n }\n\n const regex = /^.*(youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=|&v=)([^#&?]*).*/;\n return url.match(regex) ? RegExp.$2 : url;\n}\n\n// Standardise YouTube quality unit\nfunction mapQualityUnit(input) {\n const qualities = {\n hd2160: 2160,\n hd1440: 1440,\n hd1080: 1080,\n hd720: 720,\n large: 480,\n medium: 360,\n small: 240,\n tiny: 144,\n };\n\n const entry = Object.entries(qualities).find(entry => entry.includes(input));\n\n if (entry) {\n // Get the match corresponding to the input\n return entry.find(value => value !== input);\n }\n\n return 'default';\n}\n\nfunction mapQualityUnits(levels) {\n if (is.empty(levels)) {\n return levels;\n }\n\n return dedupe(levels.map(level => mapQualityUnit(level)));\n}\n\n// Set playback state and trigger change (only on actual change)\nfunction assurePlaybackState(play) {\n if (play && !this.embed.hasPlayed) {\n this.embed.hasPlayed = true;\n }\n if (this.media.paused === play) {\n this.media.paused = !play;\n triggerEvent.call(this, this.media, play ? 'play' : 'pause');\n }\n}\n\nconst youtube = {\n setup() {\n // Add embed class for responsive\n toggleClass(this.elements.wrapper, this.config.classNames.embed, true);\n\n // Set aspect ratio\n youtube.setAspectRatio.call(this);\n\n // Setup API\n if (is.object(window.YT) && is.function(window.YT.Player)) {\n youtube.ready.call(this);\n } else {\n // Load the API\n loadScript(this.config.urls.youtube.sdk).catch(error => {\n this.debug.warn('YouTube API failed to load', error);\n });\n\n // Setup callback for the API\n // YouTube has it's own system of course...\n window.onYouTubeReadyCallbacks = window.onYouTubeReadyCallbacks || [];\n\n // Add to queue\n window.onYouTubeReadyCallbacks.push(() => {\n youtube.ready.call(this);\n });\n\n // Set callback to process queue\n window.onYouTubeIframeAPIReady = () => {\n window.onYouTubeReadyCallbacks.forEach(callback => {\n callback();\n });\n };\n }\n },\n\n // Get the media title\n getTitle(videoId) {\n // Try via undocumented API method first\n // This method disappears now and then though...\n // https://github.com/sampotts/plyr/issues/709\n if (is.function(this.embed.getVideoData)) {\n const { title } = this.embed.getVideoData();\n\n if (is.empty(title)) {\n this.config.title = title;\n ui.setTitle.call(this);\n return;\n }\n }\n\n // Or via Google API\n const key = this.config.keys.google;\n if (is.string(key) && !is.empty(key)) {\n const url = format(this.config.urls.youtube.api, videoId, key);\n\n fetch(url)\n .then(result => {\n if (is.object(result)) {\n this.config.title = result.items[0].snippet.title;\n ui.setTitle.call(this);\n }\n })\n .catch(() => {});\n }\n },\n\n // Set aspect ratio\n setAspectRatio() {\n const ratio = this.config.ratio.split(':');\n this.elements.wrapper.style.paddingBottom = `${100 / ratio[0] * ratio[1]}%`;\n },\n\n // API ready\n ready() {\n const player = this;\n\n // Ignore already setup (race condition)\n const currentId = player.media.getAttribute('id');\n if (!is.empty(currentId) && currentId.startsWith('youtube-')) {\n return;\n }\n\n // Get the source URL or ID\n let source = player.media.getAttribute('src');\n\n // Get from <div> if needed\n if (is.empty(source)) {\n source = player.media.getAttribute(this.config.attributes.embed.id);\n }\n\n // Replace the <iframe> with a <div> due to YouTube API issues\n const videoId = parseId(source);\n const id = generateId(player.provider);\n\n // Get poster, if already set\n const { poster } = player;\n\n // Replace media element\n const container = createElement('div', { id, poster });\n player.media = replaceElement(container, player.media);\n\n // Id to poster wrapper\n const posterSrc = format => `https://img.youtube.com/vi/${videoId}/${format}default.jpg`;\n\n // Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)\n loadImage(posterSrc('maxres'), 121) // Higest quality and unpadded\n .catch(() => loadImage(posterSrc('sd'), 121)) // 480p padded 4:3\n .catch(() => loadImage(posterSrc('hq'))) // 360p padded 4:3. Always exists\n .then(image => ui.setPoster.call(player, image.src))\n .then(posterSrc => {\n // If the image is padded, use background-size \"cover\" instead (like youtube does too with their posters)\n if (!posterSrc.includes('maxres')) {\n player.elements.poster.style.backgroundSize = 'cover';\n }\n })\n .catch(() => {});\n\n // Setup instance\n // https://developers.google.com/youtube/iframe_api_reference\n player.embed = new window.YT.Player(id, {\n videoId,\n playerVars: {\n autoplay: player.config.autoplay ? 1 : 0, // Autoplay\n controls: player.supported.ui ? 0 : 1, // Only show controls if not fully supported\n rel: 0, // No related vids\n showinfo: 0, // Hide info\n iv_load_policy: 3, // Hide annotations\n modestbranding: 1, // Hide logos as much as possible (they still show one in the corner when paused)\n disablekb: 1, // Disable keyboard as we handle it\n playsinline: 1, // Allow iOS inline playback\n\n // Tracking for stats\n // origin: window ? `${window.location.protocol}//${window.location.host}` : null,\n widget_referrer: window ? window.location.href : null,\n\n // Captions are flaky on YouTube\n cc_load_policy: player.captions.active ? 1 : 0,\n cc_lang_pref: player.config.captions.language,\n },\n events: {\n onError(event) {\n // YouTube may fire onError twice, so only handle it once\n if (!player.media.error) {\n const code = event.data;\n // Messages copied from https://developers.google.com/youtube/iframe_api_reference#onError\n const message =\n {\n 2: 'The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.',\n 5: 'The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.',\n 100: 'The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.',\n 101: 'The owner of the requested video does not allow it to be played in embedded players.',\n 150: 'The owner of the requested video does not allow it to be played in embedded players.',\n }[code] || 'An unknown error occured';\n\n player.media.error = { code, message };\n\n triggerEvent.call(player, player.media, 'error');\n }\n },\n onPlaybackQualityChange() {\n triggerEvent.call(player, player.media, 'qualitychange', false, {\n quality: player.media.quality,\n });\n },\n onPlaybackRateChange(event) {\n // Get the instance\n const instance = event.target;\n\n // Get current speed\n player.media.playbackRate = instance.getPlaybackRate();\n\n triggerEvent.call(player, player.media, 'ratechange');\n },\n onReady(event) {\n // Get the instance\n const instance = event.target;\n\n // Get the title\n youtube.getTitle.call(player, videoId);\n\n // Create a faux HTML5 API using the YouTube API\n player.media.play = () => {\n assurePlaybackState.call(player, true);\n instance.playVideo();\n };\n\n player.media.pause = () => {\n assurePlaybackState.call(player, false);\n instance.pauseVideo();\n };\n\n player.media.stop = () => {\n instance.stopVideo();\n };\n\n player.media.duration = instance.getDuration();\n player.media.paused = true;\n\n // Seeking\n player.media.currentTime = 0;\n Object.defineProperty(player.media, 'currentTime', {\n get() {\n return Number(instance.getCurrentTime());\n },\n set(time) {\n // If paused, mute audio preventively (YouTube starts playing on seek if the video hasn't been played yet).\n if (player.paused) {\n player.embed.mute();\n }\n\n // Set seeking state and trigger event\n player.media.seeking = true;\n triggerEvent.call(player, player.media, 'seeking');\n\n // Seek after events sent\n instance.seekTo(time);\n },\n });\n\n // Playback speed\n Object.defineProperty(player.media, 'playbackRate', {\n get() {\n return instance.getPlaybackRate();\n },\n set(input) {\n instance.setPlaybackRate(input);\n },\n });\n\n // Quality\n Object.defineProperty(player.media, 'quality', {\n get() {\n return mapQualityUnit(instance.getPlaybackQuality());\n },\n set(input) {\n instance.setPlaybackQuality(mapQualityUnit(input));\n },\n });\n\n // Volume\n let { volume } = player.config;\n Object.defineProperty(player.media, 'volume', {\n get() {\n return volume;\n },\n set(input) {\n volume = input;\n instance.setVolume(volume * 100);\n triggerEvent.call(player, player.media, 'volumechange');\n },\n });\n\n // Muted\n let { muted } = player.config;\n Object.defineProperty(player.media, 'muted', {\n get() {\n return muted;\n },\n set(input) {\n const toggle = is.boolean(input) ? input : muted;\n muted = toggle;\n instance[toggle ? 'mute' : 'unMute']();\n triggerEvent.call(player, player.media, 'volumechange');\n },\n });\n\n // Source\n Object.defineProperty(player.media, 'currentSrc', {\n get() {\n return instance.getVideoUrl();\n },\n });\n\n // Ended\n Object.defineProperty(player.media, 'ended', {\n get() {\n return player.currentTime === player.duration;\n },\n });\n\n // Get available speeds\n player.options.speed = instance.getAvailablePlaybackRates();\n\n // Set the tabindex to avoid focus entering iframe\n if (player.supported.ui) {\n player.media.setAttribute('tabindex', -1);\n }\n\n triggerEvent.call(player, player.media, 'timeupdate');\n triggerEvent.call(player, player.media, 'durationchange');\n\n // Reset timer\n clearInterval(player.timers.buffering);\n\n // Setup buffering\n player.timers.buffering = setInterval(() => {\n // Get loaded % from YouTube\n player.media.buffered = instance.getVideoLoadedFraction();\n\n // Trigger progress only when we actually buffer something\n if (player.media.lastBuffered === null || player.media.lastBuffered < player.media.buffered) {\n triggerEvent.call(player, player.media, 'progress');\n }\n\n // Set last buffer point\n player.media.lastBuffered = player.media.buffered;\n\n // Bail if we're at 100%\n if (player.media.buffered === 1) {\n clearInterval(player.timers.buffering);\n\n // Trigger event\n triggerEvent.call(player, player.media, 'canplaythrough');\n }\n }, 200);\n\n // Rebuild UI\n setTimeout(() => ui.build.call(player), 50);\n },\n onStateChange(event) {\n // Get the instance\n const instance = event.target;\n\n // Reset timer\n clearInterval(player.timers.playing);\n\n const seeked = player.media.seeking && [1, 2].includes(event.data);\n\n if (seeked) {\n // Unset seeking and fire seeked event\n player.media.seeking = false;\n triggerEvent.call(player, player.media, 'seeked');\n }\n\n // Handle events\n // -1 Unstarted\n // 0 Ended\n // 1 Playing\n // 2 Paused\n // 3 Buffering\n // 5 Video cued\n switch (event.data) {\n case -1:\n // Update scrubber\n triggerEvent.call(player, player.media, 'timeupdate');\n\n // Get loaded % from YouTube\n player.media.buffered = instance.getVideoLoadedFraction();\n triggerEvent.call(player, player.media, 'progress');\n\n break;\n\n case 0:\n assurePlaybackState.call(player, false);\n\n // YouTube doesn't support loop for a single video, so mimick it.\n if (player.media.loop) {\n // YouTube needs a call to `stopVideo` before playing again\n instance.stopVideo();\n instance.playVideo();\n } else {\n triggerEvent.call(player, player.media, 'ended');\n }\n\n break;\n\n case 1:\n // Restore paused state (YouTube starts playing on seek if the video hasn't been played yet)\n if (player.media.paused && !player.embed.hasPlayed) {\n player.media.pause();\n } else {\n assurePlaybackState.call(player, true);\n\n triggerEvent.call(player, player.media, 'playing');\n\n // Poll to get playback progress\n player.timers.playing = setInterval(() => {\n triggerEvent.call(player, player.media, 'timeupdate');\n }, 50);\n\n // Check duration again due to YouTube bug\n // https://github.com/sampotts/plyr/issues/374\n // https://code.google.com/p/gdata-issues/issues/detail?id=8690\n if (player.media.duration !== instance.getDuration()) {\n player.media.duration = instance.getDuration();\n triggerEvent.call(player, player.media, 'durationchange');\n }\n\n // Get quality\n controls.setQualityMenu.call(\n player,\n mapQualityUnits(instance.getAvailableQualityLevels()),\n );\n }\n\n break;\n\n case 2:\n // Restore audio (YouTube starts playing on seek if the video hasn't been played yet)\n if (!player.muted) {\n player.embed.unMute();\n }\n assurePlaybackState.call(player, false);\n\n break;\n\n default:\n break;\n }\n\n triggerEvent.call(player, player.elements.container, 'statechange', false, {\n code: event.data,\n });\n },\n },\n });\n },\n};\n\nexport default youtube;\n","// ==========================================================================\n// Plyr Media\n// ==========================================================================\n\nimport html5 from './html5';\nimport vimeo from './plugins/vimeo';\nimport youtube from './plugins/youtube';\nimport { createElement, toggleClass, wrap } from './utils/elements';\n\nconst media = {\n // Setup media\n setup() {\n // If there's no media, bail\n if (!this.media) {\n this.debug.warn('No media element found!');\n return;\n }\n\n // Add type class\n toggleClass(this.elements.container, this.config.classNames.type.replace('{0}', this.type), true);\n\n // Add provider class\n toggleClass(this.elements.container, this.config.classNames.provider.replace('{0}', this.provider), true);\n\n // Add video class for embeds\n // This will require changes if audio embeds are added\n if (this.isEmbed) {\n toggleClass(this.elements.container, this.config.classNames.type.replace('{0}', 'video'), true);\n }\n\n // Inject the player wrapper\n if (this.isVideo) {\n // Create the wrapper div\n this.elements.wrapper = createElement('div', {\n class: this.config.classNames.video,\n });\n\n // Wrap the video in a container\n wrap(this.media, this.elements.wrapper);\n\n // Faux poster container\n this.elements.poster = createElement('div', {\n class: this.config.classNames.poster,\n });\n\n this.elements.wrapper.appendChild(this.elements.poster);\n }\n\n if (this.isHTML5) {\n html5.extend.call(this);\n } else if (this.isYouTube) {\n youtube.setup.call(this);\n } else if (this.isVimeo) {\n vimeo.setup.call(this);\n }\n },\n};\n\nexport default media;\n","// ==========================================================================\n// Advertisement plugin using Google IMA HTML5 SDK\n// Create an account with our ad partner, vi here:\n// https://www.vi.ai/publisher-video-monetization/\n// ==========================================================================\n\n/* global google */\n\nimport i18n from '../i18n';\nimport { createElement } from './../utils/elements';\nimport { triggerEvent } from './../utils/events';\nimport is from './../utils/is';\nimport loadScript from './../utils/loadScript';\nimport { formatTime } from './../utils/time';\nimport { buildUrlParams } from './../utils/urls';\n\nclass Ads {\n /**\n * Ads constructor.\n * @param {object} player\n * @return {Ads}\n */\n constructor(player) {\n this.player = player;\n this.publisherId = player.config.ads.publisherId;\n this.playing = false;\n this.initialized = false;\n this.elements = {\n container: null,\n displayContainer: null,\n };\n this.manager = null;\n this.loader = null;\n this.cuePoints = null;\n this.events = {};\n this.safetyTimer = null;\n this.countdownTimer = null;\n\n // Setup a promise to resolve when the IMA manager is ready\n this.managerPromise = new Promise((resolve, reject) => {\n // The ad is loaded and ready\n this.on('loaded', resolve);\n\n // Ads failed\n this.on('error', reject);\n });\n\n this.load();\n }\n\n get enabled() {\n return this.player.isVideo && this.player.config.ads.enabled && !is.empty(this.publisherId);\n }\n\n /**\n * Load the IMA SDK\n */\n load() {\n if (this.enabled) {\n // Check if the Google IMA3 SDK is loaded or load it ourselves\n if (!is.object(window.google) || !is.object(window.google.ima)) {\n loadScript(this.player.config.urls.googleIMA.sdk)\n .then(() => {\n this.ready();\n })\n .catch(() => {\n // Script failed to load or is blocked\n this.trigger('error', new Error('Google IMA SDK failed to load'));\n });\n } else {\n this.ready();\n }\n }\n }\n\n /**\n * Get the ads instance ready\n */\n ready() {\n // Start ticking our safety timer. If the whole advertisement\n // thing doesn't resolve within our set time; we bail\n this.startSafetyTimer(12000, 'ready()');\n\n // Clear the safety timer\n this.managerPromise.then(() => {\n this.clearSafetyTimer('onAdsManagerLoaded()');\n });\n\n // Set listeners on the Plyr instance\n this.listeners();\n\n // Setup the IMA SDK\n this.setupIMA();\n }\n\n // Build the default tag URL\n get tagUrl() {\n const params = {\n AV_PUBLISHERID: '58c25bb0073ef448b1087ad6',\n AV_CHANNELID: '5a0458dc28a06145e4519d21',\n AV_URL: location.hostname,\n cb: Date.now(),\n AV_WIDTH: 640,\n AV_HEIGHT: 480,\n AV_CDIM2: this.publisherId,\n };\n\n const base = 'https://go.aniview.com/api/adserver6/vast/';\n\n return `${base}?${buildUrlParams(params)}`;\n }\n\n /**\n * In order for the SDK to display ads for our video, we need to tell it where to put them,\n * so here we define our ad container. This div is set up to render on top of the video player.\n * Using the code below, we tell the SDK to render ads within that div. We also provide a\n * handle to the content video player - the SDK will poll the current time of our player to\n * properly place mid-rolls. After we create the ad display container, we initialize it. On\n * mobile devices, this initialization is done as the result of a user action.\n */\n setupIMA() {\n // Create the container for our advertisements\n this.elements.container = createElement('div', {\n class: this.player.config.classNames.ads,\n });\n this.player.elements.container.appendChild(this.elements.container);\n\n // So we can run VPAID2\n google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED);\n\n // Set language\n google.ima.settings.setLocale(this.player.config.ads.language);\n\n // We assume the adContainer is the video container of the plyr element\n // that will house the ads\n this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container);\n\n // Request video ads to be pre-loaded\n this.requestAds();\n }\n\n /**\n * Request advertisements\n */\n requestAds() {\n const { container } = this.player.elements;\n\n try {\n // Create ads loader\n this.loader = new google.ima.AdsLoader(this.elements.displayContainer);\n\n // Listen and respond to ads loaded and error events\n this.loader.addEventListener(\n google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,\n event => this.onAdsManagerLoaded(event),\n false,\n );\n this.loader.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error), false);\n\n // Request video ads\n const request = new google.ima.AdsRequest();\n request.adTagUrl = this.tagUrl;\n\n // Specify the linear and nonlinear slot sizes. This helps the SDK\n // to select the correct creative if multiple are returned\n request.linearAdSlotWidth = container.offsetWidth;\n request.linearAdSlotHeight = container.offsetHeight;\n request.nonLinearAdSlotWidth = container.offsetWidth;\n request.nonLinearAdSlotHeight = container.offsetHeight;\n\n // We only overlay ads as we only support video.\n request.forceNonLinearFullSlot = false;\n\n // Mute based on current state\n request.setAdWillPlayMuted(!this.player.muted);\n\n this.loader.requestAds(request);\n } catch (e) {\n this.onAdError(e);\n }\n }\n\n /**\n * Update the ad countdown\n * @param {boolean} start\n */\n pollCountdown(start = false) {\n if (!start) {\n clearInterval(this.countdownTimer);\n this.elements.container.removeAttribute('data-badge-text');\n return;\n }\n\n const update = () => {\n const time = formatTime(Math.max(this.manager.getRemainingTime(), 0));\n const label = `${i18n.get('advertisement', this.player.config)} - ${time}`;\n this.elements.container.setAttribute('data-badge-text', label);\n };\n\n this.countdownTimer = setInterval(update, 100);\n }\n\n /**\n * This method is called whenever the ads are ready inside the AdDisplayContainer\n * @param {Event} adsManagerLoadedEvent\n */\n onAdsManagerLoaded(event) {\n // Get the ads manager\n const settings = new google.ima.AdsRenderingSettings();\n\n // Tell the SDK to save and restore content video state on our behalf\n settings.restoreCustomPlaybackStateOnAdBreakComplete = true;\n settings.enablePreloading = true;\n\n // The SDK is polling currentTime on the contentPlayback. And needs a duration\n // so it can determine when to start the mid- and post-roll\n this.manager = event.getAdsManager(this.player, settings);\n\n // Get the cue points for any mid-rolls by filtering out the pre- and post-roll\n this.cuePoints = this.manager.getCuePoints();\n\n // Add advertisement cue's within the time line if available\n if (!is.empty(this.cuePoints)) {\n this.cuePoints.forEach(cuePoint => {\n if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < this.player.duration) {\n const seekElement = this.player.elements.progress;\n\n if (is.element(seekElement)) {\n const cuePercentage = 100 / this.player.duration * cuePoint;\n const cue = createElement('span', {\n class: this.player.config.classNames.cues,\n });\n\n cue.style.left = `${cuePercentage.toString()}%`;\n seekElement.appendChild(cue);\n }\n }\n });\n }\n\n // Get skippable state\n // TODO: Skip button\n // this.player.debug.warn(this.manager.getAdSkippableState());\n\n // Set volume to match player\n this.manager.setVolume(this.player.volume);\n\n // Add listeners to the required events\n // Advertisement error events\n this.manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error));\n\n // Advertisement regular events\n Object.keys(google.ima.AdEvent.Type).forEach(type => {\n this.manager.addEventListener(google.ima.AdEvent.Type[type], event => this.onAdEvent(event));\n });\n\n // Resolve our adsManager\n this.trigger('loaded');\n }\n\n /**\n * This is where all the event handling takes place. Retrieve the ad from the event. Some\n * events (e.g. ALL_ADS_COMPLETED) don't have the ad object associated\n * https://developers.google.com/interactive-media-ads/docs/sdks/html5/v3/apis#ima.AdEvent.Type\n * @param {Event} event\n */\n onAdEvent(event) {\n const { container } = this.player.elements;\n\n // Retrieve the ad from the event. Some events (e.g. ALL_ADS_COMPLETED)\n // don't have ad object associated\n const ad = event.getAd();\n\n // Proxy event\n const dispatchEvent = type => {\n const event = `ads${type.replace(/_/g, '').toLowerCase()}`;\n triggerEvent.call(this.player, this.player.media, event);\n };\n\n switch (event.type) {\n case google.ima.AdEvent.Type.LOADED:\n // This is the first event sent for an ad - it is possible to determine whether the\n // ad is a video ad or an overlay\n this.trigger('loaded');\n\n // Bubble event\n dispatchEvent(event.type);\n\n // Start countdown\n this.pollCountdown(true);\n\n if (!ad.isLinear()) {\n // Position AdDisplayContainer correctly for overlay\n ad.width = container.offsetWidth;\n ad.height = container.offsetHeight;\n }\n\n // console.info('Ad type: ' + event.getAd().getAdPodInfo().getPodIndex());\n // console.info('Ad time: ' + event.getAd().getAdPodInfo().getTimeOffset());\n break;\n\n case google.ima.AdEvent.Type.ALL_ADS_COMPLETED:\n // All ads for the current videos are done. We can now request new advertisements\n // in case the video is re-played\n\n // Fire event\n dispatchEvent(event.type);\n\n // TODO: Example for what happens when a next video in a playlist would be loaded.\n // So here we load a new video when all ads are done.\n // Then we load new ads within a new adsManager. When the video\n // Is started - after - the ads are loaded, then we get ads.\n // You can also easily test cancelling and reloading by running\n // player.ads.cancel() and player.ads.play from the console I guess.\n // this.player.source = {\n // type: 'video',\n // title: 'View From A Blue Moon',\n // sources: [{\n // src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4', type:\n // 'video/mp4', }], poster:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg', tracks:\n // [ { kind: 'captions', label: 'English', srclang: 'en', src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt',\n // default: true, }, { kind: 'captions', label: 'French', srclang: 'fr', src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt', }, ],\n // };\n\n // TODO: So there is still this thing where a video should only be allowed to start\n // playing when the IMA SDK is ready or has failed\n\n this.loadAds();\n break;\n\n case google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED:\n // This event indicates the ad has started - the video player can adjust the UI,\n // for example display a pause button and remaining time. Fired when content should\n // be paused. This usually happens right before an ad is about to cover the content\n\n dispatchEvent(event.type);\n\n this.pauseContent();\n\n break;\n\n case google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED:\n // This event indicates the ad has finished - the video player can perform\n // appropriate UI actions, such as removing the timer for remaining time detection.\n // Fired when content should be resumed. This usually happens when an ad finishes\n // or collapses\n\n dispatchEvent(event.type);\n\n this.pollCountdown();\n\n this.resumeContent();\n\n break;\n\n case google.ima.AdEvent.Type.STARTED:\n case google.ima.AdEvent.Type.MIDPOINT:\n case google.ima.AdEvent.Type.COMPLETE:\n case google.ima.AdEvent.Type.IMPRESSION:\n case google.ima.AdEvent.Type.CLICK:\n dispatchEvent(event.type);\n break;\n\n default:\n break;\n }\n }\n\n /**\n * Any ad error handling comes through here\n * @param {Event} event\n */\n onAdError(event) {\n this.cancel();\n this.player.debug.warn('Ads error', event);\n }\n\n /**\n * Setup hooks for Plyr and window events. This ensures\n * the mid- and post-roll launch at the correct time. And\n * resize the advertisement when the player resizes\n */\n listeners() {\n const { container } = this.player.elements;\n let time;\n\n // Add listeners to the required events\n this.player.on('ended', () => {\n this.loader.contentComplete();\n });\n\n this.player.on('seeking', () => {\n time = this.player.currentTime;\n return time;\n });\n\n this.player.on('seeked', () => {\n const seekedTime = this.player.currentTime;\n\n if (is.empty(this.cuePoints)) {\n return;\n }\n\n this.cuePoints.forEach((cuePoint, index) => {\n if (time < cuePoint && cuePoint < seekedTime) {\n this.manager.discardAdBreak();\n this.cuePoints.splice(index, 1);\n }\n });\n });\n\n // Listen to the resizing of the window. And resize ad accordingly\n // TODO: eventually implement ResizeObserver\n window.addEventListener('resize', () => {\n if (this.manager) {\n this.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);\n }\n });\n }\n\n /**\n * Initialize the adsManager and start playing advertisements\n */\n play() {\n const { container } = this.player.elements;\n\n if (!this.managerPromise) {\n this.resumeContent();\n }\n\n // Play the requested advertisement whenever the adsManager is ready\n this.managerPromise\n .then(() => {\n // Initialize the container. Must be done via a user action on mobile devices\n this.elements.displayContainer.initialize();\n\n try {\n if (!this.initialized) {\n // Initialize the ads manager. Ad rules playlist will start at this time\n this.manager.init(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);\n\n // Call play to start showing the ad. Single video and overlay ads will\n // start at this time; the call will be ignored for ad rules\n this.manager.start();\n }\n\n this.initialized = true;\n } catch (adError) {\n // An error may be thrown if there was a problem with the\n // VAST response\n this.onAdError(adError);\n }\n })\n .catch(() => {});\n }\n\n /**\n * Resume our video\n */\n resumeContent() {\n // Hide the advertisement container\n this.elements.container.style.zIndex = '';\n\n // Ad is stopped\n this.playing = false;\n\n // Play our video\n if (this.player.currentTime < this.player.duration) {\n this.player.play();\n }\n }\n\n /**\n * Pause our video\n */\n pauseContent() {\n // Show the advertisement container\n this.elements.container.style.zIndex = 3;\n\n // Ad is playing.\n this.playing = true;\n\n // Pause our video.\n this.player.pause();\n }\n\n /**\n * Destroy the adsManager so we can grab new ads after this. If we don't then we're not\n * allowed to call new ads based on google policies, as they interpret this as an accidental\n * video requests. https://developers.google.com/interactive-\n * media-ads/docs/sdks/android/faq#8\n */\n cancel() {\n // Pause our video\n if (this.initialized) {\n this.resumeContent();\n }\n\n // Tell our instance that we're done for now\n this.trigger('error');\n\n // Re-create our adsManager\n this.loadAds();\n }\n\n /**\n * Re-create our adsManager\n */\n loadAds() {\n // Tell our adsManager to go bye bye\n this.managerPromise\n .then(() => {\n // Destroy our adsManager\n if (this.manager) {\n this.manager.destroy();\n }\n\n // Re-set our adsManager promises\n this.managerPromise = new Promise(resolve => {\n this.on('loaded', resolve);\n this.player.debug.log(this.manager);\n });\n\n // Now request some new advertisements\n this.requestAds();\n })\n .catch(() => {});\n }\n\n /**\n * Handles callbacks after an ad event was invoked\n * @param {string} event - Event type\n */\n trigger(event, ...args) {\n const handlers = this.events[event];\n\n if (is.array(handlers)) {\n handlers.forEach(handler => {\n if (is.function(handler)) {\n handler.apply(this, args);\n }\n });\n }\n }\n\n /**\n * Add event listeners\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n * @return {Ads}\n */\n on(event, callback) {\n if (!is.array(this.events[event])) {\n this.events[event] = [];\n }\n\n this.events[event].push(callback);\n\n return this;\n }\n\n /**\n * Setup a safety timer for when the ad network doesn't respond for whatever reason.\n * The advertisement has 12 seconds to get its things together. We stop this timer when the\n * advertisement is playing, or when a user action is required to start, then we clear the\n * timer on ad ready\n * @param {number} time\n * @param {string} from\n */\n startSafetyTimer(time, from) {\n this.player.debug.log(`Safety timer invoked from: ${from}`);\n\n this.safetyTimer = setTimeout(() => {\n this.cancel();\n this.clearSafetyTimer('startSafetyTimer()');\n }, time);\n }\n\n /**\n * Clear our safety timer(s)\n * @param {string} from\n */\n clearSafetyTimer(from) {\n if (!is.nullOrUndefined(this.safetyTimer)) {\n this.player.debug.log(`Safety timer cleared from: ${from}`);\n\n clearTimeout(this.safetyTimer);\n this.safetyTimer = null;\n }\n }\n}\n\nexport default Ads;\n","// ==========================================================================\n// Plyr source update\n// ==========================================================================\n\nimport { providers } from './config/types';\nimport html5 from './html5';\nimport media from './media';\nimport support from './support';\nimport ui from './ui';\nimport { createElement, insertElement, removeElement } from './utils/elements';\nimport is from './utils/is';\nimport { getDeep } from './utils/objects';\n\nconst source = {\n // Add elements to HTML5 media (source, tracks, etc)\n insertElements(type, attributes) {\n if (is.string(attributes)) {\n insertElement(type, this.media, {\n src: attributes,\n });\n } else if (is.array(attributes)) {\n attributes.forEach(attribute => {\n insertElement(type, this.media, attribute);\n });\n }\n },\n\n // Update source\n // Sources are not checked for support so be careful\n change(input) {\n if (!getDeep(input, 'sources.length')) {\n this.debug.warn('Invalid source format');\n return;\n }\n\n // Cancel current network requests\n html5.cancelRequests.call(this);\n\n // Destroy instance and re-setup\n this.destroy.call(\n this,\n () => {\n // Reset quality options\n this.options.quality = [];\n\n // Remove elements\n removeElement(this.media);\n this.media = null;\n\n // Reset class name\n if (is.element(this.elements.container)) {\n this.elements.container.removeAttribute('class');\n }\n\n // Set the type and provider\n const { sources, type } = input;\n const [{ provider = providers.html5, src }] = sources;\n const tagName = provider === 'html5' ? type : 'div';\n const attributes = provider === 'html5' ? {} : { src };\n\n Object.assign(this, {\n provider,\n type,\n // Check for support\n supported: support.check(type, provider, this.config.playsinline),\n // Create new element\n media: createElement(tagName, attributes),\n });\n\n // Inject the new element\n this.elements.container.appendChild(this.media);\n\n // Autoplay the new source?\n if (is.boolean(input.autoplay)) {\n this.config.autoplay = input.autoplay;\n }\n\n // Set attributes for audio and video\n if (this.isHTML5) {\n if (this.config.crossorigin) {\n this.media.setAttribute('crossorigin', '');\n }\n if (this.config.autoplay) {\n this.media.setAttribute('autoplay', '');\n }\n if (!is.empty(input.poster)) {\n this.poster = input.poster;\n }\n if (this.config.loop.active) {\n this.media.setAttribute('loop', '');\n }\n if (this.config.muted) {\n this.media.setAttribute('muted', '');\n }\n if (this.config.playsinline) {\n this.media.setAttribute('playsinline', '');\n }\n }\n\n // Restore class hook\n ui.addStyleHook.call(this);\n\n // Set new sources for html5\n if (this.isHTML5) {\n source.insertElements.call(this, 'source', sources);\n }\n\n // Set video title\n this.config.title = input.title;\n\n // Set up from scratch\n media.setup.call(this);\n\n // HTML5 stuff\n if (this.isHTML5) {\n // Setup captions\n if ('tracks' in input) {\n source.insertElements.call(this, 'track', input.tracks);\n }\n\n // Load HTML5 sources\n this.media.load();\n }\n\n // If HTML5 or embed but not fully supported, setupInterface and call ready now\n if (this.isHTML5 || (this.isEmbed && !this.supported.ui)) {\n // Setup interface\n ui.build.call(this);\n }\n\n // Update the fullscreen support\n this.fullscreen.update();\n },\n true,\n );\n },\n};\n\nexport default source;\n","// ==========================================================================\n// Plyr\n// plyr.js v3.3.15\n// https://github.com/sampotts/plyr\n// License: The MIT License (MIT)\n// ==========================================================================\n\nimport captions from './captions';\nimport defaults from './config/defaults';\nimport { getProviderByUrl, providers, types } from './config/types';\nimport Console from './console';\nimport controls from './controls';\nimport Fullscreen from './fullscreen';\nimport Listeners from './listeners';\nimport media from './media';\nimport Ads from './plugins/ads';\nimport source from './source';\nimport Storage from './storage';\nimport support from './support';\nimport ui from './ui';\nimport { closest } from './utils/arrays';\nimport { createElement, hasClass, removeElement, replaceElement, toggleClass, wrap } from './utils/elements';\nimport { off, on, once, triggerEvent, unbindListeners } from './utils/events';\nimport is from './utils/is';\nimport loadSprite from './utils/loadSprite';\nimport { cloneDeep, extend } from './utils/objects';\nimport { parseUrl } from './utils/urls';\n\n// Private properties\n// TODO: Use a WeakMap for private globals\n// const globals = new WeakMap();\n\n// Plyr instance\nclass Plyr {\n constructor(target, options) {\n this.timers = {};\n\n // State\n this.ready = false;\n this.loading = false;\n this.failed = false;\n\n // Touch device\n this.touch = support.touch;\n\n // Set the media element\n this.media = target;\n\n // String selector passed\n if (is.string(this.media)) {\n this.media = document.querySelectorAll(this.media);\n }\n\n // jQuery, NodeList or Array passed, use first element\n if ((window.jQuery && this.media instanceof jQuery) || is.nodeList(this.media) || is.array(this.media)) {\n // eslint-disable-next-line\n this.media = this.media[0];\n }\n\n // Set config\n this.config = extend(\n {},\n defaults,\n Plyr.defaults,\n options || {},\n (() => {\n try {\n return JSON.parse(this.media.getAttribute('data-plyr-config'));\n } catch (e) {\n return {};\n }\n })(),\n );\n\n // Elements cache\n this.elements = {\n container: null,\n captions: null,\n buttons: {},\n display: {},\n progress: {},\n inputs: {},\n settings: {\n popup: null,\n menu: null,\n panels: {},\n buttons: {},\n },\n };\n\n // Captions\n this.captions = {\n active: null,\n currentTrack: -1,\n meta: new WeakMap(),\n };\n\n // Fullscreen\n this.fullscreen = {\n active: false,\n };\n\n // Options\n this.options = {\n speed: [],\n quality: [],\n };\n\n // Debugging\n // TODO: move to globals\n this.debug = new Console(this.config.debug);\n\n // Log config options and support\n this.debug.log('Config', this.config);\n this.debug.log('Support', support);\n\n // We need an element to setup\n if (is.nullOrUndefined(this.media) || !is.element(this.media)) {\n this.debug.error('Setup failed: no suitable element passed');\n return;\n }\n\n // Bail if the element is initialized\n if (this.media.plyr) {\n this.debug.warn('Target already setup');\n return;\n }\n\n // Bail if not enabled\n if (!this.config.enabled) {\n this.debug.error('Setup failed: disabled by config');\n return;\n }\n\n // Bail if disabled or no basic support\n // You may want to disable certain UAs etc\n if (!support.check().api) {\n this.debug.error('Setup failed: no support');\n return;\n }\n\n // Cache original element state for .destroy()\n const clone = this.media.cloneNode(true);\n clone.autoplay = false;\n this.elements.original = clone;\n\n // Set media type based on tag or data attribute\n // Supported: video, audio, vimeo, youtube\n const type = this.media.tagName.toLowerCase();\n\n // Embed properties\n let iframe = null;\n let url = null;\n\n // Different setup based on type\n switch (type) {\n case 'div':\n // Find the frame\n iframe = this.media.querySelector('iframe');\n\n // <iframe> type\n if (is.element(iframe)) {\n // Detect provider\n url = parseUrl(iframe.getAttribute('src'));\n this.provider = getProviderByUrl(url.toString());\n\n // Rework elements\n this.elements.container = this.media;\n this.media = iframe;\n\n // Reset classname\n this.elements.container.className = '';\n\n // Get attributes from URL and set config\n if (url.searchParams.length) {\n const truthy = ['1', 'true'];\n\n if (truthy.includes(url.searchParams.get('autoplay'))) {\n this.config.autoplay = true;\n }\n if (truthy.includes(url.searchParams.get('loop'))) {\n this.config.loop.active = true;\n }\n\n // TODO: replace fullscreen.iosNative with this playsinline config option\n // YouTube requires the playsinline in the URL\n if (this.isYouTube) {\n this.config.playsinline = truthy.includes(url.searchParams.get('playsinline'));\n } else {\n this.config.playsinline = true;\n }\n }\n } else {\n // <div> with attributes\n this.provider = this.media.getAttribute(this.config.attributes.embed.provider);\n\n // Remove attribute\n this.media.removeAttribute(this.config.attributes.embed.provider);\n }\n\n // Unsupported or missing provider\n if (is.empty(this.provider) || !Object.keys(providers).includes(this.provider)) {\n this.debug.error('Setup failed: Invalid provider');\n return;\n }\n\n // Audio will come later for external providers\n this.type = types.video;\n\n break;\n\n case 'video':\n case 'audio':\n this.type = type;\n this.provider = providers.html5;\n\n // Get config from attributes\n if (this.media.hasAttribute('crossorigin')) {\n this.config.crossorigin = true;\n }\n if (this.media.hasAttribute('autoplay')) {\n this.config.autoplay = true;\n }\n if (this.media.hasAttribute('playsinline')) {\n this.config.playsinline = true;\n }\n if (this.media.hasAttribute('muted')) {\n this.config.muted = true;\n }\n if (this.media.hasAttribute('loop')) {\n this.config.loop.active = true;\n }\n\n break;\n\n default:\n this.debug.error('Setup failed: unsupported type');\n return;\n }\n\n // Check for support again but with type\n this.supported = support.check(this.type, this.provider, this.config.playsinline);\n\n // If no support for even API, bail\n if (!this.supported.api) {\n this.debug.error('Setup failed: no support');\n return;\n }\n\n this.eventListeners = [];\n\n // Create listeners\n this.listeners = new Listeners(this);\n\n // Setup local storage for user settings\n this.storage = new Storage(this);\n\n // Store reference\n this.media.plyr = this;\n\n // Wrap media\n if (!is.element(this.elements.container)) {\n this.elements.container = createElement('div');\n wrap(this.media, this.elements.container);\n }\n\n // Add style hook\n ui.addStyleHook.call(this);\n\n // Setup media\n media.setup.call(this);\n\n // Listen for events if debugging\n if (this.config.debug) {\n on.call(this, this.elements.container, this.config.events.join(' '), event => {\n this.debug.log(`event: ${event.type}`);\n });\n }\n\n // Setup interface\n // If embed but not fully supported, build interface now to avoid flash of controls\n if (this.isHTML5 || (this.isEmbed && !this.supported.ui)) {\n ui.build.call(this);\n }\n\n // Container listeners\n this.listeners.container();\n\n // Global listeners\n this.listeners.global();\n\n // Setup fullscreen\n this.fullscreen = new Fullscreen(this);\n\n // Setup ads if provided\n this.ads = new Ads(this);\n\n // Autoplay if required\n if (this.config.autoplay) {\n this.play();\n }\n }\n\n // ---------------------------------------\n // API\n // ---------------------------------------\n\n /**\n * Types and provider helpers\n */\n get isHTML5() {\n return Boolean(this.provider === providers.html5);\n }\n get isEmbed() {\n return Boolean(this.isYouTube || this.isVimeo);\n }\n get isYouTube() {\n return Boolean(this.provider === providers.youtube);\n }\n get isVimeo() {\n return Boolean(this.provider === providers.vimeo);\n }\n get isVideo() {\n return Boolean(this.type === types.video);\n }\n get isAudio() {\n return Boolean(this.type === types.audio);\n }\n\n /**\n * Play the media, or play the advertisement (if they are not blocked)\n */\n play() {\n if (!is.function(this.media.play)) {\n return null;\n }\n\n // Return the promise (for HTML5)\n return this.media.play();\n }\n\n /**\n * Pause the media\n */\n pause() {\n if (!this.playing || !is.function(this.media.pause)) {\n return;\n }\n\n this.media.pause();\n }\n\n /**\n * Get playing state\n */\n get playing() {\n return Boolean(this.ready && !this.paused && !this.ended);\n }\n\n /**\n * Get paused state\n */\n get paused() {\n return Boolean(this.media.paused);\n }\n\n /**\n * Get stopped state\n */\n get stopped() {\n return Boolean(this.paused && this.currentTime === 0);\n }\n\n /**\n * Get ended state\n */\n get ended() {\n return Boolean(this.media.ended);\n }\n\n /**\n * Toggle playback based on current status\n * @param {boolean} input\n */\n togglePlay(input) {\n // Toggle based on current state if nothing passed\n const toggle = is.boolean(input) ? input : !this.playing;\n\n if (toggle) {\n this.play();\n } else {\n this.pause();\n }\n }\n\n /**\n * Stop playback\n */\n stop() {\n if (this.isHTML5) {\n this.pause();\n this.restart();\n } else if (is.function(this.media.stop)) {\n this.media.stop();\n }\n }\n\n /**\n * Restart playback\n */\n restart() {\n this.currentTime = 0;\n }\n\n /**\n * Rewind\n * @param {number} seekTime - how far to rewind in seconds. Defaults to the config.seekTime\n */\n rewind(seekTime) {\n this.currentTime = this.currentTime - (is.number(seekTime) ? seekTime : this.config.seekTime);\n }\n\n /**\n * Fast forward\n * @param {number} seekTime - how far to fast forward in seconds. Defaults to the config.seekTime\n */\n forward(seekTime) {\n this.currentTime = this.currentTime + (is.number(seekTime) ? seekTime : this.config.seekTime);\n }\n\n /**\n * Seek to a time\n * @param {number} input - where to seek to in seconds. Defaults to 0 (the start)\n */\n set currentTime(input) {\n // Bail if media duration isn't available yet\n if (!this.duration) {\n return;\n }\n\n // Validate input\n const inputIsValid = is.number(input) && input > 0;\n\n // Set\n this.media.currentTime = inputIsValid ? Math.min(input, this.duration) : 0;\n\n // Logging\n this.debug.log(`Seeking to ${this.currentTime} seconds`);\n }\n\n /**\n * Get current time\n */\n get currentTime() {\n return Number(this.media.currentTime);\n }\n\n /**\n * Get buffered\n */\n get buffered() {\n const { buffered } = this.media;\n\n // YouTube / Vimeo return a float between 0-1\n if (is.number(buffered)) {\n return buffered;\n }\n\n // HTML5\n // TODO: Handle buffered chunks of the media\n // (i.e. seek to another section buffers only that section)\n if (buffered && buffered.length && this.duration > 0) {\n return buffered.end(0) / this.duration;\n }\n\n return 0;\n }\n\n /**\n * Get seeking status\n */\n get seeking() {\n return Boolean(this.media.seeking);\n }\n\n /**\n * Get the duration of the current media\n */\n get duration() {\n // Faux duration set via config\n const fauxDuration = parseFloat(this.config.duration);\n\n // Media duration can be NaN before the media has loaded\n const duration = (this.media || {}).duration || 0;\n\n // If config duration is funky, use regular duration\n return fauxDuration || duration;\n }\n\n /**\n * Set the player volume\n * @param {number} value - must be between 0 and 1. Defaults to the value from local storage and config.volume if not set in storage\n */\n set volume(value) {\n let volume = value;\n const max = 1;\n const min = 0;\n\n if (is.string(volume)) {\n volume = Number(volume);\n }\n\n // Load volume from storage if no value specified\n if (!is.number(volume)) {\n volume = this.storage.get('volume');\n }\n\n // Use config if all else fails\n if (!is.number(volume)) {\n ({ volume } = this.config);\n }\n\n // Maximum is volumeMax\n if (volume > max) {\n volume = max;\n }\n // Minimum is volumeMin\n if (volume < min) {\n volume = min;\n }\n\n // Update config\n this.config.volume = volume;\n\n // Set the player volume\n this.media.volume = volume;\n\n // If muted, and we're increasing volume manually, reset muted state\n if (!is.empty(value) && this.muted && volume > 0) {\n this.muted = false;\n }\n }\n\n /**\n * Get the current player volume\n */\n get volume() {\n return Number(this.media.volume);\n }\n\n /**\n * Increase volume\n * @param {boolean} step - How much to decrease by (between 0 and 1)\n */\n increaseVolume(step) {\n const volume = this.media.muted ? 0 : this.volume;\n this.volume = volume + (is.number(step) ? step : 1);\n }\n\n /**\n * Decrease volume\n * @param {boolean} step - How much to decrease by (between 0 and 1)\n */\n decreaseVolume(step) {\n const volume = this.media.muted ? 0 : this.volume;\n this.volume = volume - (is.number(step) ? step : 1);\n }\n\n /**\n * Set muted state\n * @param {boolean} mute\n */\n set muted(mute) {\n let toggle = mute;\n\n // Load muted state from storage\n if (!is.boolean(toggle)) {\n toggle = this.storage.get('muted');\n }\n\n // Use config if all else fails\n if (!is.boolean(toggle)) {\n toggle = this.config.muted;\n }\n\n // Update config\n this.config.muted = toggle;\n\n // Set mute on the player\n this.media.muted = toggle;\n }\n\n /**\n * Get current muted state\n */\n get muted() {\n return Boolean(this.media.muted);\n }\n\n /**\n * Check if the media has audio\n */\n get hasAudio() {\n // Assume yes for all non HTML5 (as we can't tell...)\n if (!this.isHTML5) {\n return true;\n }\n\n if (this.isAudio) {\n return true;\n }\n\n // Get audio tracks\n return (\n Boolean(this.media.mozHasAudio) ||\n Boolean(this.media.webkitAudioDecodedByteCount) ||\n Boolean(this.media.audioTracks && this.media.audioTracks.length)\n );\n }\n\n /**\n * Set playback speed\n * @param {number} speed - the speed of playback (0.5-2.0)\n */\n set speed(input) {\n let speed = null;\n\n if (is.number(input)) {\n speed = input;\n }\n\n if (!is.number(speed)) {\n speed = this.storage.get('speed');\n }\n\n if (!is.number(speed)) {\n speed = this.config.speed.selected;\n }\n\n // Set min/max\n if (speed < 0.1) {\n speed = 0.1;\n }\n if (speed > 2.0) {\n speed = 2.0;\n }\n\n if (!this.config.speed.options.includes(speed)) {\n this.debug.warn(`Unsupported speed (${speed})`);\n return;\n }\n\n // Update config\n this.config.speed.selected = speed;\n\n // Set media speed\n this.media.playbackRate = speed;\n }\n\n /**\n * Get current playback speed\n */\n get speed() {\n return Number(this.media.playbackRate);\n }\n\n /**\n * Set playback quality\n * Currently HTML5 & YouTube only\n * @param {number} input - Quality level\n */\n set quality(input) {\n const config = this.config.quality;\n const options = this.options.quality;\n\n if (!options.length) {\n return;\n }\n\n let quality = [\n !is.empty(input) && Number(input),\n this.storage.get('quality'),\n config.selected,\n config.default,\n ].find(is.number);\n\n if (!options.includes(quality)) {\n const value = closest(options, quality);\n this.debug.warn(`Unsupported quality option: ${quality}, using ${value} instead`);\n quality = value;\n }\n\n // Trigger request event\n triggerEvent.call(this, this.media, 'qualityrequested', false, { quality });\n\n // Update config\n config.selected = quality;\n\n // Set quality\n this.media.quality = quality;\n }\n\n /**\n * Get current quality level\n */\n get quality() {\n return this.media.quality;\n }\n\n /**\n * Toggle loop\n * TODO: Finish fancy new logic. Set the indicator on load as user may pass loop as config\n * @param {boolean} input - Whether to loop or not\n */\n set loop(input) {\n const toggle = is.boolean(input) ? input : this.config.loop.active;\n this.config.loop.active = toggle;\n this.media.loop = toggle;\n\n // Set default to be a true toggle\n /* const type = ['start', 'end', 'all', 'none', 'toggle'].includes(input) ? input : 'toggle';\n\n switch (type) {\n case 'start':\n if (this.config.loop.end && this.config.loop.end <= this.currentTime) {\n this.config.loop.end = null;\n }\n this.config.loop.start = this.currentTime;\n // this.config.loop.indicator.start = this.elements.display.played.value;\n break;\n\n case 'end':\n if (this.config.loop.start >= this.currentTime) {\n return this;\n }\n this.config.loop.end = this.currentTime;\n // this.config.loop.indicator.end = this.elements.display.played.value;\n break;\n\n case 'all':\n this.config.loop.start = 0;\n this.config.loop.end = this.duration - 2;\n this.config.loop.indicator.start = 0;\n this.config.loop.indicator.end = 100;\n break;\n\n case 'toggle':\n if (this.config.loop.active) {\n this.config.loop.start = 0;\n this.config.loop.end = null;\n } else {\n this.config.loop.start = 0;\n this.config.loop.end = this.duration - 2;\n }\n break;\n\n default:\n this.config.loop.start = 0;\n this.config.loop.end = null;\n break;\n } */\n }\n\n /**\n * Get current loop state\n */\n get loop() {\n return Boolean(this.media.loop);\n }\n\n /**\n * Set new media source\n * @param {object} input - The new source object (see docs)\n */\n set source(input) {\n source.change.call(this, input);\n }\n\n /**\n * Get current source\n */\n get source() {\n return this.media.currentSrc;\n }\n\n /**\n * Set the poster image for a video\n * @param {input} - the URL for the new poster image\n */\n set poster(input) {\n if (!this.isVideo) {\n this.debug.warn('Poster can only be set for video');\n return;\n }\n\n ui.setPoster.call(this, input, false).catch(() => {});\n }\n\n /**\n * Get the current poster image\n */\n get poster() {\n if (!this.isVideo) {\n return null;\n }\n\n return this.media.getAttribute('poster');\n }\n\n /**\n * Set the autoplay state\n * @param {boolean} input - Whether to autoplay or not\n */\n set autoplay(input) {\n const toggle = is.boolean(input) ? input : this.config.autoplay;\n this.config.autoplay = toggle;\n }\n\n /**\n * Get the current autoplay state\n */\n get autoplay() {\n return Boolean(this.config.autoplay);\n }\n\n /**\n * Toggle captions\n * @param {boolean} input - Whether to enable captions\n */\n toggleCaptions(input) {\n captions.toggle.call(this, input, false);\n }\n\n /**\n * Set the caption track by index\n * @param {number} - Caption index\n */\n set currentTrack(input) {\n captions.set.call(this, input, false);\n }\n\n /**\n * Get the current caption track index (-1 if disabled)\n */\n get currentTrack() {\n const { toggled, currentTrack } = this.captions;\n return toggled ? currentTrack : -1;\n }\n\n /**\n * Set the wanted language for captions\n * Since tracks can be added later it won't update the actual caption track until there is a matching track\n * @param {string} - Two character ISO language code (e.g. EN, FR, PT, etc)\n */\n set language(input) {\n captions.setLanguage.call(this, input, false);\n }\n\n /**\n * Get the current track's language\n */\n get language() {\n return (captions.getCurrentTrack.call(this) || {}).language;\n }\n\n /**\n * Toggle picture-in-picture playback on WebKit/MacOS\n * TODO: update player with state, support, enabled\n * TODO: detect outside changes\n */\n set pip(input) {\n const states = {\n pip: 'picture-in-picture',\n inline: 'inline',\n };\n\n // Bail if no support\n if (!support.pip) {\n return;\n }\n\n // Toggle based on current state if not passed\n const toggle = is.boolean(input) ? input : this.pip === states.inline;\n\n // Toggle based on current state\n this.media.webkitSetPresentationMode(toggle ? states.pip : states.inline);\n }\n\n /**\n * Get the current picture-in-picture state\n */\n get pip() {\n if (!support.pip) {\n return null;\n }\n\n return this.media.webkitPresentationMode;\n }\n\n /**\n * Trigger the airplay dialog\n * TODO: update player with state, support, enabled\n */\n airplay() {\n // Show dialog if supported\n if (support.airplay) {\n this.media.webkitShowPlaybackTargetPicker();\n }\n }\n\n /**\n * Toggle the player controls\n * @param {boolean} [toggle] - Whether to show the controls\n */\n toggleControls(toggle) {\n // Don't toggle if missing UI support or if it's audio\n if (this.supported.ui && !this.isAudio) {\n // Get state before change\n const isHidden = hasClass(this.elements.container, this.config.classNames.hideControls);\n\n // Negate the argument if not undefined since adding the class to hides the controls\n const force = typeof toggle === 'undefined' ? undefined : !toggle;\n\n // Apply and get updated state\n const hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force);\n\n // Close menu\n if (hiding && this.config.controls.includes('settings') && !is.empty(this.config.settings)) {\n controls.toggleMenu.call(this, false);\n }\n // Trigger event on change\n if (hiding !== isHidden) {\n const eventName = hiding ? 'controlshidden' : 'controlsshown';\n triggerEvent.call(this, this.media, eventName);\n }\n return !hiding;\n }\n return false;\n }\n\n /**\n * Add event listeners\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n */\n on(event, callback) {\n on.call(this, this.elements.container, event, callback);\n }\n /**\n * Add event listeners once\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n */\n once(event, callback) {\n once.call(this, this.elements.container, event, callback);\n }\n /**\n * Remove event listeners\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n */\n off(event, callback) {\n off(this.elements.container, event, callback);\n }\n\n /**\n * Destroy an instance\n * Event listeners are removed when elements are removed\n * http://stackoverflow.com/questions/12528049/if-a-dom-element-is-removed-are-its-listeners-also-removed-from-memory\n * @param {function} callback - Callback for when destroy is complete\n * @param {boolean} soft - Whether it's a soft destroy (for source changes etc)\n */\n destroy(callback, soft = false) {\n if (!this.ready) {\n return;\n }\n\n const done = () => {\n // Reset overflow (incase destroyed while in fullscreen)\n document.body.style.overflow = '';\n\n // GC for embed\n this.embed = null;\n\n // If it's a soft destroy, make minimal changes\n if (soft) {\n if (Object.keys(this.elements).length) {\n // Remove elements\n removeElement(this.elements.buttons.play);\n removeElement(this.elements.captions);\n removeElement(this.elements.controls);\n removeElement(this.elements.wrapper);\n\n // Clear for GC\n this.elements.buttons.play = null;\n this.elements.captions = null;\n this.elements.controls = null;\n this.elements.wrapper = null;\n }\n\n // Callback\n if (is.function(callback)) {\n callback();\n }\n } else {\n // Unbind listeners\n unbindListeners.call(this);\n\n // Replace the container with the original element provided\n replaceElement(this.elements.original, this.elements.container);\n\n // Event\n triggerEvent.call(this, this.elements.original, 'destroyed', true);\n\n // Callback\n if (is.function(callback)) {\n callback.call(this.elements.original);\n }\n\n // Reset state\n this.ready = false;\n\n // Clear for garbage collection\n setTimeout(() => {\n this.elements = null;\n this.media = null;\n }, 200);\n }\n };\n\n // Stop playback\n this.stop();\n\n // Provider specific stuff\n if (this.isHTML5) {\n // Clear timeout\n clearTimeout(this.timers.loading);\n\n // Restore native video controls\n ui.toggleNativeControls.call(this, true);\n\n // Clean up\n done();\n } else if (this.isYouTube) {\n // Clear timers\n clearInterval(this.timers.buffering);\n clearInterval(this.timers.playing);\n\n // Destroy YouTube API\n if (this.embed !== null && is.function(this.embed.destroy)) {\n this.embed.destroy();\n }\n\n // Clean up\n done();\n } else if (this.isVimeo) {\n // Destroy Vimeo API\n // then clean up (wait, to prevent postmessage errors)\n if (this.embed !== null) {\n this.embed.unload().then(done);\n }\n\n // Vimeo does not always return\n setTimeout(done, 200);\n }\n }\n\n /**\n * Check for support for a mime type (HTML5 only)\n * @param {string} type - Mime type\n */\n supports(type) {\n return support.mime.call(this, type);\n }\n\n /**\n * Check for support\n * @param {string} type - Player type (audio/video)\n * @param {string} provider - Provider (html5/youtube/vimeo)\n * @param {bool} inline - Where player has `playsinline` sttribute\n */\n static supported(type, provider, inline) {\n return support.check(type, provider, inline);\n }\n\n /**\n * Load an SVG sprite into the page\n * @param {string} url - URL for the SVG sprite\n * @param {string} [id] - Unique ID\n */\n static loadSprite(url, id) {\n return loadSprite(url, id);\n }\n\n /**\n * Setup multiple instances\n * @param {*} selector\n * @param {object} options\n */\n static setup(selector, options = {}) {\n let targets = null;\n\n if (is.string(selector)) {\n targets = Array.from(document.querySelectorAll(selector));\n } else if (is.nodeList(selector)) {\n targets = Array.from(selector);\n } else if (is.array(selector)) {\n targets = selector.filter(is.element);\n }\n\n if (is.empty(targets)) {\n return null;\n }\n\n return targets.map(t => new Plyr(t, options));\n }\n}\n\nPlyr.defaults = cloneDeep(defaults);\n\nexport default Plyr;\n"]}
\ No newline at end of file +{"version":3,"sources":["src/js/utils/is.js","src/js/utils/events.js","src/js/utils/elements.js","src/js/utils/animation.js","src/js/utils/browser.js","src/js/support.js","src/js/html5.js","src/js/utils/objects.js","src/js/utils/strings.js","src/js/i18n.js","src/js/utils/arrays.js","src/js/storage.js","src/js/utils/fetch.js","src/js/utils/loadSprite.js","src/js/utils/time.js","src/js/controls.js","src/js/utils/urls.js","src/js/captions.js","src/js/config/defaults.js","src/js/config/types.js","src/js/console.js","src/js/fullscreen.js","src/js/utils/loadImage.js","src/js/ui.js","src/js/listeners.js","node_modules/loadjs/dist/loadjs.umd.js","src/js/utils/loadScript.js","src/js/plugins/vimeo.js","src/js/plugins/youtube.js","src/js/media.js","src/js/plugins/ads.js","src/js/source.js","src/js/plyr.js"],"names":["getConstructor","input","constructor","instanceOf","Boolean","is","object","Object","number","Number","isNaN","string","String","boolean","function","Function","array","nullOrUndefined","Array","isArray","weakMap","WeakMap","nodeList","NodeList","element","Element","textNode","Text","event","Event","cue","window","TextTrackCue","VTTCue","track","TextTrack","kind","url","test","empty","length","keys","supportsPassiveListeners","supported","options","defineProperty","get","addEventListener","removeEventListener","e","toggleListener","callback","toggle","arguments","undefined","_this","this","passive","capture","events","split","forEach","type","eventListeners","push","on","call","off","once","onceCallback","_len","args","_key","apply","triggerEvent","bubbles","detail","CustomEvent","assign","plyr","dispatchEvent","wrap","elements","wrapper","targets","from","reverse","index","child","cloneNode","parent","parentNode","sibling","nextSibling","appendChild","insertBefore","setAttributes","attributes","entries","filter","_ref","value","slicedToArray","_ref3","_ref4","key","setAttribute","createElement","text","document","innerText","insertElement","removeElement","removeChild","emptyElement","childNodes","lastChild","replaceElement","newChild","oldChild","replaceChild","getAttributesFromSelector","sel","existingAttributes","existing","s","selector","trim","className","replace","parts","charAt","class","id","toggleHidden","hidden","hide","hasAttribute","removeAttribute","toggleClass","force","method","classList","contains","hasClass","matches","prototype","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","querySelectorAll","includes","getElements","container","getElement","querySelector","getFocusElement","focused","activeElement","body","transitionEndEvent","WebkitTransition","MozTransition","OTransition","transition","find","style","range","browser","isIE","documentMode","isWebkit","documentElement","navigator","userAgent","isIPhone","platform","isIos","defaultCodecs","audio/ogg","audio/wav","video/webm","video/mp4","video/ogg","support","audio","video","check","provider","playsinline","canPlayInline","api","ui","rangeInput","pip","webkitSetPresentationMode","airplay","WebKitPlaybackTargetAvailabilityEvent","mime","inputType","_inputType$split","mediaType","isHTML5","media","canPlayType","err","textTracks","touch","transitions","reducedMotion","matchMedia","html5","getSources","source","getAttribute","getQualityOptions","map","extend","player","_sources$filter","set","currentTime","playing","src","load","play","quality","cancelRequests","config","blankVideo","debug","log","getDeep","path","reduce","obj","target","sources","shift","concat","format","toString","match","i","replaceAll","RegExp","toTitleCase","toUpperCase","substr","toLowerCase","toCamelCase","toPascalCase","slice","getHTML","innerHTML","i18n","{seektime}","seekTime","{title}","title","_ref2","dedupe","item","indexOf","Storage","classCallCheck","enabled","storage","store","localStorage","getItem","json","JSON","parse","setItem","stringify","removeItem","fetch","responseType","Promise","resolve","reject","request","XMLHttpRequest","responseText","response","Error","status","open","send","loadSprite","hasId","exists","getElementById","update","data","insertAdjacentElement","useStorage","cached","prefix","content","then","result","catch","getHours","parseInt","getMinutes","getSeconds","formatTime","time","displayHours","inverted","hours","mins","secs","controls","getIconUrl","cors","URL","iconUrl","location","host","svg4everybody","findElements","selectors","buttons","pause","restart","rewind","fastForward","mute","settings","captions","fullscreen","progress","inputs","seek","volume","display","buffer","duration","seekTooltip","classNames","tooltip","error","warn","toggleNativeControls","createIcon","iconPath","iconPrefix","icon","createElementNS","role","focusable","use","setAttributeNS","createLabel","attr","join","createBadge","badge","menu","createButton","buttonType","button","label","labelPressed","iconPressed","control","controlPressed","enumerable","pressed","createRange","min","max","step","autocomplete","aria-label","aria-valuemin","aria-valuemax","aria-valuenow","updateRangeFill","createProgress","aria-hidden","suffixKey","played","suffix","createTime","createMenuItem","list","_ref$badge","_ref$checked","checked","aria-checked","children","node","updateTimeDisplay","updateVolume","setRange","muted","updateProgress","current","toFixed","getElementsByTagName","nodeValue","setProgress","buffered","percent","setProperty","updateSeekTooltip","_this2","tooltips","clientRect","getBoundingClientRect","visible","_toggle","width","pageX","left","parseFloat","timeUpdate","invert","invertTime","seeking","durationUpdate","hasDuration","displayDuration","paused","toggleMenuButton","setting","setQualityMenu","_this3","panels","console","checkMenu","sort","a","b","sorting","getLabel","getBadge","updateSetting","pane","currentTrack","default","setCaptionsMenu","_this4","tracks","getTracks","toggled","language","unshift","bind","setSpeedMenu","_this5","speed","isVimeo","values","some","toggleMenu","popup","show","isMenuItem","isButton","stopPropagation","getMenuSize","tab","clone","position","opacity","scrollWidth","height","scrollHeight","showMenuPanel","_this6","size","restore","propertyName","firstItem","focus","create","_this7","aria-haspopup","aria-controls","aria-expanded","aria-labelled-by","inner","home","menuItem","flex","back","inject","_this8","Math","floor","random","props","seektime","insertAdjacentHTML","setTimeout","offsetHeight","_config","labels","parseUrl","parser","href","buildUrlParams","params","URLSearchParams","setup","isVideo","isYouTube","hostname","protocol","blob","createObjectURL","languages","userLanguage","active","trackEvents","_captions","meta","currentTrackNode","languageExists","mode","updateCues","setLanguage","activeClass","findTrack","toConsumableArray","embed","enableTextTrack","has","sortIsDefault","sorted","every","getCurrentTrack","cues","activeCues","getCueAsHTML","cueText","caption","defaults","autoplay","autopause","toggleInvert","ratio","clickToPlay","hideControls","resetOnEnd","disableContextMenu","loop","selected","keyboard","global","fallback","iosNative","seekLabel","unmute","enableCaptions","disableCaptions","enterFullscreen","exitFullscreen","frameTitle","menuBack","normal","start","end","all","reset","disabled","advertisement","qualityBadge","2160","1440","1080","720","576","480","urls","vimeo","sdk","iframe","youtube","googleIMA","listeners","editable","embedContainer","poster","posterEnabled","ads","stopped","loading","hover","isTouch","uiSupported","noTransition","tabFocus","google","publisherId","providers","types","noop","Console","onChange","first","last","keyCode","shiftKey","preventDefault","toggleFallback","scrollPosition","x","scrollX","y","scrollY","scrollTo","overflow","Fullscreen","property","native","webkitEnterFullscreen","requestFullscreen","webkitExitFullscreen","action","cancelFullScreen","exit","enter","fullscreenElement","fullscreenEnabled","webkitFullscreenEnabled","mozFullScreenEnabled","msFullscreenEnabled","pre","loadImage","minWidth","image","Image","handler","onload","onerror","naturalWidth","addStyleHook","build","checkPlaying","ready","setTitle","setPoster","isEmbed","togglePoster","enable","backgroundImage","backgroundSize","toggleControls","checkLoading","clearTimeout","timers","Listeners","lastKey","handleKey","firstTouch","code","which","repeat","altKey","ctrlKey","metaKey","togglePlay","increaseVolume","decreaseVolume","forward","toggleCaptions","delay","hasAudio","initialized","managerPromise","isAudio","ended","proxyEvents","_event$detail","inputEvent","proxy","defaultHandler","customHandlerKey","customHandler","returned","hasCustomHandler","showHomeTab","currentTarget","eventType","done","seekTo","_player","webkitDirectionInvertedFromDevice","direction","deltaY","deltaX","factory","devnull","bundleIdCache","bundleResultCache","bundleCallbackQueue","publish","bundleId","pathsNotFound","q","splice","executeCallbacks","depsNotFound","success","loadFile","callbackFn","numTries","isCss","doc","async","maxTries","numRetries","beforeCallbackFn","before","pathStripped","rel","onbeforeload","ev","sheet","cssText","defaultPrevented","head","loadjs","paths","arg1","arg2","fn","numWaiting","loadFiles","deps","bundleIds","r","subscribe","isDefined","module","exports","loadScript","assurePlaybackState","hasPlayed","setAspectRatio","Vimeo","_split","_split2","padding","paddingBottom","offset","transform","byline","portrait","transparent","gesture","$2","thumbnail_large","pathname","Player","disableTextTrack","stop","restorePause","setVolume","setCurrentTime","setPlaybackRate","name","setLoop","currentSrc","getVideoUrl","getVideoWidth","getVideoHeight","dimensions","getRatio","w","h","getAspectRatio","setAutopause","state","getVideoTitle","getCurrentTime","getDuration","getTextTracks","_ref$cues","strippedCues","fragment","createDocumentFragment","firstChild","getPaused","seconds","mapQualityUnit","entry","hd2160","hd1440","hd1080","hd720","large","medium","small","tiny","YT","onYouTubeReadyCallbacks","onYouTubeIframeAPIReady","getTitle","videoId","getVideoData","items","snippet","currentId","startsWith","posterSrc","format$$1","playerVars","showinfo","iv_load_policy","modestbranding","disablekb","widget_referrer","cc_load_policy","cc_lang_pref","onError","message","2","5","100","101","150","onPlaybackQualityChange","onPlaybackRateChange","instance","playbackRate","getPlaybackRate","onReady","playVideo","pauseVideo","stopVideo","getPlaybackQuality","setPlaybackQuality","getAvailablePlaybackRates","clearInterval","buffering","setInterval","getVideoLoadedFraction","lastBuffered","onStateChange","levels","getAvailableQualityLevels","level","unMute","Ads","displayContainer","manager","loader","cuePoints","safetyTimer","countdownTimer","ima","trigger","startSafetyTimer","clearSafetyTimer","setupIMA","setVpaidMode","ImaSdkSettings","VpaidMode","ENABLED","setLocale","AdDisplayContainer","requestAds","AdsLoader","AdsManagerLoadedEvent","Type","ADS_MANAGER_LOADED","onAdsManagerLoaded","AdErrorEvent","AD_ERROR","onAdError","AdsRequest","adTagUrl","tagUrl","linearAdSlotWidth","offsetWidth","linearAdSlotHeight","nonLinearAdSlotWidth","nonLinearAdSlotHeight","forceNonLinearFullSlot","setAdWillPlayMuted","getRemainingTime","AdsRenderingSettings","restoreCustomPlaybackStateOnAdBreakComplete","enablePreloading","getAdsManager","getCuePoints","cuePoint","seekElement","cuePercentage","AdEvent","onAdEvent","ad","getAd","LOADED","pollCountdown","isLinear","ALL_ADS_COMPLETED","loadAds","CONTENT_PAUSE_REQUESTED","pauseContent","CONTENT_RESUME_REQUESTED","resumeContent","STARTED","MIDPOINT","COMPLETE","IMPRESSION","CLICK","cancel","contentComplete","seekedTime","discardAdBreak","resize","ViewMode","NORMAL","_this9","initialize","init","adError","zIndex","_this10","destroy","_this11","handlers","_this12","base","AV_PUBLISHERID","AV_CHANNELID","AV_URL","cb","Date","now","AV_WIDTH","AV_HEIGHT","AV_CDIM2","insertElements","attribute","change","_sources$","_sources$$provider","tagName","crossorigin","Plyr","failed","jQuery","original","getProviderByUrl","searchParams","truthy","webkitShowPlaybackTargetPicker","isHidden","hiding","eventName","soft","unload","inputIsValid","fauxDuration","mozHasAudio","webkitAudioDecodedByteCount","audioTracks","prev","curr","abs","closest","states","webkitPresentationMode","inline","t"],"mappings":"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","file":"plyr.min.js","sourcesContent":["// ==========================================================================\n// Type checking utils\n// ==========================================================================\n\nconst getConstructor = input => (input !== null && typeof input !== 'undefined' ? input.constructor : null);\n\nconst instanceOf = (input, constructor) => Boolean(input && constructor && input instanceof constructor);\n\nconst is = {\n object(input) {\n return getConstructor(input) === Object;\n },\n number(input) {\n return getConstructor(input) === Number && !Number.isNaN(input);\n },\n string(input) {\n return getConstructor(input) === String;\n },\n boolean(input) {\n return getConstructor(input) === Boolean;\n },\n function(input) {\n return getConstructor(input) === Function;\n },\n array(input) {\n return !is.nullOrUndefined(input) && Array.isArray(input);\n },\n weakMap(input) {\n return instanceOf(input, WeakMap);\n },\n nodeList(input) {\n return instanceOf(input, NodeList);\n },\n element(input) {\n return instanceOf(input, Element);\n },\n textNode(input) {\n return getConstructor(input) === Text;\n },\n event(input) {\n return instanceOf(input, Event);\n },\n cue(input) {\n return instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue);\n },\n track(input) {\n return instanceOf(input, TextTrack) || (!is.nullOrUndefined(input) && is.string(input.kind));\n },\n url(input) {\n return (\n !is.nullOrUndefined(input) &&\n /(ftp|http|https):\\/\\/(\\w+:{0,1}\\w*@)?(\\S+)(:[0-9]+)?(\\/|\\/([\\w#!:.?+=&%@!\\-/]))?/.test(input)\n );\n },\n nullOrUndefined(input) {\n return input === null || typeof input === 'undefined';\n },\n empty(input) {\n return (\n is.nullOrUndefined(input) ||\n ((is.string(input) || is.array(input) || is.nodeList(input)) && !input.length) ||\n (is.object(input) && !Object.keys(input).length)\n );\n },\n};\n\nexport default is;\n","// ==========================================================================\n// Event utils\n// ==========================================================================\n\nimport is from './is';\n\n// Check for passive event listener support\n// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md\n// https://www.youtube.com/watch?v=NPM6172J22g\nconst supportsPassiveListeners = (() => {\n // Test via a getter in the options object to see if the passive property is accessed\n let supported = false;\n try {\n const options = Object.defineProperty({}, 'passive', {\n get() {\n supported = true;\n return null;\n },\n });\n window.addEventListener('test', null, options);\n window.removeEventListener('test', null, options);\n } catch (e) {\n // Do nothing\n }\n\n return supported;\n})();\n\n// Toggle event listener\nexport function toggleListener(element, event, callback, toggle = false, passive = true, capture = false) {\n // Bail if no element, event, or callback\n if (!element || !('addEventListener' in element) || is.empty(event) || !is.function(callback)) {\n return;\n }\n\n // Allow multiple events\n const events = event.split(' ');\n\n // Build options\n // Default to just the capture boolean for browsers with no passive listener support\n let options = capture;\n\n // If passive events listeners are supported\n if (supportsPassiveListeners) {\n options = {\n // Whether the listener can be passive (i.e. default never prevented)\n passive,\n // Whether the listener is a capturing listener or not\n capture,\n };\n }\n\n // If a single node is passed, bind the event listener\n events.forEach(type => {\n if (this && this.eventListeners && toggle) {\n // Cache event listener\n this.eventListeners.push({ element, type, callback, options });\n }\n\n element[toggle ? 'addEventListener' : 'removeEventListener'](type, callback, options);\n });\n}\n\n// Bind event handler\nexport function on(element, events = '', callback, passive = true, capture = false) {\n toggleListener.call(this, element, events, callback, true, passive, capture);\n}\n\n// Unbind event handler\nexport function off(element, events = '', callback, passive = true, capture = false) {\n toggleListener.call(this, element, events, callback, false, passive, capture);\n}\n\n// Bind once-only event handler\nexport function once(element, events = '', callback, passive = true, capture = false) {\n function onceCallback(...args) {\n off(element, events, onceCallback, passive, capture);\n callback.apply(this, args);\n }\n\n toggleListener.call(this, element, events, onceCallback, true, passive, capture);\n}\n\n// Trigger event\nexport function triggerEvent(element, type = '', bubbles = false, detail = {}) {\n // Bail if no element\n if (!is.element(element) || is.empty(type)) {\n return;\n }\n\n // Create and dispatch the event\n const event = new CustomEvent(type, {\n bubbles,\n detail: Object.assign({}, detail, {\n plyr: this,\n }),\n });\n\n // Dispatch the event\n element.dispatchEvent(event);\n}\n\n// Unbind all cached event listeners\nexport function unbindListeners() {\n if (this && this.eventListeners) {\n this.eventListeners.forEach(item => {\n const { element, type, callback, options } = item;\n element.removeEventListener(type, callback, options);\n });\n\n this.eventListeners = [];\n }\n}\n\n// Run method when / if player is ready\nexport function ready() {\n return new Promise(\n resolve => (this.ready ? setTimeout(resolve, 0) : on.call(this, this.elements.container, 'ready', resolve)),\n ).then(() => {});\n}\n","// ==========================================================================\n// Element utils\n// ==========================================================================\n\nimport { toggleListener } from './events';\nimport is from './is';\n\n// Wrap an element\nexport function wrap(elements, wrapper) {\n // Convert `elements` to an array, if necessary.\n const targets = elements.length ? elements : [elements];\n\n // Loops backwards to prevent having to clone the wrapper on the\n // first element (see `child` below).\n Array.from(targets)\n .reverse()\n .forEach((element, index) => {\n const child = index > 0 ? wrapper.cloneNode(true) : wrapper;\n\n // Cache the current parent and sibling.\n const parent = element.parentNode;\n const sibling = element.nextSibling;\n\n // Wrap the element (is automatically removed from its current\n // parent).\n child.appendChild(element);\n\n // If the element had a sibling, insert the wrapper before\n // the sibling to maintain the HTML structure; otherwise, just\n // append it to the parent.\n if (sibling) {\n parent.insertBefore(child, sibling);\n } else {\n parent.appendChild(child);\n }\n });\n}\n\n// Set attributes\nexport function setAttributes(element, attributes) {\n if (!is.element(element) || is.empty(attributes)) {\n return;\n }\n\n // Assume null and undefined attributes should be left out,\n // Setting them would otherwise convert them to \"null\" and \"undefined\"\n Object.entries(attributes)\n .filter(([, value]) => !is.nullOrUndefined(value))\n .forEach(([key, value]) => element.setAttribute(key, value));\n}\n\n// Create a DocumentFragment\nexport function createElement(type, attributes, text) {\n // Create a new <element>\n const element = document.createElement(type);\n\n // Set all passed attributes\n if (is.object(attributes)) {\n setAttributes(element, attributes);\n }\n\n // Add text node\n if (is.string(text)) {\n element.innerText = text;\n }\n\n // Return built element\n return element;\n}\n\n// Inaert an element after another\nexport function insertAfter(element, target) {\n if (!is.element(element) || !is.element(target)) {\n return;\n }\n\n target.parentNode.insertBefore(element, target.nextSibling);\n}\n\n// Insert a DocumentFragment\nexport function insertElement(type, parent, attributes, text) {\n if (!is.element(parent)) {\n return;\n }\n\n parent.appendChild(createElement(type, attributes, text));\n}\n\n// Remove element(s)\nexport function removeElement(element) {\n if (is.nodeList(element) || is.array(element)) {\n Array.from(element).forEach(removeElement);\n return;\n }\n\n if (!is.element(element) || !is.element(element.parentNode)) {\n return;\n }\n\n element.parentNode.removeChild(element);\n}\n\n// Remove all child elements\nexport function emptyElement(element) {\n if (!is.element(element)) {\n return;\n }\n\n let { length } = element.childNodes;\n\n while (length > 0) {\n element.removeChild(element.lastChild);\n length -= 1;\n }\n}\n\n// Replace element\nexport function replaceElement(newChild, oldChild) {\n if (!is.element(oldChild) || !is.element(oldChild.parentNode) || !is.element(newChild)) {\n return null;\n }\n\n oldChild.parentNode.replaceChild(newChild, oldChild);\n\n return newChild;\n}\n\n// Get an attribute object from a string selector\nexport function getAttributesFromSelector(sel, existingAttributes) {\n // For example:\n // '.test' to { class: 'test' }\n // '#test' to { id: 'test' }\n // '[data-test=\"test\"]' to { 'data-test': 'test' }\n\n if (!is.string(sel) || is.empty(sel)) {\n return {};\n }\n\n const attributes = {};\n const existing = existingAttributes;\n\n sel.split(',').forEach(s => {\n // Remove whitespace\n const selector = s.trim();\n const className = selector.replace('.', '');\n const stripped = selector.replace(/[[\\]]/g, '');\n\n // Get the parts and value\n const parts = stripped.split('=');\n const key = parts[0];\n const value = parts.length > 1 ? parts[1].replace(/[\"']/g, '') : '';\n\n // Get the first character\n const start = selector.charAt(0);\n\n switch (start) {\n case '.':\n // Add to existing classname\n if (is.object(existing) && is.string(existing.class)) {\n existing.class += ` ${className}`;\n }\n\n attributes.class = className;\n break;\n\n case '#':\n // ID selector\n attributes.id = selector.replace('#', '');\n break;\n\n case '[':\n // Attribute selector\n attributes[key] = value;\n\n break;\n\n default:\n break;\n }\n });\n\n return attributes;\n}\n\n// Toggle hidden\nexport function toggleHidden(element, hidden) {\n if (!is.element(element)) {\n return;\n }\n\n let hide = hidden;\n\n if (!is.boolean(hide)) {\n hide = !element.hasAttribute('hidden');\n }\n\n if (hide) {\n element.setAttribute('hidden', '');\n } else {\n element.removeAttribute('hidden');\n }\n}\n\n// Mirror Element.classList.toggle, with IE compatibility for \"force\" argument\nexport function toggleClass(element, className, force) {\n if (is.element(element)) {\n let method = 'toggle';\n if (typeof force !== 'undefined') {\n method = force ? 'add' : 'remove';\n }\n\n element.classList[method](className);\n return element.classList.contains(className);\n }\n\n return null;\n}\n\n// Has class name\nexport function hasClass(element, className) {\n return is.element(element) && element.classList.contains(className);\n}\n\n// Element matches selector\nexport function matches(element, selector) {\n const prototype = { Element };\n\n function match() {\n return Array.from(document.querySelectorAll(selector)).includes(this);\n }\n\n const matches =\n prototype.matches ||\n prototype.webkitMatchesSelector ||\n prototype.mozMatchesSelector ||\n prototype.msMatchesSelector ||\n match;\n\n return matches.call(element, selector);\n}\n\n// Find all elements\nexport function getElements(selector) {\n return this.elements.container.querySelectorAll(selector);\n}\n\n// Find a single element\nexport function getElement(selector) {\n return this.elements.container.querySelector(selector);\n}\n\n// Get the focused element\nexport function getFocusElement() {\n let focused = document.activeElement;\n\n if (!focused || focused === document.body) {\n focused = null;\n } else {\n focused = document.querySelector(':focus');\n }\n\n return focused;\n}\n\n// Trap focus inside container\nexport function trapFocus(element = null, toggle = false) {\n if (!is.element(element)) {\n return;\n }\n\n const focusable = getElements.call(this, 'button:not(:disabled), input:not(:disabled), [tabindex]');\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n const trap = event => {\n // Bail if not tab key or not fullscreen\n if (event.key !== 'Tab' || event.keyCode !== 9) {\n return;\n }\n\n // Get the current focused element\n const focused = getFocusElement();\n\n if (focused === last && !event.shiftKey) {\n // Move focus to first element that can be tabbed if Shift isn't used\n first.focus();\n event.preventDefault();\n } else if (focused === first && event.shiftKey) {\n // Move focus to last element that can be tabbed if Shift is used\n last.focus();\n event.preventDefault();\n }\n };\n\n toggleListener.call(this, this.elements.container, 'keydown', trap, toggle, false);\n}\n","// ==========================================================================\n// Animation utils\n// ==========================================================================\n\nimport { toggleHidden } from './elements';\nimport is from './is';\n\nexport const transitionEndEvent = (() => {\n const element = document.createElement('span');\n\n const events = {\n WebkitTransition: 'webkitTransitionEnd',\n MozTransition: 'transitionend',\n OTransition: 'oTransitionEnd otransitionend',\n transition: 'transitionend',\n };\n\n const type = Object.keys(events).find(event => element.style[event] !== undefined);\n\n return is.string(type) ? events[type] : false;\n})();\n\n// Force repaint of element\nexport function repaint(element) {\n setTimeout(() => {\n toggleHidden(element, true);\n element.offsetHeight; // eslint-disable-line\n toggleHidden(element, false);\n }, 0);\n}\n","// ==========================================================================\n// Browser sniffing\n// Unfortunately, due to mixed support, UA sniffing is required\n// ==========================================================================\n\nconst browser = {\n isIE: /* @cc_on!@ */ false || !!document.documentMode,\n isWebkit: 'WebkitAppearance' in document.documentElement.style && !/Edge/.test(navigator.userAgent),\n isIPhone: /(iPhone|iPod)/gi.test(navigator.platform),\n isIos: /(iPad|iPhone|iPod)/gi.test(navigator.platform),\n};\n\nexport default browser;\n","// ==========================================================================\n// Plyr support checks\n// ==========================================================================\n\nimport { transitionEndEvent } from './utils/animation';\nimport browser from './utils/browser';\nimport { createElement } from './utils/elements';\nimport is from './utils/is';\n\n// Default codecs for checking mimetype support\nconst defaultCodecs = {\n 'audio/ogg': 'vorbis',\n 'audio/wav': '1',\n 'video/webm': 'vp8, vorbis',\n 'video/mp4': 'avc1.42E01E, mp4a.40.2',\n 'video/ogg': 'theora',\n};\n\n// Check for feature support\nconst support = {\n // Basic support\n audio: 'canPlayType' in document.createElement('audio'),\n video: 'canPlayType' in document.createElement('video'),\n\n // Check for support\n // Basic functionality vs full UI\n check(type, provider, playsinline) {\n const canPlayInline = browser.isIPhone && playsinline && support.playsinline;\n const api = support[type] || provider !== 'html5';\n const ui = api && support.rangeInput && (type !== 'video' || !browser.isIPhone || canPlayInline);\n\n return {\n api,\n ui,\n };\n },\n\n // Picture-in-picture support\n // Safari only currently\n pip: (() => !browser.isIPhone && is.function(createElement('video').webkitSetPresentationMode))(),\n\n // Airplay support\n // Safari only currently\n airplay: is.function(window.WebKitPlaybackTargetAvailabilityEvent),\n\n // Inline playback support\n // https://webkit.org/blog/6784/new-video-policies-for-ios/\n playsinline: 'playsInline' in document.createElement('video'),\n\n // Check for mime type support against a player instance\n // Credits: http://diveintohtml5.info/everything.html\n // Related: http://www.leanbackplayer.com/test/h5mt.html\n mime(inputType) {\n const [mediaType] = inputType.split('/');\n if (!this.isHTML5 || mediaType !== this.type) {\n return false;\n }\n\n let type;\n if (inputType && inputType.includes('codecs=')) {\n // Use input directly\n type = inputType;\n } else if (inputType === 'audio/mpeg') {\n // Skip codec\n type = 'audio/mpeg;';\n } else if (inputType in defaultCodecs) {\n // Use codec\n type = `${inputType}; codecs=\"${defaultCodecs[inputType]}\"`;\n }\n\n try {\n return Boolean(type && this.media.canPlayType(type).replace(/no/, ''));\n } catch (err) {\n return false;\n }\n },\n\n // Check for textTracks support\n textTracks: 'textTracks' in document.createElement('video'),\n\n // <input type=\"range\"> Sliders\n rangeInput: (() => {\n const range = document.createElement('input');\n range.type = 'range';\n return range.type === 'range';\n })(),\n\n // Touch\n // NOTE: Remember a device can be mouse + touch enabled so we check on first touch event\n touch: 'ontouchstart' in document.documentElement,\n\n // Detect transitions support\n transitions: transitionEndEvent !== false,\n\n // Reduced motion iOS & MacOS setting\n // https://webkit.org/blog/7551/responsive-design-for-motion/\n reducedMotion: 'matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches,\n};\n\nexport default support;\n","// ==========================================================================\n// Plyr HTML5 helpers\n// ==========================================================================\n\nimport support from './support';\nimport { removeElement } from './utils/elements';\nimport { triggerEvent } from './utils/events';\n\nconst html5 = {\n getSources() {\n if (!this.isHTML5) {\n return [];\n }\n\n const sources = Array.from(this.media.querySelectorAll('source'));\n\n // Filter out unsupported sources\n return sources.filter(source => support.mime.call(this, source.getAttribute('type')));\n },\n\n // Get quality levels\n getQualityOptions() {\n // Get sizes from <source> elements\n return html5.getSources\n .call(this)\n .map(source => Number(source.getAttribute('size')))\n .filter(Boolean);\n },\n\n extend() {\n if (!this.isHTML5) {\n return;\n }\n\n const player = this;\n\n // Quality\n Object.defineProperty(player.media, 'quality', {\n get() {\n // Get sources\n const sources = html5.getSources.call(player);\n const [source] = sources.filter(source => source.getAttribute('src') === player.source);\n\n // Return size, if match is found\n return source && Number(source.getAttribute('size'));\n },\n set(input) {\n // Get sources\n const sources = html5.getSources.call(player);\n\n // Get first match for requested size\n const source = sources.find(source => Number(source.getAttribute('size')) === input);\n\n // No matching source found\n if (!source) {\n return;\n }\n\n // Get current state\n const { currentTime, playing } = player;\n\n // Set new source\n player.media.src = source.getAttribute('src');\n\n // Restore time\n const onLoadedMetaData = () => {\n player.currentTime = currentTime;\n };\n player.once('loadedmetadata', onLoadedMetaData);\n\n // Load new source\n player.media.load();\n\n // Resume playing\n if (playing) {\n player.play();\n }\n\n // Trigger change event\n triggerEvent.call(player, player.media, 'qualitychange', false, {\n quality: input,\n });\n },\n });\n },\n\n // Cancel current network requests\n // See https://github.com/sampotts/plyr/issues/174\n cancelRequests() {\n if (!this.isHTML5) {\n return;\n }\n\n // Remove child sources\n removeElement(html5.getSources.call(this));\n\n // Set blank video src attribute\n // This is to prevent a MEDIA_ERR_SRC_NOT_SUPPORTED error\n // Info: http://stackoverflow.com/questions/32231579/how-to-properly-dispose-of-an-html5-video-and-close-socket-or-connection\n this.media.setAttribute('src', this.config.blankVideo);\n\n // Load the new empty source\n // This will cancel existing requests\n // See https://github.com/sampotts/plyr/issues/174\n this.media.load();\n\n // Debugging\n this.debug.log('Cancelled network requests');\n },\n};\n\nexport default html5;\n","// ==========================================================================\n// Object utils\n// ==========================================================================\n\nimport is from './is';\n\n// Clone nested objects\nexport function cloneDeep(object) {\n return JSON.parse(JSON.stringify(object));\n}\n\n// Get a nested value in an object\nexport function getDeep(object, path) {\n return path.split('.').reduce((obj, key) => obj && obj[key], object);\n}\n\n// Deep extend destination object with N more objects\nexport function extend(target = {}, ...sources) {\n if (!sources.length) {\n return target;\n }\n\n const source = sources.shift();\n\n if (!is.object(source)) {\n return target;\n }\n\n Object.keys(source).forEach(key => {\n if (is.object(source[key])) {\n if (!Object.keys(target).includes(key)) {\n Object.assign(target, { [key]: {} });\n }\n\n extend(target[key], source[key]);\n } else {\n Object.assign(target, { [key]: source[key] });\n }\n });\n\n return extend(target, ...sources);\n}\n","// ==========================================================================\n// String utils\n// ==========================================================================\n\nimport is from './is';\n\n// Generate a random ID\nexport function generateId(prefix) {\n return `${prefix}-${Math.floor(Math.random() * 10000)}`;\n}\n\n// Format string\nexport function format(input, ...args) {\n if (is.empty(input)) {\n return input;\n }\n\n return input.toString().replace(/{(\\d+)}/g, (match, i) => args[i].toString());\n}\n\n// Get percentage\nexport function getPercentage(current, max) {\n if (current === 0 || max === 0 || Number.isNaN(current) || Number.isNaN(max)) {\n return 0;\n }\n\n return (current / max * 100).toFixed(2);\n}\n\n// Replace all occurances of a string in a string\nexport function replaceAll(input = '', find = '', replace = '') {\n return input.replace(\n new RegExp(find.toString().replace(/([.*+?^=!:${}()|[\\]/\\\\])/g, '\\\\$1'), 'g'),\n replace.toString(),\n );\n}\n\n// Convert to title case\nexport function toTitleCase(input = '') {\n return input.toString().replace(/\\w\\S*/g, text => text.charAt(0).toUpperCase() + text.substr(1).toLowerCase());\n}\n\n// Convert string to pascalCase\nexport function toPascalCase(input = '') {\n let string = input.toString();\n\n // Convert kebab case\n string = replaceAll(string, '-', ' ');\n\n // Convert snake case\n string = replaceAll(string, '_', ' ');\n\n // Convert to title case\n string = toTitleCase(string);\n\n // Convert to pascal case\n return replaceAll(string, ' ', '');\n}\n\n// Convert string to pascalCase\nexport function toCamelCase(input = '') {\n let string = input.toString();\n\n // Convert to pascal case\n string = toPascalCase(string);\n\n // Convert first character to lowercase\n return string.charAt(0).toLowerCase() + string.slice(1);\n}\n\n// Remove HTML from a string\nexport function stripHTML(source) {\n const fragment = document.createDocumentFragment();\n const element = document.createElement('div');\n fragment.appendChild(element);\n element.innerHTML = source;\n return fragment.firstChild.innerText;\n}\n\n// Like outerHTML, but also works for DocumentFragment\nexport function getHTML(element) {\n const wrapper = document.createElement('div');\n wrapper.appendChild(element);\n return wrapper.innerHTML;\n}\n","// ==========================================================================\n// Plyr internationalization\n// ==========================================================================\n\nimport is from './utils/is';\nimport { getDeep } from './utils/objects';\nimport { replaceAll } from './utils/strings';\n\nconst i18n = {\n get(key = '', config = {}) {\n if (is.empty(key) || is.empty(config)) {\n return '';\n }\n\n let string = getDeep(config.i18n, key);\n\n if (is.empty(string)) {\n return '';\n }\n\n const replace = {\n '{seektime}': config.seekTime,\n '{title}': config.title,\n };\n\n Object.entries(replace).forEach(([key, value]) => {\n string = replaceAll(string, key, value);\n });\n\n return string;\n },\n};\n\nexport default i18n;\n","// ==========================================================================\n// Array utils\n// ==========================================================================\n\nimport is from './is';\n\n// Remove duplicates in an array\nexport function dedupe(array) {\n if (!is.array(array)) {\n return array;\n }\n\n return array.filter((item, index) => array.indexOf(item) === index);\n}\n\n// Get the closest value in an array\nexport function closest(array, value) {\n if (!is.array(array) || !array.length) {\n return null;\n }\n\n return array.reduce((prev, curr) => (Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev));\n}\n","// ==========================================================================\n// Plyr storage\n// ==========================================================================\n\nimport is from './utils/is';\nimport { extend } from './utils/objects';\n\nclass Storage {\n constructor(player) {\n this.enabled = player.config.storage.enabled;\n this.key = player.config.storage.key;\n }\n\n // Check for actual support (see if we can use it)\n static get supported() {\n try {\n if (!('localStorage' in window)) {\n return false;\n }\n\n const test = '___test';\n\n // Try to use it (it might be disabled, e.g. user is in private mode)\n // see: https://github.com/sampotts/plyr/issues/131\n window.localStorage.setItem(test, test);\n window.localStorage.removeItem(test);\n\n return true;\n } catch (e) {\n return false;\n }\n }\n\n get(key) {\n if (!Storage.supported || !this.enabled) {\n return null;\n }\n\n const store = window.localStorage.getItem(this.key);\n\n if (is.empty(store)) {\n return null;\n }\n\n const json = JSON.parse(store);\n\n return is.string(key) && key.length ? json[key] : json;\n }\n\n set(object) {\n // Bail if we don't have localStorage support or it's disabled\n if (!Storage.supported || !this.enabled) {\n return;\n }\n\n // Can only store objectst\n if (!is.object(object)) {\n return;\n }\n\n // Get current storage\n let storage = this.get();\n\n // Default to empty object\n if (is.empty(storage)) {\n storage = {};\n }\n\n // Update the working copy of the values\n extend(storage, object);\n\n // Update storage\n window.localStorage.setItem(this.key, JSON.stringify(storage));\n }\n}\n\nexport default Storage;\n","// ==========================================================================\n// Fetch wrapper\n// Using XHR to avoid issues with older browsers\n// ==========================================================================\n\nexport default function fetch(url, responseType = 'text') {\n return new Promise((resolve, reject) => {\n try {\n const request = new XMLHttpRequest();\n\n // Check for CORS support\n if (!('withCredentials' in request)) {\n return;\n }\n\n request.addEventListener('load', () => {\n if (responseType === 'text') {\n try {\n resolve(JSON.parse(request.responseText));\n } catch (e) {\n resolve(request.responseText);\n }\n } else {\n resolve(request.response);\n }\n });\n\n request.addEventListener('error', () => {\n throw new Error(request.status);\n });\n\n request.open('GET', url, true);\n\n // Set the required response type\n request.responseType = responseType;\n\n request.send();\n } catch (e) {\n reject(e);\n }\n });\n}\n","// ==========================================================================\n// Sprite loader\n// ==========================================================================\n\nimport Storage from './../storage';\nimport fetch from './fetch';\nimport is from './is';\n\n// Load an external SVG sprite\nexport default function loadSprite(url, id) {\n if (!is.string(url)) {\n return;\n }\n\n const prefix = 'cache';\n const hasId = is.string(id);\n let isCached = false;\n\n const exists = () => document.getElementById(id) !== null;\n\n const update = (container, data) => {\n container.innerHTML = data;\n\n // Check again incase of race condition\n if (hasId && exists()) {\n return;\n }\n\n // Inject the SVG to the body\n document.body.insertAdjacentElement('afterbegin', container);\n };\n\n // Only load once if ID set\n if (!hasId || !exists()) {\n const useStorage = Storage.supported;\n\n // Create container\n const container = document.createElement('div');\n container.setAttribute('hidden', '');\n\n if (hasId) {\n container.setAttribute('id', id);\n }\n\n // Check in cache\n if (useStorage) {\n const cached = window.localStorage.getItem(`${prefix}-${id}`);\n isCached = cached !== null;\n\n if (isCached) {\n const data = JSON.parse(cached);\n update(container, data.content);\n }\n }\n\n // Get the sprite\n fetch(url)\n .then(result => {\n if (is.empty(result)) {\n return;\n }\n\n if (useStorage) {\n window.localStorage.setItem(\n `${prefix}-${id}`,\n JSON.stringify({\n content: result,\n }),\n );\n }\n\n update(container, result);\n })\n .catch(() => {});\n }\n}\n","// ==========================================================================\n// Time utils\n// ==========================================================================\n\nimport is from './is';\n\n// Time helpers\nexport const getHours = value => parseInt((value / 60 / 60) % 60, 10);\nexport const getMinutes = value => parseInt((value / 60) % 60, 10);\nexport const getSeconds = value => parseInt(value % 60, 10);\n\n// Format time to UI friendly string\nexport function formatTime(time = 0, displayHours = false, inverted = false) {\n // Bail if the value isn't a number\n if (!is.number(time)) {\n return formatTime(null, displayHours, inverted);\n }\n\n // Format time component to add leading zero\n const format = value => `0${value}`.slice(-2);\n\n // Breakdown to hours, mins, secs\n let hours = getHours(time);\n const mins = getMinutes(time);\n const secs = getSeconds(time);\n\n // Do we need to display hours?\n if (displayHours || hours > 0) {\n hours = `${hours}:`;\n } else {\n hours = '';\n }\n\n // Render\n return `${inverted && time > 0 ? '-' : ''}${hours}${format(mins)}:${format(secs)}`;\n}\n","// ==========================================================================\n// Plyr controls\n// ==========================================================================\n\nimport captions from './captions';\nimport html5 from './html5';\nimport i18n from './i18n';\nimport support from './support';\nimport { repaint, transitionEndEvent } from './utils/animation';\nimport { dedupe } from './utils/arrays';\nimport browser from './utils/browser';\nimport { createElement, emptyElement, getAttributesFromSelector, getElement, getElements, hasClass, matches, removeElement, setAttributes, toggleClass, toggleHidden } from './utils/elements';\nimport { off, on } from './utils/events';\nimport is from './utils/is';\nimport loadSprite from './utils/loadSprite';\nimport { extend } from './utils/objects';\nimport { getPercentage, replaceAll, toCamelCase, toTitleCase } from './utils/strings';\nimport { formatTime, getHours } from './utils/time';\n\n// TODO: Don't export a massive object - break down and create class\nconst controls = {\n // Get icon URL\n getIconUrl() {\n const url = new URL(this.config.iconUrl, window.location);\n const cors = url.host !== window.location.host || (browser.isIE && !window.svg4everybody);\n\n return {\n url: this.config.iconUrl,\n cors,\n };\n },\n\n // Find the UI controls\n findElements() {\n try {\n this.elements.controls = getElement.call(this, this.config.selectors.controls.wrapper);\n\n // Buttons\n this.elements.buttons = {\n play: getElements.call(this, this.config.selectors.buttons.play),\n pause: getElement.call(this, this.config.selectors.buttons.pause),\n restart: getElement.call(this, this.config.selectors.buttons.restart),\n rewind: getElement.call(this, this.config.selectors.buttons.rewind),\n fastForward: getElement.call(this, this.config.selectors.buttons.fastForward),\n mute: getElement.call(this, this.config.selectors.buttons.mute),\n pip: getElement.call(this, this.config.selectors.buttons.pip),\n airplay: getElement.call(this, this.config.selectors.buttons.airplay),\n settings: getElement.call(this, this.config.selectors.buttons.settings),\n captions: getElement.call(this, this.config.selectors.buttons.captions),\n fullscreen: getElement.call(this, this.config.selectors.buttons.fullscreen),\n };\n\n // Progress\n this.elements.progress = getElement.call(this, this.config.selectors.progress);\n\n // Inputs\n this.elements.inputs = {\n seek: getElement.call(this, this.config.selectors.inputs.seek),\n volume: getElement.call(this, this.config.selectors.inputs.volume),\n };\n\n // Display\n this.elements.display = {\n buffer: getElement.call(this, this.config.selectors.display.buffer),\n currentTime: getElement.call(this, this.config.selectors.display.currentTime),\n duration: getElement.call(this, this.config.selectors.display.duration),\n };\n\n // Seek tooltip\n if (is.element(this.elements.progress)) {\n this.elements.display.seekTooltip = this.elements.progress.querySelector(\n `.${this.config.classNames.tooltip}`,\n );\n }\n\n return true;\n } catch (error) {\n // Log it\n this.debug.warn('It looks like there is a problem with your custom controls HTML', error);\n\n // Restore native video controls\n this.toggleNativeControls(true);\n\n return false;\n }\n },\n\n // Create <svg> icon\n createIcon(type, attributes) {\n const namespace = 'http://www.w3.org/2000/svg';\n const iconUrl = controls.getIconUrl.call(this);\n const iconPath = `${!iconUrl.cors ? iconUrl.url : ''}#${this.config.iconPrefix}`;\n\n // Create <svg>\n const icon = document.createElementNS(namespace, 'svg');\n setAttributes(\n icon,\n extend(attributes, {\n role: 'presentation',\n focusable: 'false',\n }),\n );\n\n // Create the <use> to reference sprite\n const use = document.createElementNS(namespace, 'use');\n const path = `${iconPath}-${type}`;\n\n // Set `href` attributes\n // https://github.com/sampotts/plyr/issues/460\n // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href\n if ('href' in use) {\n use.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);\n } else {\n use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', path);\n }\n\n // Add <use> to <svg>\n icon.appendChild(use);\n\n return icon;\n },\n\n // Create hidden text label\n createLabel(type, attr = {}) {\n // Skip i18n for abbreviations and brand names\n const universals = {\n pip: 'PIP',\n airplay: 'AirPlay',\n };\n const text = universals[type] || i18n.get(type, this.config);\n\n const attributes = Object.assign({}, attr, {\n class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' '),\n });\n return createElement('span', attributes, text);\n },\n\n // Create a badge\n createBadge(text) {\n if (is.empty(text)) {\n return null;\n }\n\n const badge = createElement('span', {\n class: this.config.classNames.menu.value,\n });\n\n badge.appendChild(\n createElement(\n 'span',\n {\n class: this.config.classNames.menu.badge,\n },\n text,\n ),\n );\n\n return badge;\n },\n\n // Create a <button>\n createButton(buttonType, attr) {\n const button = createElement('button');\n const attributes = Object.assign({}, attr);\n let type = toCamelCase(buttonType);\n\n let toggle = false;\n let label;\n let icon;\n let labelPressed;\n let iconPressed;\n\n if (!('type' in attributes)) {\n attributes.type = 'button';\n }\n\n if ('class' in attributes) {\n if (attributes.class.includes(this.config.classNames.control)) {\n attributes.class += ` ${this.config.classNames.control}`;\n }\n } else {\n attributes.class = this.config.classNames.control;\n }\n\n // Large play button\n switch (buttonType) {\n case 'play':\n toggle = true;\n label = 'play';\n labelPressed = 'pause';\n icon = 'play';\n iconPressed = 'pause';\n break;\n\n case 'mute':\n toggle = true;\n label = 'mute';\n labelPressed = 'unmute';\n icon = 'volume';\n iconPressed = 'muted';\n break;\n\n case 'captions':\n toggle = true;\n label = 'enableCaptions';\n labelPressed = 'disableCaptions';\n icon = 'captions-off';\n iconPressed = 'captions-on';\n break;\n\n case 'fullscreen':\n toggle = true;\n label = 'enterFullscreen';\n labelPressed = 'exitFullscreen';\n icon = 'enter-fullscreen';\n iconPressed = 'exit-fullscreen';\n break;\n\n case 'play-large':\n attributes.class += ` ${this.config.classNames.control}--overlaid`;\n type = 'play';\n label = 'play';\n icon = 'play';\n break;\n\n default:\n label = type;\n icon = buttonType;\n }\n\n // Setup toggle icon and labels\n if (toggle) {\n // Icon\n button.appendChild(controls.createIcon.call(this, iconPressed, { class: 'icon--pressed' }));\n button.appendChild(controls.createIcon.call(this, icon, { class: 'icon--not-pressed' }));\n\n // Label/Tooltip\n button.appendChild(controls.createLabel.call(this, labelPressed, { class: 'label--pressed' }));\n button.appendChild(controls.createLabel.call(this, label, { class: 'label--not-pressed' }));\n } else {\n button.appendChild(controls.createIcon.call(this, icon));\n button.appendChild(controls.createLabel.call(this, label));\n }\n\n // Merge attributes\n extend(attributes, getAttributesFromSelector(this.config.selectors.buttons[type], attributes));\n\n setAttributes(button, attributes);\n\n // We have multiple play buttons\n if (type === 'play') {\n if (!is.array(this.elements.buttons[type])) {\n this.elements.buttons[type] = [];\n }\n\n this.elements.buttons[type].push(button);\n } else {\n this.elements.buttons[type] = button;\n }\n\n // Toggle classname when pressed property is set\n const className = this.config.classNames.controlPressed;\n Object.defineProperty(button, 'pressed', {\n enumerable: true,\n get() {\n return hasClass(button, className);\n },\n set(pressed = false) {\n toggleClass(button, className, pressed);\n },\n });\n\n return button;\n },\n\n // Create an <input type='range'>\n createRange(type, attributes) {\n // Seek input\n const input = createElement(\n 'input',\n extend(\n getAttributesFromSelector(this.config.selectors.inputs[type]),\n {\n type: 'range',\n min: 0,\n max: 100,\n step: 0.01,\n value: 0,\n autocomplete: 'off',\n // A11y fixes for https://github.com/sampotts/plyr/issues/905\n role: 'slider',\n 'aria-label': i18n.get(type, this.config),\n 'aria-valuemin': 0,\n 'aria-valuemax': 100,\n 'aria-valuenow': 0,\n },\n attributes,\n ),\n );\n\n this.elements.inputs[type] = input;\n\n // Set the fill for webkit now\n controls.updateRangeFill.call(this, input);\n\n return input;\n },\n\n // Create a <progress>\n createProgress(type, attributes) {\n const progress = createElement(\n 'progress',\n extend(\n getAttributesFromSelector(this.config.selectors.display[type]),\n {\n min: 0,\n max: 100,\n value: 0,\n role: 'presentation',\n 'aria-hidden': true,\n },\n attributes,\n ),\n );\n\n // Create the label inside\n if (type !== 'volume') {\n progress.appendChild(createElement('span', null, '0'));\n\n const suffixKey = {\n played: 'played',\n buffer: 'buffered',\n }[type];\n const suffix = suffixKey ? i18n.get(suffixKey, this.config) : '';\n\n progress.innerText = `% ${suffix.toLowerCase()}`;\n }\n\n this.elements.display[type] = progress;\n\n return progress;\n },\n\n // Create time display\n createTime(type) {\n const attributes = getAttributesFromSelector(this.config.selectors.display[type]);\n\n const container = createElement(\n 'div',\n extend(attributes, {\n class: `${this.config.classNames.display.time} ${attributes.class ? attributes.class : ''}`.trim(),\n 'aria-label': i18n.get(type, this.config),\n }),\n '00:00',\n );\n\n // Reference for updates\n this.elements.display[type] = container;\n\n return container;\n },\n\n // Create a settings menu item\n createMenuItem({ value, list, type, title, badge = null, checked = false }) {\n const attributes = getAttributesFromSelector(this.config.selectors.inputs[type]);\n\n const item = createElement(\n 'button',\n extend(attributes, {\n type: 'button',\n role: 'menuitemradio',\n class: `${this.config.classNames.control} ${attributes.class ? attributes.class : ''}`.trim(),\n value,\n 'aria-checked': checked,\n })\n );\n\n // We have to set as HTML incase of special characters\n item.innerHTML = title;\n\n if (is.element(badge)) {\n item.appendChild(badge);\n }\n\n Object.defineProperty(item, 'checked', {\n enumerable: true,\n get() {\n return item.getAttribute('aria-checked') === 'true';\n },\n set(checked) {\n // Ensure exclusivity\n if (checked) {\n Array.from(item.parentNode.children)\n .filter(node => matches(node, '[role=\"menuitemradio\"]'))\n .forEach(node => node.setAttribute('aria-checked', 'false'));\n }\n\n item.setAttribute('aria-checked', checked ? 'true' : 'false');\n },\n });\n\n list.appendChild(item);\n },\n\n // Format a time for display\n formatTime(time = 0, inverted = false) {\n // Bail if the value isn't a number\n if (!is.number(time)) {\n return time;\n }\n\n // Always display hours if duration is over an hour\n const forceHours = getHours(this.duration) > 0;\n\n return formatTime(time, forceHours, inverted);\n },\n\n // Update the displayed time\n updateTimeDisplay(target = null, time = 0, inverted = false) {\n // Bail if there's no element to display or the value isn't a number\n if (!is.element(target) || !is.number(time)) {\n return;\n }\n\n // eslint-disable-next-line no-param-reassign\n target.innerText = controls.formatTime(time, inverted);\n },\n\n // Update volume UI and storage\n updateVolume() {\n if (!this.supported.ui) {\n return;\n }\n\n // Update range\n if (is.element(this.elements.inputs.volume)) {\n controls.setRange.call(this, this.elements.inputs.volume, this.muted ? 0 : this.volume);\n }\n\n // Update mute state\n if (is.element(this.elements.buttons.mute)) {\n this.elements.buttons.mute.pressed = this.muted || this.volume === 0;\n }\n },\n\n // Update seek value and lower fill\n setRange(target, value = 0) {\n if (!is.element(target)) {\n return;\n }\n\n // eslint-disable-next-line\n target.value = value;\n\n // Webkit range fill\n controls.updateRangeFill.call(this, target);\n },\n\n // Update <progress> elements\n updateProgress(event) {\n if (!this.supported.ui || !is.event(event)) {\n return;\n }\n\n let value = 0;\n\n const setProgress = (target, input) => {\n const value = is.number(input) ? input : 0;\n const progress = is.element(target) ? target : this.elements.display.buffer;\n\n // Update value and label\n if (is.element(progress)) {\n progress.value = value;\n\n // Update text label inside\n const label = progress.getElementsByTagName('span')[0];\n if (is.element(label)) {\n label.childNodes[0].nodeValue = value;\n }\n }\n };\n\n if (event) {\n switch (event.type) {\n // Video playing\n case 'timeupdate':\n case 'seeking':\n case 'seeked':\n value = getPercentage(this.currentTime, this.duration);\n\n // Set seek range value only if it's a 'natural' time event\n if (event.type === 'timeupdate') {\n controls.setRange.call(this, this.elements.inputs.seek, value);\n }\n\n break;\n\n // Check buffer status\n case 'playing':\n case 'progress':\n setProgress(this.elements.display.buffer, this.buffered * 100);\n\n break;\n\n default:\n break;\n }\n }\n },\n\n // Webkit polyfill for lower fill range\n updateRangeFill(target) {\n // Get range from event if event passed\n const range = is.event(target) ? target.target : target;\n\n // Needs to be a valid <input type='range'>\n if (!is.element(range) || range.getAttribute('type') !== 'range') {\n return;\n }\n\n // Set aria values for https://github.com/sampotts/plyr/issues/905\n if (matches(range, this.config.selectors.inputs.seek)) {\n range.setAttribute('aria-valuenow', this.currentTime);\n const currentTime = controls.formatTime(this.currentTime);\n const duration = controls.formatTime(this.duration);\n const format = i18n.get('seekLabel', this.config);\n range.setAttribute(\n 'aria-valuetext',\n format.replace('{currentTime}', currentTime).replace('{duration}', duration),\n );\n } else if (matches(range, this.config.selectors.inputs.volume)) {\n const percent = range.value * 100;\n range.setAttribute('aria-valuenow', percent);\n range.setAttribute('aria-valuetext', `${percent}%`);\n } else {\n range.setAttribute('aria-valuenow', range.value);\n }\n\n // WebKit only\n if (!browser.isWebkit) {\n return;\n }\n\n // Set CSS custom property\n range.style.setProperty('--value', `${range.value / range.max * 100}%`);\n },\n\n // Update hover tooltip for seeking\n updateSeekTooltip(event) {\n // Bail if setting not true\n if (\n !this.config.tooltips.seek ||\n !is.element(this.elements.inputs.seek) ||\n !is.element(this.elements.display.seekTooltip) ||\n this.duration === 0\n ) {\n return;\n }\n\n // Calculate percentage\n let percent = 0;\n const clientRect = this.elements.progress.getBoundingClientRect();\n const visible = `${this.config.classNames.tooltip}--visible`;\n\n const toggle = toggle => {\n toggleClass(this.elements.display.seekTooltip, visible, toggle);\n };\n\n // Hide on touch\n if (this.touch) {\n toggle(false);\n return;\n }\n\n // Determine percentage, if already visible\n if (is.event(event)) {\n percent = 100 / clientRect.width * (event.pageX - clientRect.left);\n } else if (hasClass(this.elements.display.seekTooltip, visible)) {\n percent = parseFloat(this.elements.display.seekTooltip.style.left, 10);\n } else {\n return;\n }\n\n // Set bounds\n if (percent < 0) {\n percent = 0;\n } else if (percent > 100) {\n percent = 100;\n }\n\n // Display the time a click would seek to\n controls.updateTimeDisplay.call(this, this.elements.display.seekTooltip, this.duration / 100 * percent);\n\n // Set position\n this.elements.display.seekTooltip.style.left = `${percent}%`;\n\n // Show/hide the tooltip\n // If the event is a moues in/out and percentage is inside bounds\n if (is.event(event) && ['mouseenter', 'mouseleave'].includes(event.type)) {\n toggle(event.type === 'mouseenter');\n }\n },\n\n // Handle time change event\n timeUpdate(event) {\n // Only invert if only one time element is displayed and used for both duration and currentTime\n const invert = !is.element(this.elements.display.duration) && this.config.invertTime;\n\n // Duration\n controls.updateTimeDisplay.call(\n this,\n this.elements.display.currentTime,\n invert ? this.duration - this.currentTime : this.currentTime,\n invert,\n );\n\n // Ignore updates while seeking\n if (event && event.type === 'timeupdate' && this.media.seeking) {\n return;\n }\n\n // Playing progress\n controls.updateProgress.call(this, event);\n },\n\n // Show the duration on metadataloaded or durationchange events\n durationUpdate() {\n // Bail if no UI or durationchange event triggered after playing/seek when invertTime is false\n if (!this.supported.ui || (!this.config.invertTime && this.currentTime)) {\n return;\n }\n\n // Update ARIA values\n if (is.element(this.elements.inputs.seek)) {\n this.elements.inputs.seek.setAttribute('aria-valuemax', this.duration);\n }\n\n // If there's a spot to display duration\n const hasDuration = is.element(this.elements.display.duration);\n\n // If there's only one time display, display duration there\n if (!hasDuration && this.config.displayDuration && this.paused) {\n controls.updateTimeDisplay.call(this, this.elements.display.currentTime, this.duration);\n }\n\n // If there's a duration element, update content\n if (hasDuration) {\n controls.updateTimeDisplay.call(this, this.elements.display.duration, this.duration);\n }\n\n // Update the tooltip (if visible)\n controls.updateSeekTooltip.call(this);\n },\n\n // Hide/show a tab\n toggleMenuButton(setting, toggle) {\n toggleHidden(this.elements.settings.buttons[setting], !toggle);\n },\n\n // Set the quality menu\n setQualityMenu(options) {\n // Menu required\n if (!is.element(this.elements.settings.panels.quality)) {\n console.warn('Not an element');\n return;\n }\n\n const type = 'quality';\n const list = this.elements.settings.panels.quality.querySelector('[role=\"menu\"]');\n\n // Set options if passed and filter based on uniqueness and config\n if (is.array(options)) {\n this.options.quality = dedupe(options).filter(quality => this.config.quality.options.includes(quality));\n }\n\n // Toggle the pane and tab\n console.warn(this.options.quality);\n const toggle = !is.empty(this.options.quality) && this.options.quality.length > 1;\n controls.toggleMenuButton.call(this, type, toggle);\n\n // Check if we need to toggle the parent\n controls.checkMenu.call(this);\n\n // If we're hiding, nothing more to do\n if (!toggle) {\n return;\n }\n\n // Empty the menu\n emptyElement(list);\n\n // Get the badge HTML for HD, 4K etc\n const getBadge = quality => {\n const label = i18n.get(`qualityBadge.${quality}`, this.config);\n\n if (!label.length) {\n return null;\n }\n\n return controls.createBadge.call(this, label);\n };\n\n // Sort options by the config and then render options\n this.options.quality\n .sort((a, b) => {\n const sorting = this.config.quality.options;\n return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;\n })\n .forEach(quality => {\n controls.createMenuItem.call(this, {\n value: quality,\n list,\n type,\n title: controls.getLabel.call(this, 'quality', quality),\n badge: getBadge(quality),\n });\n });\n\n controls.updateSetting.call(this, type, list);\n },\n\n // Translate a value into a nice label\n getLabel(setting, value) {\n switch (setting) {\n case 'speed':\n return value === 1 ? i18n.get('normal', this.config) : `${value}×`;\n\n case 'quality':\n if (is.number(value)) {\n const label = i18n.get(`qualityLabel.${value}`, this.config);\n\n if (!label.length) {\n return `${value}p`;\n }\n\n return label;\n }\n\n return toTitleCase(value);\n\n case 'captions':\n return captions.getLabel.call(this);\n\n default:\n return null;\n }\n },\n\n // Update the selected setting\n updateSetting(setting, container, input) {\n const pane = this.elements.settings.panels[setting];\n let value = null;\n let list = container;\n\n if (setting === 'captions') {\n value = this.currentTrack;\n } else {\n value = !is.empty(input) ? input : this[setting];\n\n // Get default\n if (is.empty(value)) {\n value = this.config[setting].default;\n }\n\n // Unsupported value\n if (!is.empty(this.options[setting]) && !this.options[setting].includes(value)) {\n this.debug.warn(`Unsupported value of '${value}' for ${setting}`);\n return;\n }\n\n // Disabled value\n if (!this.config[setting].options.includes(value)) {\n this.debug.warn(`Disabled value of '${value}' for ${setting}`);\n return;\n }\n }\n\n // Get the list if we need to\n if (!is.element(list)) {\n list = pane && pane.querySelector('[role=\"menu\"]');\n }\n\n // If there's no list it means it's not been rendered...\n if (!is.element(list)) {\n return;\n }\n\n // Update the label\n const label = this.elements.settings.buttons[setting].querySelector(`.${this.config.classNames.menu.value}`);\n label.innerHTML = controls.getLabel.call(this, setting, value);\n\n // Find the radio option and check it\n const target = list && list.querySelector(`[value=\"${value}\"]`);\n\n if (is.element(target)) {\n target.checked = true;\n }\n },\n\n // Set the looping options\n /* setLoopMenu() {\n // Menu required\n if (!is.element(this.elements.settings.panels.loop)) {\n return;\n }\n\n const options = ['start', 'end', 'all', 'reset'];\n const list = this.elements.settings.panels.loop.querySelector('[role=\"menu\"]');\n\n // Show the pane and tab\n toggleHidden(this.elements.settings.buttons.loop, false);\n toggleHidden(this.elements.settings.panels.loop, false);\n\n // Toggle the pane and tab\n const toggle = !is.empty(this.loop.options);\n controls.toggleMenuButton.call(this, 'loop', toggle);\n\n // Empty the menu\n emptyElement(list);\n\n options.forEach(option => {\n const item = createElement('li');\n\n const button = createElement(\n 'button',\n extend(getAttributesFromSelector(this.config.selectors.buttons.loop), {\n type: 'button',\n class: this.config.classNames.control,\n 'data-plyr-loop-action': option,\n }),\n i18n.get(option, this.config)\n );\n\n if (['start', 'end'].includes(option)) {\n const badge = controls.createBadge.call(this, '00:00');\n button.appendChild(badge);\n }\n\n item.appendChild(button);\n list.appendChild(item);\n });\n }, */\n\n // Get current selected caption language\n // TODO: rework this to user the getter in the API?\n\n // Set a list of available captions languages\n setCaptionsMenu() {\n // TODO: Captions or language? Currently it's mixed\n const type = 'captions';\n const list = this.elements.settings.panels.captions.querySelector('[role=\"menu\"]');\n const tracks = captions.getTracks.call(this);\n\n // Toggle the pane and tab\n controls.toggleMenuButton.call(this, type, tracks.length);\n\n // Empty the menu\n emptyElement(list);\n\n // Check if we need to toggle the parent\n controls.checkMenu.call(this);\n\n // If there's no captions, bail\n if (!tracks.length) {\n return;\n }\n\n // Generate options data\n const options = tracks.map((track, value) => ({\n value,\n checked: this.captions.toggled && this.currentTrack === value,\n title: captions.getLabel.call(this, track),\n badge: track.language && controls.createBadge.call(this, track.language.toUpperCase()),\n list,\n type: 'language',\n }));\n\n // Add the \"Disabled\" option to turn off captions\n options.unshift({\n value: -1,\n checked: !this.captions.toggled,\n title: i18n.get('disabled', this.config),\n list,\n type: 'language',\n });\n\n // Generate options\n options.forEach(controls.createMenuItem.bind(this));\n\n controls.updateSetting.call(this, type, list);\n },\n\n // Set a list of available captions languages\n setSpeedMenu(options) {\n // Do nothing if not selected\n if (!this.config.controls.includes('settings') || !this.config.settings.includes('speed')) {\n return;\n }\n\n // Menu required\n if (!is.element(this.elements.settings.panels.speed)) {\n return;\n }\n\n const type = 'speed';\n\n // Set the speed options\n if (is.array(options)) {\n this.options.speed = options;\n } else if (this.isHTML5 || this.isVimeo) {\n this.options.speed = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];\n }\n\n // Set options if passed and filter based on config\n this.options.speed = this.options.speed.filter(speed => this.config.speed.options.includes(speed));\n\n // Toggle the pane and tab\n const toggle = !is.empty(this.options.speed) && this.options.speed.length > 1;\n controls.toggleMenuButton.call(this, type, toggle);\n\n // Check if we need to toggle the parent\n controls.checkMenu.call(this);\n\n // If we're hiding, nothing more to do\n if (!toggle) {\n return;\n }\n\n // Get the list to populate\n const list = this.elements.settings.panels.speed.querySelector('[role=\"menu\"]');\n\n // Empty the menu\n emptyElement(list);\n\n // Create items\n this.options.speed.forEach(speed => {\n controls.createMenuItem.call(this, {\n value: speed,\n list,\n type,\n title: controls.getLabel.call(this, 'speed', speed),\n });\n });\n\n controls.updateSetting.call(this, type, list);\n },\n\n // Check if we need to hide/show the settings menu\n checkMenu() {\n const { buttons } = this.elements.settings;\n const visible = !is.empty(buttons) && Object.values(buttons).some(button => !button.hidden);\n\n toggleHidden(this.elements.settings.menu, !visible);\n },\n\n // Show/hide menu\n toggleMenu(event) {\n const { popup } = this.elements.settings;\n const button = this.elements.buttons.settings;\n\n // Menu and button are required\n if (!is.element(popup) || !is.element(button)) {\n return;\n }\n\n const show = is.boolean(event) ? event : is.element(popup) && popup.hasAttribute('hidden');\n\n if (is.event(event)) {\n const isMenuItem = is.element(popup) && popup.contains(event.target);\n const isButton = event.target === this.elements.buttons.settings;\n\n // If the click was inside the form or if the click\n // wasn't the button or menu item and we're trying to\n // show the menu (a doc click shouldn't show the menu)\n if (isMenuItem || (!isMenuItem && !isButton && show)) {\n return;\n }\n\n // Prevent the toggle being caught by the doc listener\n if (isButton) {\n event.stopPropagation();\n }\n }\n\n // Set form and button attributes\n if (is.element(button)) {\n button.setAttribute('aria-expanded', show);\n }\n\n if (is.element(popup)) {\n toggleHidden(popup, !show);\n toggleClass(this.elements.container, this.config.classNames.menu.open, show);\n\n if (show) {\n popup.removeAttribute('tabindex');\n } else {\n popup.setAttribute('tabindex', -1);\n }\n }\n },\n\n // Get the natural size of a menu panel\n getMenuSize(tab) {\n const clone = tab.cloneNode(true);\n clone.style.position = 'absolute';\n clone.style.opacity = 0;\n clone.removeAttribute('hidden');\n\n // Append to parent so we get the \"real\" size\n tab.parentNode.appendChild(clone);\n\n // Get the sizes before we remove\n const width = clone.scrollWidth;\n const height = clone.scrollHeight;\n\n // Remove from the DOM\n removeElement(clone);\n\n return {\n width,\n height,\n };\n },\n\n // Show a panel in the menu\n showMenuPanel(type = '') {\n const target = document.getElementById(`plyr-settings-${this.id}-${type}`);\n\n // Nothing to show, bail\n if (!is.element(target)) {\n return;\n }\n\n // Hide all other panels\n const container = target.parentNode;\n const current = Array.from(container.children).find(node => !node.hidden);\n\n // If we can do fancy animations, we'll animate the height/width\n if (support.transitions && !support.reducedMotion) {\n // Set the current width as a base\n container.style.width = `${current.scrollWidth}px`;\n container.style.height = `${current.scrollHeight}px`;\n\n // Get potential sizes\n const size = controls.getMenuSize.call(this, target);\n\n // Restore auto height/width\n const restore = event => {\n // We're only bothered about height and width on the container\n if (event.target !== container || !['width', 'height'].includes(event.propertyName)) {\n return;\n }\n\n // Revert back to auto\n container.style.width = '';\n container.style.height = '';\n\n // Only listen once\n off.call(this, container, transitionEndEvent, restore);\n };\n\n // Listen for the transition finishing and restore auto height/width\n on.call(this, container, transitionEndEvent, restore);\n\n // Set dimensions to target\n container.style.width = `${size.width}px`;\n container.style.height = `${size.height}px`;\n }\n\n // Set attributes on current tab\n toggleHidden(current, true);\n // current.setAttribute('tabindex', -1);\n\n // Set attributes on target\n toggleHidden(target, false);\n\n // Focus the first item\n const firstItem = target.querySelector('[role^=\"menuitem\"]');\n if (firstItem) {\n firstItem.focus();\n }\n },\n\n // Build the default HTML\n // TODO: Set order based on order in the config.controls array?\n create(data) {\n // Do nothing if we want no controls\n if (is.empty(this.config.controls)) {\n return null;\n }\n\n // Create the container\n const container = createElement('div', getAttributesFromSelector(this.config.selectors.controls.wrapper));\n\n // Restart button\n if (this.config.controls.includes('restart')) {\n container.appendChild(controls.createButton.call(this, 'restart'));\n }\n\n // Rewind button\n if (this.config.controls.includes('rewind')) {\n container.appendChild(controls.createButton.call(this, 'rewind'));\n }\n\n // Play/Pause button\n if (this.config.controls.includes('play')) {\n container.appendChild(controls.createButton.call(this, 'play'));\n }\n\n // Fast forward button\n if (this.config.controls.includes('fast-forward')) {\n container.appendChild(controls.createButton.call(this, 'fast-forward'));\n }\n\n // Progress\n if (this.config.controls.includes('progress')) {\n const progress = createElement('div', getAttributesFromSelector(this.config.selectors.progress));\n\n // Seek range slider\n progress.appendChild(\n controls.createRange.call(this, 'seek', {\n id: `plyr-seek-${data.id}`,\n }),\n );\n\n // Buffer progress\n progress.appendChild(controls.createProgress.call(this, 'buffer'));\n\n // TODO: Add loop display indicator\n\n // Seek tooltip\n if (this.config.tooltips.seek) {\n const tooltip = createElement(\n 'span',\n {\n class: this.config.classNames.tooltip,\n },\n '00:00',\n );\n\n progress.appendChild(tooltip);\n this.elements.display.seekTooltip = tooltip;\n }\n\n this.elements.progress = progress;\n container.appendChild(this.elements.progress);\n }\n\n // Media current time display\n if (this.config.controls.includes('current-time')) {\n container.appendChild(controls.createTime.call(this, 'currentTime'));\n }\n\n // Media duration display\n if (this.config.controls.includes('duration')) {\n container.appendChild(controls.createTime.call(this, 'duration'));\n }\n\n // Toggle mute button\n if (this.config.controls.includes('mute')) {\n container.appendChild(controls.createButton.call(this, 'mute'));\n }\n\n // Volume range control\n if (this.config.controls.includes('volume')) {\n const volume = createElement('div', {\n class: 'plyr__volume',\n });\n\n // Set the attributes\n const attributes = {\n max: 1,\n step: 0.05,\n value: this.config.volume,\n };\n\n // Create the volume range slider\n volume.appendChild(\n controls.createRange.call(\n this,\n 'volume',\n extend(attributes, {\n id: `plyr-volume-${data.id}`,\n }),\n ),\n );\n\n this.elements.volume = volume;\n\n container.appendChild(volume);\n }\n\n // Toggle captions button\n if (this.config.controls.includes('captions')) {\n container.appendChild(controls.createButton.call(this, 'captions'));\n }\n\n // Settings button / menu\n if (this.config.controls.includes('settings') && !is.empty(this.config.settings)) {\n const control = createElement('div', {\n class: 'plyr__menu',\n hidden: '',\n });\n\n control.appendChild(\n controls.createButton.call(this, 'settings', {\n id: `plyr-settings-toggle-${data.id}`,\n 'aria-haspopup': true,\n 'aria-controls': `plyr-settings-${data.id}`,\n 'aria-expanded': false,\n }),\n );\n\n const popup = createElement('div', {\n class: 'plyr__menu__container',\n id: `plyr-settings-${data.id}`,\n hidden: '',\n 'aria-labelled-by': `plyr-settings-toggle-${data.id}`,\n });\n\n const inner = createElement('div');\n\n const home = createElement('div', {\n id: `plyr-settings-${data.id}-home`,\n });\n\n // Create the menu\n const menu = createElement('div', {\n role: 'menu',\n });\n\n // Build the menu items\n this.config.settings.forEach(type => {\n const menuItem = createElement(\n 'button',\n extend(getAttributesFromSelector(this.config.selectors.buttons.settings), {\n type: 'button',\n class: `${this.config.classNames.control} ${this.config.classNames.control}--forward`,\n role: 'menuitem',\n 'aria-haspopup': true,\n }),\n );\n\n const flex = createElement('span', null, i18n.get(type, this.config));\n\n const value = createElement('span', {\n class: this.config.classNames.menu.value,\n });\n\n // Speed contains HTML entities\n value.innerHTML = data[type];\n\n flex.appendChild(value);\n menuItem.appendChild(flex);\n menu.appendChild(menuItem);\n\n // Build the panes\n const pane = createElement('div', {\n id: `plyr-settings-${data.id}-${type}`,\n hidden: '',\n });\n\n // Back button\n const back = createElement(\n 'button',\n {\n type: 'button',\n class: `${this.config.classNames.control} ${this.config.classNames.control}--back`,\n },\n i18n.get(type, this.config),\n );\n back.addEventListener('click', () => {\n controls.showMenuPanel.call(this, 'home');\n });\n pane.appendChild(back);\n\n // Menu\n pane.appendChild(\n createElement('div', {\n role: 'menu',\n }),\n );\n\n inner.appendChild(pane);\n\n menuItem.addEventListener('click', () => {\n controls.showMenuPanel.call(this, type);\n });\n\n this.elements.settings.buttons[type] = menuItem;\n this.elements.settings.panels[type] = pane;\n });\n\n home.appendChild(menu);\n inner.appendChild(home);\n\n popup.appendChild(inner);\n control.appendChild(popup);\n container.appendChild(control);\n\n this.elements.settings.popup = popup;\n this.elements.settings.menu = control;\n }\n\n // Picture in picture button\n if (this.config.controls.includes('pip') && support.pip) {\n container.appendChild(controls.createButton.call(this, 'pip'));\n }\n\n // Airplay button\n if (this.config.controls.includes('airplay') && support.airplay) {\n container.appendChild(controls.createButton.call(this, 'airplay'));\n }\n\n // Toggle fullscreen button\n if (this.config.controls.includes('fullscreen')) {\n container.appendChild(controls.createButton.call(this, 'fullscreen'));\n }\n\n // Larger overlaid play button\n if (this.config.controls.includes('play-large')) {\n this.elements.container.appendChild(controls.createButton.call(this, 'play-large'));\n }\n\n this.elements.controls = container;\n\n if (this.isHTML5) {\n controls.setQualityMenu.call(this, html5.getQualityOptions.call(this));\n }\n\n controls.setSpeedMenu.call(this);\n\n return container;\n },\n\n // Insert controls\n inject() {\n // Sprite\n if (this.config.loadSprite) {\n const icon = controls.getIconUrl.call(this);\n\n // Only load external sprite using AJAX\n if (icon.cors) {\n loadSprite(icon.url, 'sprite-plyr');\n }\n }\n\n // Create a unique ID\n this.id = Math.floor(Math.random() * 10000);\n\n // Null by default\n let container = null;\n this.elements.controls = null;\n\n // Set template properties\n const props = {\n id: this.id,\n seektime: this.config.seekTime,\n title: this.config.title,\n };\n let update = true;\n\n if (is.string(this.config.controls) || is.element(this.config.controls)) {\n // String or HTMLElement passed as the option\n container = this.config.controls;\n } else if (is.function(this.config.controls)) {\n // A custom function to build controls\n // The function can return a HTMLElement or String\n container = this.config.controls.call(this, props);\n } else {\n // Create controls\n container = controls.create.call(this, {\n id: this.id,\n seektime: this.config.seekTime,\n speed: this.speed,\n quality: this.quality,\n captions: captions.getLabel.call(this),\n // TODO: Looping\n // loop: 'None',\n });\n update = false;\n }\n\n // Replace props with their value\n const replace = input => {\n let result = input;\n\n Object.entries(props).forEach(([key, value]) => {\n result = replaceAll(result, `{${key}}`, value);\n });\n\n return result;\n };\n\n // Update markup\n if (update) {\n if (is.string(this.config.controls)) {\n container = replace(container);\n } else if (is.element(container)) {\n container.innerHTML = replace(container.innerHTML);\n }\n }\n\n // Controls container\n let target;\n\n // Inject to custom location\n if (is.string(this.config.selectors.controls.container)) {\n target = document.querySelector(this.config.selectors.controls.container);\n }\n\n // Inject into the container by default\n if (!is.element(target)) {\n target = this.elements.container;\n }\n\n // Inject controls HTML\n if (is.element(container)) {\n target.appendChild(container);\n } else if (container) {\n target.insertAdjacentHTML('beforeend', container);\n }\n\n // Find the elements if need be\n if (!is.element(this.elements.controls)) {\n controls.findElements.call(this);\n }\n\n // Edge sometimes doesn't finish the paint so force a redraw\n if (window.navigator.userAgent.includes('Edge')) {\n repaint(target);\n }\n\n // Setup tooltips\n if (this.config.tooltips.controls) {\n const { classNames, selectors } = this.config;\n const selector = `${selectors.controls.wrapper} ${selectors.labels} .${classNames.hidden}`;\n const labels = getElements.call(this, selector);\n\n Array.from(labels).forEach(label => {\n toggleClass(label, this.config.classNames.hidden, false);\n toggleClass(label, this.config.classNames.tooltip, true);\n });\n }\n },\n};\n\nexport default controls;\n","// ==========================================================================\n// URL utils\n// ==========================================================================\n\nimport is from './is';\n\n/**\n * Parse a string to a URL object\n * @param {string} input - the URL to be parsed\n * @param {boolean} safe - failsafe parsing\n */\nexport function parseUrl(input, safe = true) {\n let url = input;\n\n if (safe) {\n const parser = document.createElement('a');\n parser.href = url;\n url = parser.href;\n }\n\n try {\n return new URL(url);\n } catch (e) {\n return null;\n }\n}\n\n// Convert object to URLSearchParams\nexport function buildUrlParams(input) {\n const params = new URLSearchParams();\n\n if (is.object(input)) {\n Object.entries(input).forEach(([key, value]) => {\n params.set(key, value);\n });\n }\n\n return params;\n}\n","// ==========================================================================\n// Plyr Captions\n// TODO: Create as class\n// ==========================================================================\n\nimport controls from './controls';\nimport i18n from './i18n';\nimport support from './support';\nimport { dedupe } from './utils/arrays';\nimport browser from './utils/browser';\nimport {\n createElement,\n emptyElement,\n getAttributesFromSelector,\n insertAfter,\n removeElement,\n toggleClass,\n} from './utils/elements';\nimport { on, triggerEvent } from './utils/events';\nimport fetch from './utils/fetch';\nimport is from './utils/is';\nimport { getHTML } from './utils/strings';\nimport { parseUrl } from './utils/urls';\n\nconst captions = {\n // Setup captions\n setup() {\n // Requires UI support\n if (!this.supported.ui) {\n return;\n }\n\n // Only Vimeo and HTML5 video supported at this point\n if (!this.isVideo || this.isYouTube || (this.isHTML5 && !support.textTracks)) {\n // Clear menu and hide\n if (\n is.array(this.config.controls) &&\n this.config.controls.includes('settings') &&\n this.config.settings.includes('captions')\n ) {\n controls.setCaptionsMenu.call(this);\n }\n\n return;\n }\n\n // Inject the container\n if (!is.element(this.elements.captions)) {\n this.elements.captions = createElement('div', getAttributesFromSelector(this.config.selectors.captions));\n\n insertAfter(this.elements.captions, this.elements.wrapper);\n }\n\n // Fix IE captions if CORS is used\n // Fetch captions and inject as blobs instead (data URIs not supported!)\n if (browser.isIE && window.URL) {\n const elements = this.media.querySelectorAll('track');\n\n Array.from(elements).forEach(track => {\n const src = track.getAttribute('src');\n const url = parseUrl(src);\n\n if (\n url !== null &&\n url.hostname !== window.location.href.hostname &&\n ['http:', 'https:'].includes(url.protocol)\n ) {\n fetch(src, 'blob')\n .then(blob => {\n track.setAttribute('src', window.URL.createObjectURL(blob));\n })\n .catch(() => {\n removeElement(track);\n });\n }\n });\n }\n\n // Get and set initial data\n // The \"preferred\" options are not realized unless / until the wanted language has a match\n // * languages: Array of user's browser languages.\n // * language: The language preferred by user settings or config\n // * active: The state preferred by user settings or config\n // * toggled: The real captions state\n\n const languages = dedupe(\n Array.from(navigator.languages || navigator.userLanguage).map(language => language.split('-')[0]),\n );\n\n let language = (this.storage.get('language') || this.config.captions.language || 'auto').toLowerCase();\n\n // Use first browser language when language is 'auto'\n if (language === 'auto') {\n [language] = languages;\n }\n\n let active = this.storage.get('captions');\n if (!is.boolean(active)) {\n ({ active } = this.config.captions);\n }\n\n Object.assign(this.captions, {\n toggled: false,\n active,\n language,\n languages,\n });\n\n // Watch changes to textTracks and update captions menu\n if (this.isHTML5) {\n const trackEvents = this.config.captions.update ? 'addtrack removetrack' : 'removetrack';\n on.call(this, this.media.textTracks, trackEvents, captions.update.bind(this));\n }\n\n // Update available languages in list next tick (the event must not be triggered before the listeners)\n setTimeout(captions.update.bind(this), 0);\n },\n\n // Update available language options in settings based on tracks\n update() {\n const tracks = captions.getTracks.call(this, true);\n // Get the wanted language\n const { active, language, meta, currentTrackNode } = this.captions;\n const languageExists = Boolean(tracks.find(track => track.language === language));\n\n // Handle tracks (add event listener and \"pseudo\"-default)\n if (this.isHTML5 && this.isVideo) {\n tracks.filter(track => !meta.get(track)).forEach(track => {\n this.debug.log('Track added', track);\n // Attempt to store if the original dom element was \"default\"\n meta.set(track, {\n default: track.mode === 'showing',\n });\n\n // Turn off native caption rendering to avoid double captions\n track.mode = 'hidden';\n\n // Add event listener for cue changes\n on.call(this, track, 'cuechange', () => captions.updateCues.call(this));\n });\n }\n\n // Update language first time it matches, or if the previous matching track was removed\n if ((languageExists && this.language !== language) || !tracks.includes(currentTrackNode)) {\n captions.setLanguage.call(this, language);\n captions.toggle.call(this, active && languageExists);\n }\n\n // Enable or disable captions based on track length\n toggleClass(this.elements.container, this.config.classNames.captions.enabled, !is.empty(tracks));\n\n // Update available languages in list\n if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) {\n controls.setCaptionsMenu.call(this);\n }\n },\n\n // Toggle captions display\n // Used internally for the toggleCaptions method, with the passive option forced to false\n toggle(input, passive = true) {\n // If there's no full support\n if (!this.supported.ui) {\n return;\n }\n\n const { toggled } = this.captions; // Current state\n const activeClass = this.config.classNames.captions.active;\n\n // Get the next state\n // If the method is called without parameter, toggle based on current value\n const active = is.nullOrUndefined(input) ? !toggled : input;\n\n // Update state and trigger event\n if (active !== toggled) {\n // When passive, don't override user preferences\n if (!passive) {\n this.captions.active = active;\n this.storage.set({ captions: active });\n }\n\n // Force language if the call isn't passive and there is no matching language to toggle to\n if (!this.language && active && !passive) {\n const tracks = captions.getTracks.call(this);\n const track = captions.findTrack.call(this, [this.captions.language, ...this.captions.languages], true);\n\n // Override user preferences to avoid switching languages if a matching track is added\n this.captions.language = track.language;\n\n // Set caption, but don't store in localStorage as user preference\n captions.set.call(this, tracks.indexOf(track));\n return;\n }\n\n // Toggle state\n this.elements.buttons.captions.pressed = active;\n\n // Add class hook\n toggleClass(this.elements.container, activeClass, active);\n\n this.captions.toggled = active;\n\n // Update settings menu\n controls.updateSetting.call(this, 'captions');\n\n // Trigger event (not used internally)\n triggerEvent.call(this, this.media, active ? 'captionsenabled' : 'captionsdisabled');\n }\n },\n\n // Set captions by track index\n // Used internally for the currentTrack setter with the passive option forced to false\n set(index, passive = true) {\n const tracks = captions.getTracks.call(this);\n\n // Disable captions if setting to -1\n if (index === -1) {\n captions.toggle.call(this, false, passive);\n return;\n }\n\n if (!is.number(index)) {\n this.debug.warn('Invalid caption argument', index);\n return;\n }\n\n if (!(index in tracks)) {\n this.debug.warn('Track not found', index);\n return;\n }\n\n if (this.captions.currentTrack !== index) {\n this.captions.currentTrack = index;\n const track = tracks[index];\n const { language } = track || {};\n\n // Store reference to node for invalidation on remove\n this.captions.currentTrackNode = track;\n\n // Update settings menu\n controls.updateSetting.call(this, 'captions');\n\n // When passive, don't override user preferences\n if (!passive) {\n this.captions.language = language;\n this.storage.set({ language });\n }\n\n // Handle Vimeo captions\n if (this.isVimeo) {\n this.embed.enableTextTrack(language);\n }\n\n // Trigger event\n triggerEvent.call(this, this.media, 'languagechange');\n }\n\n // Show captions\n captions.toggle.call(this, true, passive);\n\n if (this.isHTML5 && this.isVideo) {\n // If we change the active track while a cue is already displayed we need to update it\n captions.updateCues.call(this);\n }\n },\n\n // Set captions by language\n // Used internally for the language setter with the passive option forced to false\n setLanguage(input, passive = true) {\n if (!is.string(input)) {\n this.debug.warn('Invalid language argument', input);\n return;\n }\n // Normalize\n const language = input.toLowerCase();\n this.captions.language = language;\n\n // Set currentTrack\n const tracks = captions.getTracks.call(this);\n const track = captions.findTrack.call(this, [language]);\n captions.set.call(this, tracks.indexOf(track), passive);\n },\n\n // Get current valid caption tracks\n // If update is false it will also ignore tracks without metadata\n // This is used to \"freeze\" the language options when captions.update is false\n getTracks(update = false) {\n // Handle media or textTracks missing or null\n const tracks = Array.from((this.media || {}).textTracks || []);\n // For HTML5, use cache instead of current tracks when it exists (if captions.update is false)\n // Filter out removed tracks and tracks that aren't captions/subtitles (for example metadata)\n return tracks\n .filter(track => !this.isHTML5 || update || this.captions.meta.has(track))\n .filter(track => ['captions', 'subtitles'].includes(track.kind));\n },\n\n // Match tracks based on languages and get the first\n findTrack(languages, force = false) {\n const tracks = captions.getTracks.call(this);\n const sortIsDefault = track => Number((this.captions.meta.get(track) || {}).default);\n const sorted = Array.from(tracks).sort((a, b) => sortIsDefault(b) - sortIsDefault(a));\n let track;\n languages.every(language => {\n track = sorted.find(track => track.language === language);\n return !track; // Break iteration if there is a match\n });\n // If no match is found but is required, get first\n return track || (force ? sorted[0] : undefined);\n },\n\n // Get the current track\n getCurrentTrack() {\n return captions.getTracks.call(this)[this.currentTrack];\n },\n\n // Get UI label for track\n getLabel(track) {\n let currentTrack = track;\n\n if (!is.track(currentTrack) && support.textTracks && this.captions.toggled) {\n currentTrack = captions.getCurrentTrack.call(this);\n }\n\n if (is.track(currentTrack)) {\n if (!is.empty(currentTrack.label)) {\n return currentTrack.label;\n }\n\n if (!is.empty(currentTrack.language)) {\n return track.language.toUpperCase();\n }\n\n return i18n.get('enabled', this.config);\n }\n\n return i18n.get('disabled', this.config);\n },\n\n // Update captions using current track's active cues\n // Also optional array argument in case there isn't any track (ex: vimeo)\n updateCues(input) {\n // Requires UI\n if (!this.supported.ui) {\n return;\n }\n\n if (!is.element(this.elements.captions)) {\n this.debug.warn('No captions element to render to');\n return;\n }\n\n // Only accept array or empty input\n if (!is.nullOrUndefined(input) && !Array.isArray(input)) {\n this.debug.warn('updateCues: Invalid input', input);\n return;\n }\n\n let cues = input;\n\n // Get cues from track\n if (!cues) {\n const track = captions.getCurrentTrack.call(this);\n cues = Array.from((track || {}).activeCues || [])\n .map(cue => cue.getCueAsHTML())\n .map(getHTML);\n }\n\n // Set new caption text\n const content = cues.map(cueText => cueText.trim()).join('\\n');\n const changed = content !== this.elements.captions.innerHTML;\n\n if (changed) {\n // Empty the container and create a new child element\n emptyElement(this.elements.captions);\n const caption = createElement('span', getAttributesFromSelector(this.config.selectors.caption));\n caption.innerHTML = content;\n this.elements.captions.appendChild(caption);\n\n // Trigger event\n triggerEvent.call(this, this.media, 'cuechange');\n }\n },\n};\n\nexport default captions;\n","// ==========================================================================\n// Plyr default config\n// ==========================================================================\n\nconst defaults = {\n // Disable\n enabled: true,\n\n // Custom media title\n title: '',\n\n // Logging to console\n debug: false,\n\n // Auto play (if supported)\n autoplay: false,\n\n // Only allow one media playing at once (vimeo only)\n autopause: true,\n\n // Allow inline playback on iOS (this effects YouTube/Vimeo - HTML5 requires the attribute present)\n // TODO: Remove iosNative fullscreen option in favour of this (logic needs work)\n playsinline: true,\n\n // Default time to skip when rewind/fast forward\n seekTime: 10,\n\n // Default volume\n volume: 1,\n muted: false,\n\n // Pass a custom duration\n duration: null,\n\n // Display the media duration on load in the current time position\n // If you have opted to display both duration and currentTime, this is ignored\n displayDuration: true,\n\n // Invert the current time to be a countdown\n invertTime: true,\n\n // Clicking the currentTime inverts it's value to show time left rather than elapsed\n toggleInvert: true,\n\n // Aspect ratio (for embeds)\n ratio: '16:9',\n\n // Click video container to play/pause\n clickToPlay: true,\n\n // Auto hide the controls\n hideControls: true,\n\n // Reset to start when playback ended\n resetOnEnd: false,\n\n // Disable the standard context menu\n disableContextMenu: true,\n\n // Sprite (for icons)\n loadSprite: true,\n iconPrefix: 'plyr',\n iconUrl: 'https://cdn.plyr.io/3.3.12/plyr.svg',\n\n // Blank video (used to prevent errors on source change)\n blankVideo: 'https://cdn.plyr.io/static/blank.mp4',\n\n // Quality default\n quality: {\n default: 576,\n options: [\n 4320,\n 2880,\n 2160,\n 1440,\n 1080,\n 720,\n 576,\n 480,\n 360,\n 240,\n 'default', // YouTube's \"auto\"\n ],\n },\n\n // Set loops\n loop: {\n active: false,\n // start: null,\n // end: null,\n },\n\n // Speed default and options to display\n speed: {\n selected: 1,\n options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],\n },\n\n // Keyboard shortcut settings\n keyboard: {\n focused: true,\n global: false,\n },\n\n // Display tooltips\n tooltips: {\n controls: false,\n seek: true,\n },\n\n // Captions settings\n captions: {\n active: false,\n language: 'auto',\n // Listen to new tracks added after Plyr is initialized.\n // This is needed for streaming captions, but may result in unselectable options\n update: false,\n },\n\n // Fullscreen settings\n fullscreen: {\n enabled: true, // Allow fullscreen?\n fallback: true, // Fallback for vintage browsers\n iosNative: false, // Use the native fullscreen in iOS (disables custom controls)\n },\n\n // Local storage\n storage: {\n enabled: true,\n key: 'plyr',\n },\n\n // Default controls\n controls: [\n 'play-large',\n // 'restart',\n // 'rewind',\n 'play',\n // 'fast-forward',\n 'progress',\n 'current-time',\n 'mute',\n 'volume',\n 'captions',\n 'settings',\n 'pip',\n 'airplay',\n 'fullscreen',\n ],\n settings: ['captions', 'quality', 'speed'],\n\n // Localisation\n i18n: {\n restart: 'Restart',\n rewind: 'Rewind {seektime}s',\n play: 'Play',\n pause: 'Pause',\n fastForward: 'Forward {seektime}s',\n seek: 'Seek',\n seekLabel: '{currentTime} of {duration}',\n played: 'Played',\n buffered: 'Buffered',\n currentTime: 'Current time',\n duration: 'Duration',\n volume: 'Volume',\n mute: 'Mute',\n unmute: 'Unmute',\n enableCaptions: 'Enable captions',\n disableCaptions: 'Disable captions',\n enterFullscreen: 'Enter fullscreen',\n exitFullscreen: 'Exit fullscreen',\n frameTitle: 'Player for {title}',\n captions: 'Captions',\n settings: 'Settings',\n menuBack: 'Go back to previous menu',\n speed: 'Speed',\n normal: 'Normal',\n quality: 'Quality',\n loop: 'Loop',\n start: 'Start',\n end: 'End',\n all: 'All',\n reset: 'Reset',\n disabled: 'Disabled',\n enabled: 'Enabled',\n advertisement: 'Ad',\n qualityBadge: {\n 2160: '4K',\n 1440: 'HD',\n 1080: 'HD',\n 720: 'HD',\n 576: 'SD',\n 480: 'SD',\n },\n },\n\n // URLs\n urls: {\n vimeo: {\n sdk: 'https://player.vimeo.com/api/player.js',\n iframe: 'https://player.vimeo.com/video/{0}?{1}',\n api: 'https://vimeo.com/api/v2/video/{0}.json',\n },\n youtube: {\n sdk: 'https://www.youtube.com/iframe_api',\n api:\n 'https://www.googleapis.com/youtube/v3/videos?id={0}&key={1}&fields=items(snippet(title))&part=snippet',\n },\n googleIMA: {\n sdk: 'https://imasdk.googleapis.com/js/sdkloader/ima3.js',\n },\n },\n\n // Custom control listeners\n listeners: {\n seek: null,\n play: null,\n pause: null,\n restart: null,\n rewind: null,\n fastForward: null,\n mute: null,\n volume: null,\n captions: null,\n fullscreen: null,\n pip: null,\n airplay: null,\n speed: null,\n quality: null,\n loop: null,\n language: null,\n },\n\n // Events to watch and bubble\n events: [\n // Events to watch on HTML5 media elements and bubble\n // https://developer.mozilla.org/en/docs/Web/Guide/Events/Media_events\n 'ended',\n 'progress',\n 'stalled',\n 'playing',\n 'waiting',\n 'canplay',\n 'canplaythrough',\n 'loadstart',\n 'loadeddata',\n 'loadedmetadata',\n 'timeupdate',\n 'volumechange',\n 'play',\n 'pause',\n 'error',\n 'seeking',\n 'seeked',\n 'emptied',\n 'ratechange',\n 'cuechange',\n\n // Custom events\n 'enterfullscreen',\n 'exitfullscreen',\n 'captionsenabled',\n 'captionsdisabled',\n 'languagechange',\n 'controlshidden',\n 'controlsshown',\n 'ready',\n\n // YouTube\n 'statechange',\n 'qualitychange',\n 'qualityrequested',\n\n // Ads\n 'adsloaded',\n 'adscontentpause',\n 'adscontentresume',\n 'adstarted',\n 'adsmidpoint',\n 'adscomplete',\n 'adsallcomplete',\n 'adsimpression',\n 'adsclick',\n ],\n\n // Selectors\n // Change these to match your template if using custom HTML\n selectors: {\n editable: 'input, textarea, select, [contenteditable]',\n container: '.plyr',\n controls: {\n container: null,\n wrapper: '.plyr__controls',\n },\n labels: '[data-plyr]',\n buttons: {\n play: '[data-plyr=\"play\"]',\n pause: '[data-plyr=\"pause\"]',\n restart: '[data-plyr=\"restart\"]',\n rewind: '[data-plyr=\"rewind\"]',\n fastForward: '[data-plyr=\"fast-forward\"]',\n mute: '[data-plyr=\"mute\"]',\n captions: '[data-plyr=\"captions\"]',\n fullscreen: '[data-plyr=\"fullscreen\"]',\n pip: '[data-plyr=\"pip\"]',\n airplay: '[data-plyr=\"airplay\"]',\n settings: '[data-plyr=\"settings\"]',\n loop: '[data-plyr=\"loop\"]',\n },\n inputs: {\n seek: '[data-plyr=\"seek\"]',\n volume: '[data-plyr=\"volume\"]',\n speed: '[data-plyr=\"speed\"]',\n language: '[data-plyr=\"language\"]',\n quality: '[data-plyr=\"quality\"]',\n },\n display: {\n currentTime: '.plyr__time--current',\n duration: '.plyr__time--duration',\n buffer: '.plyr__progress__buffer',\n loop: '.plyr__progress__loop', // Used later\n volume: '.plyr__volume--display',\n },\n progress: '.plyr__progress',\n captions: '.plyr__captions',\n caption: '.plyr__caption',\n menu: {\n quality: '.js-plyr__menu__list--quality',\n },\n },\n\n // Class hooks added to the player in different states\n classNames: {\n type: 'plyr--{0}',\n provider: 'plyr--{0}',\n video: 'plyr__video-wrapper',\n embed: 'plyr__video-embed',\n embedContainer: 'plyr__video-embed__container',\n poster: 'plyr__poster',\n posterEnabled: 'plyr__poster-enabled',\n ads: 'plyr__ads',\n control: 'plyr__control',\n controlPressed: 'plyr__control--pressed',\n playing: 'plyr--playing',\n paused: 'plyr--paused',\n stopped: 'plyr--stopped',\n loading: 'plyr--loading',\n hover: 'plyr--hover',\n tooltip: 'plyr__tooltip',\n cues: 'plyr__cues',\n hidden: 'plyr__sr-only',\n hideControls: 'plyr--hide-controls',\n isIos: 'plyr--is-ios',\n isTouch: 'plyr--is-touch',\n uiSupported: 'plyr--full-ui',\n noTransition: 'plyr--no-transition',\n display: {\n time: 'plyr__time',\n },\n menu: {\n value: 'plyr__menu__value',\n badge: 'plyr__badge',\n open: 'plyr--menu-open',\n },\n captions: {\n enabled: 'plyr--captions-enabled',\n active: 'plyr--captions-active',\n },\n fullscreen: {\n enabled: 'plyr--fullscreen-enabled',\n fallback: 'plyr--fullscreen-fallback',\n },\n pip: {\n supported: 'plyr--pip-supported',\n active: 'plyr--pip-active',\n },\n airplay: {\n supported: 'plyr--airplay-supported',\n active: 'plyr--airplay-active',\n },\n tabFocus: 'plyr__tab-focus',\n },\n\n // Embed attributes\n attributes: {\n embed: {\n provider: 'data-plyr-provider',\n id: 'data-plyr-embed-id',\n },\n },\n\n // API keys\n keys: {\n google: null,\n },\n\n // Advertisements plugin\n // Register for an account here: http://vi.ai/publisher-video-monetization/?aid=plyrio\n ads: {\n enabled: false,\n publisherId: '',\n },\n};\n\nexport default defaults;\n","// ==========================================================================\n// Plyr supported types and providers\n// ==========================================================================\n\nexport const providers = {\n html5: 'html5',\n youtube: 'youtube',\n vimeo: 'vimeo',\n};\n\nexport const types = {\n audio: 'audio',\n video: 'video',\n};\n\n/**\n * Get provider by URL\n * @param {string} url\n */\nexport function getProviderByUrl(url) {\n // YouTube\n if (/^(https?:\\/\\/)?(www\\.)?(youtube\\.com|youtu\\.?be)\\/.+$/.test(url)) {\n return providers.youtube;\n }\n\n // Vimeo\n if (/^https?:\\/\\/player.vimeo.com\\/video\\/\\d{0,9}(?=\\b|\\/)/.test(url)) {\n return providers.vimeo;\n }\n\n return null;\n}\n\nexport default { providers, types };\n","// ==========================================================================\n// Console wrapper\n// ==========================================================================\n\nconst noop = () => {};\n\nexport default class Console {\n constructor(enabled = false) {\n this.enabled = window.console && enabled;\n\n if (this.enabled) {\n this.log('Debugging enabled');\n }\n }\n\n get log() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.log, console) : noop;\n }\n get warn() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.warn, console) : noop;\n }\n get error() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.error, console) : noop;\n }\n}\n","// ==========================================================================\n// Fullscreen wrapper\n// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API#prefixing\n// ==========================================================================\n\nimport browser from './utils/browser';\nimport { hasClass, toggleClass, trapFocus } from './utils/elements';\nimport { on, triggerEvent } from './utils/events';\nimport is from './utils/is';\n\nfunction onChange() {\n if (!this.enabled) {\n return;\n }\n\n // Update toggle button\n const button = this.player.elements.buttons.fullscreen;\n if (is.element(button)) {\n button.pressed = this.active;\n }\n\n // Trigger an event\n triggerEvent.call(this.player, this.target, this.active ? 'enterfullscreen' : 'exitfullscreen', true);\n\n // Trap focus in container\n if (!browser.isIos) {\n trapFocus.call(this.player, this.target, this.active);\n }\n}\n\nfunction toggleFallback(toggle = false) {\n // Store or restore scroll position\n if (toggle) {\n this.scrollPosition = {\n x: window.scrollX || 0,\n y: window.scrollY || 0,\n };\n } else {\n window.scrollTo(this.scrollPosition.x, this.scrollPosition.y);\n }\n\n // Toggle scroll\n document.body.style.overflow = toggle ? 'hidden' : '';\n\n // Toggle class hook\n toggleClass(this.target, this.player.config.classNames.fullscreen.fallback, toggle);\n\n // Toggle button and fire events\n onChange.call(this);\n}\n\nclass Fullscreen {\n constructor(player) {\n // Keep reference to parent\n this.player = player;\n\n // Get prefix\n this.prefix = Fullscreen.prefix;\n this.property = Fullscreen.property;\n\n // Scroll position\n this.scrollPosition = { x: 0, y: 0 };\n\n // Register event listeners\n // Handle event (incase user presses escape etc)\n on.call(\n this.player,\n document,\n this.prefix === 'ms' ? 'MSFullscreenChange' : `${this.prefix}fullscreenchange`,\n () => {\n // TODO: Filter for target??\n onChange.call(this);\n },\n );\n\n // Fullscreen toggle on double click\n on.call(this.player, this.player.elements.container, 'dblclick', event => {\n // Ignore double click in controls\n if (is.element(this.player.elements.controls) && this.player.elements.controls.contains(event.target)) {\n return;\n }\n\n this.toggle();\n });\n\n // Update the UI\n this.update();\n }\n\n // Determine if native supported\n static get native() {\n return !!(\n document.fullscreenEnabled ||\n document.webkitFullscreenEnabled ||\n document.mozFullScreenEnabled ||\n document.msFullscreenEnabled\n );\n }\n\n // Get the prefix for handlers\n static get prefix() {\n // No prefix\n if (is.function(document.exitFullscreen)) {\n return '';\n }\n\n // Check for fullscreen support by vendor prefix\n let value = '';\n const prefixes = ['webkit', 'moz', 'ms'];\n\n prefixes.some(pre => {\n if (is.function(document[`${pre}ExitFullscreen`]) || is.function(document[`${pre}CancelFullScreen`])) {\n value = pre;\n return true;\n }\n\n return false;\n });\n\n return value;\n }\n\n static get property() {\n return this.prefix === 'moz' ? 'FullScreen' : 'Fullscreen';\n }\n\n // Determine if fullscreen is enabled\n get enabled() {\n return (\n (Fullscreen.native || this.player.config.fullscreen.fallback) &&\n this.player.config.fullscreen.enabled &&\n this.player.supported.ui &&\n this.player.isVideo\n );\n }\n\n // Get active state\n get active() {\n if (!this.enabled) {\n return false;\n }\n\n // Fallback using classname\n if (!Fullscreen.native) {\n return hasClass(this.target, this.player.config.classNames.fullscreen.fallback);\n }\n\n const element = !this.prefix ? document.fullscreenElement : document[`${this.prefix}${this.property}Element`];\n\n return element === this.target;\n }\n\n // Get target element\n get target() {\n return browser.isIos && this.player.config.fullscreen.iosNative\n ? this.player.media\n : this.player.elements.container;\n }\n\n // Update UI\n update() {\n if (this.enabled) {\n this.player.debug.log(`${Fullscreen.native ? 'Native' : 'Fallback'} fullscreen enabled`);\n } else {\n this.player.debug.log('Fullscreen not supported and fallback disabled');\n }\n\n // Add styling hook to show button\n toggleClass(this.player.elements.container, this.player.config.classNames.fullscreen.enabled, this.enabled);\n }\n\n // Make an element fullscreen\n enter() {\n if (!this.enabled) {\n return;\n }\n\n // iOS native fullscreen doesn't need the request step\n if (browser.isIos && this.player.config.fullscreen.iosNative) {\n if (this.player.playing) {\n this.target.webkitEnterFullscreen();\n }\n } else if (!Fullscreen.native) {\n toggleFallback.call(this, true);\n } else if (!this.prefix) {\n this.target.requestFullscreen();\n } else if (!is.empty(this.prefix)) {\n this.target[`${this.prefix}Request${this.property}`]();\n }\n }\n\n // Bail from fullscreen\n exit() {\n if (!this.enabled) {\n return;\n }\n\n // iOS native fullscreen\n if (browser.isIos && this.player.config.fullscreen.iosNative) {\n this.target.webkitExitFullscreen();\n this.player.play();\n } else if (!Fullscreen.native) {\n toggleFallback.call(this, false);\n } else if (!this.prefix) {\n (document.cancelFullScreen || document.exitFullscreen).call(document);\n } else if (!is.empty(this.prefix)) {\n const action = this.prefix === 'moz' ? 'Cancel' : 'Exit';\n document[`${this.prefix}${action}${this.property}`]();\n }\n }\n\n // Toggle state\n toggle() {\n if (!this.active) {\n this.enter();\n } else {\n this.exit();\n }\n }\n}\n\nexport default Fullscreen;\n","// ==========================================================================\n// Load image avoiding xhr/fetch CORS issues\n// Server status can't be obtained this way unfortunately, so this uses \"naturalWidth\" to determine if the image has loaded\n// By default it checks if it is at least 1px, but you can add a second argument to change this\n// ==========================================================================\n\nexport default function loadImage(src, minWidth = 1) {\n return new Promise((resolve, reject) => {\n const image = new Image();\n\n const handler = () => {\n delete image.onload;\n delete image.onerror;\n (image.naturalWidth >= minWidth ? resolve : reject)(image);\n };\n\n Object.assign(image, { onload: handler, onerror: handler, src });\n });\n}\n","// ==========================================================================\n// Plyr UI\n// ==========================================================================\n\nimport captions from './captions';\nimport controls from './controls';\nimport i18n from './i18n';\nimport support from './support';\nimport browser from './utils/browser';\nimport { getElement, toggleClass } from './utils/elements';\nimport { ready, triggerEvent } from './utils/events';\nimport is from './utils/is';\nimport loadImage from './utils/loadImage';\n\nconst ui = {\n addStyleHook() {\n toggleClass(this.elements.container, this.config.selectors.container.replace('.', ''), true);\n toggleClass(this.elements.container, this.config.classNames.uiSupported, this.supported.ui);\n },\n\n // Toggle native HTML5 media controls\n toggleNativeControls(toggle = false) {\n if (toggle && this.isHTML5) {\n this.media.setAttribute('controls', '');\n } else {\n this.media.removeAttribute('controls');\n }\n },\n\n // Setup the UI\n build() {\n // Re-attach media element listeners\n // TODO: Use event bubbling?\n this.listeners.media();\n\n // Don't setup interface if no support\n if (!this.supported.ui) {\n this.debug.warn(`Basic support only for ${this.provider} ${this.type}`);\n\n // Restore native controls\n ui.toggleNativeControls.call(this, true);\n\n // Bail\n return;\n }\n\n // Inject custom controls if not present\n if (!is.element(this.elements.controls)) {\n // Inject custom controls\n controls.inject.call(this);\n\n // Re-attach control listeners\n this.listeners.controls();\n }\n\n // Remove native controls\n ui.toggleNativeControls.call(this);\n\n // Setup captions for HTML5\n if (this.isHTML5) {\n captions.setup.call(this);\n }\n\n // Reset volume\n this.volume = null;\n\n // Reset mute state\n this.muted = null;\n\n // Reset speed\n this.speed = null;\n\n // Reset loop state\n this.loop = null;\n\n // Reset quality setting\n this.quality = null;\n\n // Reset volume display\n controls.updateVolume.call(this);\n\n // Reset time display\n controls.timeUpdate.call(this);\n\n // Update the UI\n ui.checkPlaying.call(this);\n\n // Check for picture-in-picture support\n toggleClass(\n this.elements.container,\n this.config.classNames.pip.supported,\n support.pip && this.isHTML5 && this.isVideo,\n );\n\n // Check for airplay support\n toggleClass(this.elements.container, this.config.classNames.airplay.supported, support.airplay && this.isHTML5);\n\n // Add iOS class\n toggleClass(this.elements.container, this.config.classNames.isIos, browser.isIos);\n\n // Add touch class\n toggleClass(this.elements.container, this.config.classNames.isTouch, this.touch);\n\n // Ready for API calls\n this.ready = true;\n\n // Ready event at end of execution stack\n setTimeout(() => {\n triggerEvent.call(this, this.media, 'ready');\n }, 0);\n\n // Set the title\n ui.setTitle.call(this);\n\n // Assure the poster image is set, if the property was added before the element was created\n if (this.poster) {\n ui.setPoster.call(this, this.poster, false).catch(() => {});\n }\n\n // Manually set the duration if user has overridden it.\n // The event listeners for it doesn't get called if preload is disabled (#701)\n if (this.config.duration) {\n controls.durationUpdate.call(this);\n }\n },\n\n // Setup aria attribute for play and iframe title\n setTitle() {\n // Find the current text\n let label = i18n.get('play', this.config);\n\n // If there's a media title set, use that for the label\n if (is.string(this.config.title) && !is.empty(this.config.title)) {\n label += `, ${this.config.title}`;\n }\n\n // If there's a play button, set label\n Array.from(this.elements.buttons.play || []).forEach(button => {\n button.setAttribute('aria-label', label);\n });\n\n // Set iframe title\n // https://github.com/sampotts/plyr/issues/124\n if (this.isEmbed) {\n const iframe = getElement.call(this, 'iframe');\n\n if (!is.element(iframe)) {\n return;\n }\n\n // Default to media type\n const title = !is.empty(this.config.title) ? this.config.title : 'video';\n const format = i18n.get('frameTitle', this.config);\n\n iframe.setAttribute('title', format.replace('{title}', title));\n }\n },\n\n // Toggle poster\n togglePoster(enable) {\n toggleClass(this.elements.container, this.config.classNames.posterEnabled, enable);\n },\n\n // Set the poster image (async)\n // Used internally for the poster setter, with the passive option forced to false\n setPoster(poster, passive = true) {\n // Don't override if call is passive\n if (passive && this.poster) {\n return Promise.reject(new Error('Poster already set'));\n }\n\n // Set property synchronously to respect the call order\n this.media.setAttribute('poster', poster);\n\n // Wait until ui is ready\n return (\n ready\n .call(this)\n // Load image\n .then(() => loadImage(poster))\n .catch(err => {\n // Hide poster on error unless it's been set by another call\n if (poster === this.poster) {\n ui.togglePoster.call(this, false);\n }\n // Rethrow\n throw err;\n })\n .then(() => {\n // Prevent race conditions\n if (poster !== this.poster) {\n throw new Error('setPoster cancelled by later call to setPoster');\n }\n })\n .then(() => {\n Object.assign(this.elements.poster.style, {\n backgroundImage: `url('${poster}')`,\n // Reset backgroundSize as well (since it can be set to \"cover\" for padded thumbnails for youtube)\n backgroundSize: '',\n });\n ui.togglePoster.call(this, true);\n return poster;\n })\n );\n },\n\n // Check playing state\n checkPlaying(event) {\n // Class hooks\n toggleClass(this.elements.container, this.config.classNames.playing, this.playing);\n toggleClass(this.elements.container, this.config.classNames.paused, this.paused);\n toggleClass(this.elements.container, this.config.classNames.stopped, this.stopped);\n\n // Set state\n Array.from(this.elements.buttons.play || []).forEach(target => {\n target.pressed = this.playing;\n });\n\n // Only update controls on non timeupdate events\n if (is.event(event) && event.type === 'timeupdate') {\n return;\n }\n\n // Toggle controls\n ui.toggleControls.call(this);\n },\n\n // Check if media is loading\n checkLoading(event) {\n this.loading = ['stalled', 'waiting'].includes(event.type);\n\n // Clear timer\n clearTimeout(this.timers.loading);\n\n // Timer to prevent flicker when seeking\n this.timers.loading = setTimeout(() => {\n // Update progress bar loading class state\n toggleClass(this.elements.container, this.config.classNames.loading, this.loading);\n\n // Update controls visibility\n ui.toggleControls.call(this);\n }, this.loading ? 250 : 0);\n },\n\n // Toggle controls based on state and `force` argument\n toggleControls(force) {\n const { controls } = this.elements;\n\n if (controls && this.config.hideControls) {\n // Show controls if force, loading, paused, or button interaction, otherwise hide\n this.toggleControls(Boolean(force || this.loading || this.paused || controls.pressed || controls.hover));\n }\n },\n};\n\nexport default ui;\n","// ==========================================================================\n// Plyr Event Listeners\n// ==========================================================================\n\nimport controls from './controls';\nimport ui from './ui';\nimport browser from './utils/browser';\nimport { getElement, getElements, getFocusElement, matches, toggleClass, toggleHidden } from './utils/elements';\nimport { on, once, toggleListener, triggerEvent } from './utils/events';\nimport is from './utils/is';\n\nclass Listeners {\n constructor(player) {\n this.player = player;\n this.lastKey = null;\n\n this.handleKey = this.handleKey.bind(this);\n this.toggleMenu = this.toggleMenu.bind(this);\n this.firstTouch = this.firstTouch.bind(this);\n }\n\n // Handle key presses\n handleKey(event) {\n const code = event.keyCode ? event.keyCode : event.which;\n const pressed = event.type === 'keydown';\n const repeat = pressed && code === this.lastKey;\n\n // Bail if a modifier key is set\n if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {\n return;\n }\n\n // If the event is bubbled from the media element\n // Firefox doesn't get the keycode for whatever reason\n if (!is.number(code)) {\n return;\n }\n\n // Seek by the number keys\n const seekByKey = () => {\n // Divide the max duration into 10th's and times by the number value\n this.player.currentTime = this.player.duration / 10 * (code - 48);\n };\n\n // Handle the key on keydown\n // Reset on keyup\n if (pressed) {\n // Which keycodes should we prevent default\n const preventDefault = [32, 37, 38, 39, 40, 48, 49, 50, 51, 52, 53, 54, 56, 57, 67, 70, 73, 75, 76, 77, 79];\n\n // Check focused element\n // and if the focused element is not editable (e.g. text input)\n // and any that accept key input http://webaim.org/techniques/keyboard/\n const focused = getFocusElement();\n if (\n is.element(focused) &&\n (focused !== this.player.elements.inputs.seek &&\n matches(focused, this.player.config.selectors.editable))\n ) {\n return;\n }\n\n // If the code is found prevent default (e.g. prevent scrolling for arrows)\n if (preventDefault.includes(code)) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n switch (code) {\n case 48:\n case 49:\n case 50:\n case 51:\n case 52:\n case 53:\n case 54:\n case 55:\n case 56:\n case 57:\n // 0-9\n if (!repeat) {\n seekByKey();\n }\n break;\n\n case 32:\n case 75:\n // Space and K key\n if (!repeat) {\n this.player.togglePlay();\n }\n break;\n\n case 38:\n // Arrow up\n this.player.increaseVolume(0.1);\n break;\n\n case 40:\n // Arrow down\n this.player.decreaseVolume(0.1);\n break;\n\n case 77:\n // M key\n if (!repeat) {\n this.player.muted = !this.player.muted;\n }\n break;\n\n case 39:\n // Arrow forward\n this.player.forward();\n break;\n\n case 37:\n // Arrow back\n this.player.rewind();\n break;\n\n case 70:\n // F key\n this.player.fullscreen.toggle();\n break;\n\n case 67:\n // C key\n if (!repeat) {\n this.player.toggleCaptions();\n }\n break;\n\n case 76:\n // L key\n this.player.loop = !this.player.loop;\n break;\n\n /* case 73:\n this.setLoop('start');\n break;\n\n case 76:\n this.setLoop();\n break;\n\n case 79:\n this.setLoop('end');\n break; */\n\n default:\n break;\n }\n\n // Escape is handle natively when in full screen\n // So we only need to worry about non native\n if (!this.player.fullscreen.enabled && this.player.fullscreen.active && code === 27) {\n this.player.fullscreen.toggle();\n }\n\n // Store last code for next cycle\n this.lastKey = code;\n } else {\n this.lastKey = null;\n }\n }\n\n // Toggle menu\n toggleMenu(event) {\n controls.toggleMenu.call(this.player, event);\n }\n\n // Device is touch enabled\n firstTouch() {\n this.player.touch = true;\n\n // Add touch class\n toggleClass(this.player.elements.container, this.player.config.classNames.isTouch, true);\n }\n\n // Global window & document listeners\n global(toggle = true) {\n // Keyboard shortcuts\n if (this.player.config.keyboard.global) {\n toggleListener.call(this.player, window, 'keydown keyup', this.handleKey, toggle, false);\n }\n\n // Click anywhere closes menu\n toggleListener.call(this.player, document.body, 'click', this.toggleMenu, toggle);\n\n // Detect touch by events\n once.call(this.player, document.body, 'touchstart', this.firstTouch);\n }\n\n // Container listeners\n container() {\n // Keyboard shortcuts\n if (!this.player.config.keyboard.global && this.player.config.keyboard.focused) {\n on.call(this.player, this.player.elements.container, 'keydown keyup', this.handleKey, false);\n }\n\n // Detect tab focus\n // Remove class on blur/focusout\n on.call(this.player, this.player.elements.container, 'focusout', event => {\n toggleClass(event.target, this.player.config.classNames.tabFocus, false);\n });\n // Add classname to tabbed elements\n on.call(this.player, this.player.elements.container, 'keydown', event => {\n if (event.keyCode !== 9) {\n return;\n }\n\n // Delay the adding of classname until the focus has changed\n // This event fires before the focusin event\n setTimeout(() => {\n toggleClass(getFocusElement(), this.player.config.classNames.tabFocus, true);\n }, 0);\n });\n\n // Toggle controls on mouse events and entering fullscreen\n on.call(\n this.player,\n this.player.elements.container,\n 'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen',\n event => {\n const { controls } = this.player.elements;\n\n // Remove button states for fullscreen\n if (event.type === 'enterfullscreen') {\n controls.pressed = false;\n controls.hover = false;\n }\n\n // Show, then hide after a timeout unless another control event occurs\n const show = ['touchstart', 'touchmove', 'mousemove'].includes(event.type);\n\n let delay = 0;\n\n if (show) {\n ui.toggleControls.call(this.player, true);\n // Use longer timeout for touch devices\n delay = this.player.touch ? 3000 : 2000;\n }\n\n // Clear timer\n clearTimeout(this.player.timers.controls);\n // Timer to prevent flicker when seeking\n this.player.timers.controls = setTimeout(() => ui.toggleControls.call(this.player, false), delay);\n },\n );\n }\n\n // Listen for media events\n media() {\n // Time change on media\n on.call(this.player, this.player.media, 'timeupdate seeking seeked', event =>\n controls.timeUpdate.call(this.player, event),\n );\n\n // Display duration\n on.call(this.player, this.player.media, 'durationchange loadeddata loadedmetadata', event =>\n controls.durationUpdate.call(this.player, event),\n );\n\n // Check for audio tracks on load\n // We can't use `loadedmetadata` as it doesn't seem to have audio tracks at that point\n on.call(this.player, this.player.media, 'canplay', () => {\n toggleHidden(this.player.elements.volume, !this.player.hasAudio);\n toggleHidden(this.player.elements.buttons.mute, !this.player.hasAudio);\n });\n\n // Handle the media finishing\n on.call(this.player, this.player.media, 'ended', () => {\n // Show poster on end\n if (this.player.isHTML5 && this.player.isVideo && this.player.config.resetOnEnd) {\n // Restart\n this.player.restart();\n }\n });\n\n // Check for buffer progress\n on.call(this.player, this.player.media, 'progress playing seeking seeked', event =>\n controls.updateProgress.call(this.player, event),\n );\n\n // Handle volume changes\n on.call(this.player, this.player.media, 'volumechange', event =>\n controls.updateVolume.call(this.player, event),\n );\n\n // Handle play/pause\n on.call(this.player, this.player.media, 'playing play pause ended emptied timeupdate', event =>\n ui.checkPlaying.call(this.player, event),\n );\n\n // Loading state\n on.call(this.player, this.player.media, 'waiting canplay seeked playing', event =>\n ui.checkLoading.call(this.player, event),\n );\n\n // If autoplay, then load advertisement if required\n // TODO: Show some sort of loading state while the ad manager loads else there's a delay before ad shows\n on.call(this.player, this.player.media, 'playing', () => {\n if (!this.player.ads) {\n return;\n }\n\n // If ads are enabled, wait for them first\n if (this.player.ads.enabled && !this.player.ads.initialized) {\n // Wait for manager response\n this.player.ads.managerPromise.then(() => this.player.ads.play()).catch(() => this.player.play());\n }\n });\n\n // Click video\n if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) {\n // Re-fetch the wrapper\n const wrapper = getElement.call(this.player, `.${this.player.config.classNames.video}`);\n\n // Bail if there's no wrapper (this should never happen)\n if (!is.element(wrapper)) {\n return;\n }\n\n // On click play, pause ore restart\n on.call(this.player, wrapper, 'click', () => {\n // Touch devices will just show controls (if we're hiding controls)\n if (this.player.config.hideControls && this.player.touch && !this.player.paused) {\n return;\n }\n\n if (this.player.paused) {\n this.player.play();\n } else if (this.player.ended) {\n this.player.restart();\n this.player.play();\n } else {\n this.player.pause();\n }\n });\n }\n\n // Disable right click\n if (this.player.supported.ui && this.player.config.disableContextMenu) {\n on.call(\n this.player,\n this.player.elements.wrapper,\n 'contextmenu',\n event => {\n event.preventDefault();\n },\n false,\n );\n }\n\n // Volume change\n on.call(this.player, this.player.media, 'volumechange', () => {\n // Save to storage\n this.player.storage.set({ volume: this.player.volume, muted: this.player.muted });\n });\n\n // Speed change\n on.call(this.player, this.player.media, 'ratechange', () => {\n // Update UI\n controls.updateSetting.call(this.player, 'speed');\n\n // Save to storage\n this.player.storage.set({ speed: this.player.speed });\n });\n\n // Quality request\n on.call(this.player, this.player.media, 'qualityrequested', event => {\n // Save to storage\n this.player.storage.set({ quality: event.detail.quality });\n });\n\n // Quality change\n on.call(this.player, this.player.media, 'qualitychange', event => {\n // Update UI\n controls.updateSetting.call(this.player, 'quality', null, event.detail.quality);\n });\n\n // Proxy events to container\n // Bubble up key events for Edge\n const proxyEvents = this.player.config.events.concat(['keyup', 'keydown']).join(' ');\n on.call(this.player, this.player.media, proxyEvents, event => {\n let { detail = {} } = event;\n\n // Get error details from media\n if (event.type === 'error') {\n detail = this.player.media.error;\n }\n\n triggerEvent.call(this.player, this.player.elements.container, event.type, true, detail);\n });\n }\n\n // Listen for control events\n controls() {\n // IE doesn't support input event, so we fallback to change\n const inputEvent = browser.isIE ? 'change' : 'input';\n\n // Run default and custom handlers\n const proxy = (event, defaultHandler, customHandlerKey) => {\n const customHandler = this.player.config.listeners[customHandlerKey];\n const hasCustomHandler = is.function(customHandler);\n let returned = true;\n\n // Execute custom handler\n if (hasCustomHandler) {\n returned = customHandler.call(this.player, event);\n }\n\n // Only call default handler if not prevented in custom handler\n if (returned && is.function(defaultHandler)) {\n defaultHandler.call(this.player, event);\n }\n };\n\n // Trigger custom and default handlers\n const bind = (element, type, defaultHandler, customHandlerKey, passive = true) => {\n const customHandler = this.player.config.listeners[customHandlerKey];\n const hasCustomHandler = is.function(customHandler);\n\n on.call(\n this.player,\n element,\n type,\n event => proxy(event, defaultHandler, customHandlerKey),\n passive && !hasCustomHandler,\n );\n };\n\n // Play/pause toggle\n Array.from(this.player.elements.buttons.play).forEach(button => {\n bind(button, 'click', this.player.togglePlay, 'play');\n });\n\n // Pause\n bind(this.player.elements.buttons.restart, 'click', this.player.restart, 'restart');\n\n // Rewind\n bind(this.player.elements.buttons.rewind, 'click', this.player.rewind, 'rewind');\n\n // Rewind\n bind(this.player.elements.buttons.fastForward, 'click', this.player.forward, 'fastForward');\n\n // Mute toggle\n bind(\n this.player.elements.buttons.mute,\n 'click',\n () => {\n this.player.muted = !this.player.muted;\n },\n 'mute',\n );\n\n // Captions toggle\n bind(this.player.elements.buttons.captions, 'click', () => this.player.toggleCaptions());\n\n // Fullscreen toggle\n bind(\n this.player.elements.buttons.fullscreen,\n 'click',\n () => {\n this.player.fullscreen.toggle();\n },\n 'fullscreen',\n );\n\n // Picture-in-Picture\n bind(\n this.player.elements.buttons.pip,\n 'click',\n () => {\n this.player.pip = 'toggle';\n },\n 'pip',\n );\n\n // Airplay\n bind(this.player.elements.buttons.airplay, 'click', this.player.airplay, 'airplay');\n\n // Settings menu\n bind(this.player.elements.buttons.settings, 'click', event => {\n controls.toggleMenu.call(this.player, event);\n });\n\n // Settings menu\n bind(this.player.elements.settings.popup, 'click', event => {\n event.stopPropagation();\n\n // Go back to home tab on click\n const showHomeTab = () => {\n controls.showMenuPanel.call(this.player, 'home');\n };\n\n // Settings menu items - use event delegation as items are added/removed\n if (matches(event.target, this.player.config.selectors.inputs.language)) {\n proxy(\n event,\n () => {\n this.player.currentTrack = Number(event.target.value);\n showHomeTab();\n },\n 'language',\n );\n } else if (matches(event.target, this.player.config.selectors.inputs.quality)) {\n proxy(\n event,\n () => {\n this.player.quality = event.target.value;\n showHomeTab();\n },\n 'quality',\n );\n } else if (matches(event.target, this.player.config.selectors.inputs.speed)) {\n proxy(\n event,\n () => {\n this.player.speed = parseFloat(event.target.value);\n showHomeTab();\n },\n 'speed',\n );\n }\n });\n\n // Set range input alternative \"value\", which matches the tooltip time (#954)\n bind(this.player.elements.inputs.seek, 'mousedown mousemove', event => {\n const clientRect = this.player.elements.progress.getBoundingClientRect();\n const percent = 100 / clientRect.width * (event.pageX - clientRect.left);\n event.currentTarget.setAttribute('seek-value', percent);\n });\n\n // Pause while seeking\n bind(this.player.elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', event => {\n const seek = event.currentTarget;\n\n const code = event.keyCode ? event.keyCode : event.which;\n const eventType = event.type;\n\n if ((eventType === 'keydown' || eventType === 'keyup') && (code !== 39 && code !== 37)) {\n return;\n }\n // Was playing before?\n const play = seek.hasAttribute('play-on-seeked');\n\n // Done seeking\n const done = ['mouseup', 'touchend', 'keyup'].includes(event.type);\n\n // If we're done seeking and it was playing, resume playback\n if (play && done) {\n seek.removeAttribute('play-on-seeked');\n this.player.play();\n } else if (!done && this.player.playing) {\n seek.setAttribute('play-on-seeked', '');\n this.player.pause();\n }\n });\n\n // Seek\n bind(\n this.player.elements.inputs.seek,\n inputEvent,\n event => {\n const seek = event.currentTarget;\n\n // If it exists, use seek-value instead of \"value\" for consistency with tooltip time (#954)\n let seekTo = seek.getAttribute('seek-value');\n\n if (is.empty(seekTo)) {\n seekTo = seek.value;\n }\n\n seek.removeAttribute('seek-value');\n\n this.player.currentTime = seekTo / seek.max * this.player.duration;\n },\n 'seek',\n );\n\n // Current time invert\n // Only if one time element is used for both currentTime and duration\n if (this.player.config.toggleInvert && !is.element(this.player.elements.display.duration)) {\n bind(this.player.elements.display.currentTime, 'click', () => {\n // Do nothing if we're at the start\n if (this.player.currentTime === 0) {\n return;\n }\n\n this.player.config.invertTime = !this.player.config.invertTime;\n\n controls.timeUpdate.call(this.player);\n });\n }\n\n // Volume\n bind(\n this.player.elements.inputs.volume,\n inputEvent,\n event => {\n this.player.volume = event.target.value;\n },\n 'volume',\n );\n\n // Polyfill for lower fill in <input type=\"range\"> for webkit\n if (browser.isWebkit) {\n Array.from(getElements.call(this.player, 'input[type=\"range\"]')).forEach(element => {\n bind(element, 'input', event => controls.updateRangeFill.call(this.player, event.target));\n });\n }\n\n // Seek tooltip\n bind(this.player.elements.progress, 'mouseenter mouseleave mousemove', event =>\n controls.updateSeekTooltip.call(this.player, event),\n );\n\n // Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)\n bind(this.player.elements.controls, 'mouseenter mouseleave', event => {\n this.player.elements.controls.hover = !this.player.touch && event.type === 'mouseenter';\n });\n\n // Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)\n bind(this.player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {\n this.player.elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);\n });\n\n // Focus in/out on controls\n bind(this.player.elements.controls, 'focusin focusout', event => {\n const { config, elements, timers } = this.player;\n\n // Skip transition to prevent focus from scrolling the parent element\n toggleClass(elements.controls, config.classNames.noTransition, event.type === 'focusin');\n\n // Toggle\n ui.toggleControls.call(this.player, event.type === 'focusin');\n\n // If focusin, hide again after delay\n if (event.type === 'focusin') {\n // Restore transition\n setTimeout(() => {\n toggleClass(elements.controls, config.classNames.noTransition, false);\n }, 0);\n\n // Delay a little more for keyboard users\n const delay = this.touch ? 3000 : 4000;\n\n // Clear timer\n clearTimeout(timers.controls);\n // Hide\n timers.controls = setTimeout(() => ui.toggleControls.call(this.player, false), delay);\n }\n });\n\n // Mouse wheel for volume\n bind(\n this.player.elements.inputs.volume,\n 'wheel',\n event => {\n // Detect \"natural\" scroll - suppored on OS X Safari only\n // Other browsers on OS X will be inverted until support improves\n const inverted = event.webkitDirectionInvertedFromDevice;\n const step = 1 / 50;\n let direction = 0;\n\n // Scroll down (or up on natural) to decrease\n if (event.deltaY < 0 || event.deltaX > 0) {\n if (inverted) {\n this.player.decreaseVolume(step);\n direction = -1;\n } else {\n this.player.increaseVolume(step);\n direction = 1;\n }\n }\n\n // Scroll up (or down on natural) to increase\n if (event.deltaY > 0 || event.deltaX < 0) {\n if (inverted) {\n this.player.increaseVolume(step);\n direction = 1;\n } else {\n this.player.decreaseVolume(step);\n direction = -1;\n }\n }\n\n // Don't break page scrolling at max and min\n if (\n (direction === 1 && this.player.media.volume < 1) ||\n (direction === -1 && this.player.media.volume > 0)\n ) {\n event.preventDefault();\n }\n },\n 'volume',\n false,\n );\n }\n}\n\nexport default Listeners;\n","(function(root, factory) {\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n } else {\n root.loadjs = factory();\n }\n}(this, function() {\n/**\n * Global dependencies.\n * @global {Object} document - DOM\n */\n\nvar devnull = function() {},\n bundleIdCache = {},\n bundleResultCache = {},\n bundleCallbackQueue = {};\n\n\n/**\n * Subscribe to bundle load event.\n * @param {string[]} bundleIds - Bundle ids\n * @param {Function} callbackFn - The callback function\n */\nfunction subscribe(bundleIds, callbackFn) {\n // listify\n bundleIds = bundleIds.push ? bundleIds : [bundleIds];\n\n var depsNotFound = [],\n i = bundleIds.length,\n numWaiting = i,\n fn,\n bundleId,\n r,\n q;\n\n // define callback function\n fn = function (bundleId, pathsNotFound) {\n if (pathsNotFound.length) depsNotFound.push(bundleId);\n\n numWaiting--;\n if (!numWaiting) callbackFn(depsNotFound);\n };\n\n // register callback\n while (i--) {\n bundleId = bundleIds[i];\n\n // execute callback if in result cache\n r = bundleResultCache[bundleId];\n if (r) {\n fn(bundleId, r);\n continue;\n }\n\n // add to callback queue\n q = bundleCallbackQueue[bundleId] = bundleCallbackQueue[bundleId] || [];\n q.push(fn);\n }\n}\n\n\n/**\n * Publish bundle load event.\n * @param {string} bundleId - Bundle id\n * @param {string[]} pathsNotFound - List of files not found\n */\nfunction publish(bundleId, pathsNotFound) {\n // exit if id isn't defined\n if (!bundleId) return;\n\n var q = bundleCallbackQueue[bundleId];\n\n // cache result\n bundleResultCache[bundleId] = pathsNotFound;\n\n // exit if queue is empty\n if (!q) return;\n\n // empty callback queue\n while (q.length) {\n q[0](bundleId, pathsNotFound);\n q.splice(0, 1);\n }\n}\n\n\n/**\n * Execute callbacks.\n * @param {Object or Function} args - The callback args\n * @param {string[]} depsNotFound - List of dependencies not found\n */\nfunction executeCallbacks(args, depsNotFound) {\n // accept function as argument\n if (args.call) args = {success: args};\n\n // success and error callbacks\n if (depsNotFound.length) (args.error || devnull)(depsNotFound);\n else (args.success || devnull)(args);\n}\n\n\n/**\n * Load individual file.\n * @param {string} path - The file path\n * @param {Function} callbackFn - The callback function\n */\nfunction loadFile(path, callbackFn, args, numTries) {\n var doc = document,\n async = args.async,\n maxTries = (args.numRetries || 0) + 1,\n beforeCallbackFn = args.before || devnull,\n pathStripped = path.replace(/^(css|img)!/, ''),\n isCss,\n e;\n\n numTries = numTries || 0;\n\n if (/(^css!|\\.css$)/.test(path)) {\n isCss = true;\n\n // css\n e = doc.createElement('link');\n e.rel = 'stylesheet';\n e.href = pathStripped; //.replace(/^css!/, ''); // remove \"css!\" prefix\n } else if (/(^img!|\\.(png|gif|jpg|svg)$)/.test(path)) {\n // image\n e = doc.createElement('img');\n e.src = pathStripped; \n } else {\n // javascript\n e = doc.createElement('script');\n e.src = path;\n e.async = async === undefined ? true : async;\n }\n\n e.onload = e.onerror = e.onbeforeload = function (ev) {\n var result = ev.type[0];\n\n // Note: The following code isolates IE using `hideFocus` and treats empty\n // stylesheets as failures to get around lack of onerror support\n if (isCss && 'hideFocus' in e) {\n try {\n if (!e.sheet.cssText.length) result = 'e';\n } catch (x) {\n // sheets objects created from load errors don't allow access to\n // `cssText`\n result = 'e';\n }\n }\n\n // handle retries in case of load failure\n if (result == 'e') {\n // increment counter\n numTries += 1;\n\n // exit function and try again\n if (numTries < maxTries) {\n return loadFile(path, callbackFn, args, numTries);\n }\n }\n\n // execute callback\n callbackFn(path, result, ev.defaultPrevented);\n };\n\n // add to document (unless callback returns `false`)\n if (beforeCallbackFn(path, e) !== false) doc.head.appendChild(e);\n}\n\n\n/**\n * Load multiple files.\n * @param {string[]} paths - The file paths\n * @param {Function} callbackFn - The callback function\n */\nfunction loadFiles(paths, callbackFn, args) {\n // listify paths\n paths = paths.push ? paths : [paths];\n\n var numWaiting = paths.length,\n x = numWaiting,\n pathsNotFound = [],\n fn,\n i;\n\n // define callback function\n fn = function(path, result, defaultPrevented) {\n // handle error\n if (result == 'e') pathsNotFound.push(path);\n\n // handle beforeload event. If defaultPrevented then that means the load\n // will be blocked (ex. Ghostery/ABP on Safari)\n if (result == 'b') {\n if (defaultPrevented) pathsNotFound.push(path);\n else return;\n }\n\n numWaiting--;\n if (!numWaiting) callbackFn(pathsNotFound);\n };\n\n // load scripts\n for (i=0; i < x; i++) loadFile(paths[i], fn, args);\n}\n\n\n/**\n * Initiate script load and register bundle.\n * @param {(string|string[])} paths - The file paths\n * @param {(string|Function)} [arg1] - The bundleId or success callback\n * @param {Function} [arg2] - The success or error callback\n * @param {Function} [arg3] - The error callback\n */\nfunction loadjs(paths, arg1, arg2) {\n var bundleId,\n args;\n\n // bundleId (if string)\n if (arg1 && arg1.trim) bundleId = arg1;\n\n // args (default is {})\n args = (bundleId ? arg2 : arg1) || {};\n\n // throw error if bundle is already defined\n if (bundleId) {\n if (bundleId in bundleIdCache) {\n throw \"LoadJS\";\n } else {\n bundleIdCache[bundleId] = true;\n }\n }\n\n // load scripts\n loadFiles(paths, function (pathsNotFound) {\n // execute callbacks\n executeCallbacks(args, pathsNotFound);\n\n // publish bundle load event\n publish(bundleId, pathsNotFound);\n }, args);\n}\n\n\n/**\n * Execute callbacks when dependencies have been satisfied.\n * @param {(string|string[])} deps - List of bundle ids\n * @param {Object} args - success/error arguments\n */\nloadjs.ready = function ready(deps, args) {\n // subscribe to bundle load event\n subscribe(deps, function (depsNotFound) {\n // execute callbacks\n executeCallbacks(args, depsNotFound);\n });\n\n return loadjs;\n};\n\n\n/**\n * Manually satisfy bundle dependencies.\n * @param {string} bundleId - The bundle id\n */\nloadjs.done = function done(bundleId) {\n publish(bundleId, []);\n};\n\n\n/**\n * Reset loadjs dependencies statuses\n */\nloadjs.reset = function reset() {\n bundleIdCache = {};\n bundleResultCache = {};\n bundleCallbackQueue = {};\n};\n\n\n/**\n * Determine if bundle has already been defined\n * @param String} bundleId - The bundle id\n */\nloadjs.isDefined = function isDefined(bundleId) {\n return bundleId in bundleIdCache;\n};\n\n\n// export\nreturn loadjs;\n\n}));\n","// ==========================================================================\n// Load an external script\n// ==========================================================================\n\nimport loadjs from 'loadjs';\n\nexport default function loadScript(url) {\n return new Promise((resolve, reject) => {\n loadjs(url, {\n success: resolve,\n error: reject,\n });\n });\n}\n","// ==========================================================================\n// Vimeo plugin\n// ==========================================================================\n\nimport captions from './../captions';\nimport controls from './../controls';\nimport ui from './../ui';\nimport { createElement, replaceElement, toggleClass } from './../utils/elements';\nimport { triggerEvent } from './../utils/events';\nimport fetch from './../utils/fetch';\nimport is from './../utils/is';\nimport loadScript from './../utils/loadScript';\nimport { format, stripHTML } from './../utils/strings';\nimport { buildUrlParams } from './../utils/urls';\n\n// Parse Vimeo ID from URL\nfunction parseId(url) {\n if (is.empty(url)) {\n return null;\n }\n\n if (is.number(Number(url))) {\n return url;\n }\n\n const regex = /^.*(vimeo.com\\/|video\\/)(\\d+).*/;\n return url.match(regex) ? RegExp.$2 : url;\n}\n\n// Get aspect ratio for dimensions\nfunction getAspectRatio(width, height) {\n const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h));\n const ratio = getRatio(width, height);\n return `${width / ratio}:${height / ratio}`;\n}\n\n// Set playback state and trigger change (only on actual change)\nfunction assurePlaybackState(play) {\n if (play && !this.embed.hasPlayed) {\n this.embed.hasPlayed = true;\n }\n if (this.media.paused === play) {\n this.media.paused = !play;\n triggerEvent.call(this, this.media, play ? 'play' : 'pause');\n }\n}\n\nconst vimeo = {\n setup() {\n // Add embed class for responsive\n toggleClass(this.elements.wrapper, this.config.classNames.embed, true);\n\n // Set intial ratio\n vimeo.setAspectRatio.call(this);\n\n // Load the API if not already\n if (!is.object(window.Vimeo)) {\n loadScript(this.config.urls.vimeo.sdk)\n .then(() => {\n vimeo.ready.call(this);\n })\n .catch(error => {\n this.debug.warn('Vimeo API failed to load', error);\n });\n } else {\n vimeo.ready.call(this);\n }\n },\n\n // Set aspect ratio\n // For Vimeo we have an extra 300% height <div> to hide the standard controls and UI\n setAspectRatio(input) {\n const [x, y] = (is.string(input) ? input : this.config.ratio).split(':');\n const padding = 100 / x * y;\n this.elements.wrapper.style.paddingBottom = `${padding}%`;\n\n if (this.supported.ui) {\n const height = 240;\n const offset = (height - padding) / (height / 50);\n\n this.media.style.transform = `translateY(-${offset}%)`;\n }\n },\n\n // API Ready\n ready() {\n const player = this;\n\n // Get Vimeo params for the iframe\n const options = {\n loop: player.config.loop.active,\n autoplay: player.autoplay,\n // muted: player.muted,\n byline: false,\n portrait: false,\n title: false,\n speed: true,\n transparent: 0,\n gesture: 'media',\n playsinline: !this.config.fullscreen.iosNative,\n };\n const params = buildUrlParams(options);\n\n // Get the source URL or ID\n let source = player.media.getAttribute('src');\n\n // Get from <div> if needed\n if (is.empty(source)) {\n source = player.media.getAttribute(player.config.attributes.embed.id);\n }\n\n const id = parseId(source);\n\n // Build an iframe\n const iframe = createElement('iframe');\n const src = format(player.config.urls.vimeo.iframe, id, params);\n iframe.setAttribute('src', src);\n iframe.setAttribute('allowfullscreen', '');\n iframe.setAttribute('allowtransparency', '');\n iframe.setAttribute('allow', 'autoplay');\n\n // Get poster, if already set\n const { poster } = player;\n\n // Inject the package\n const wrapper = createElement('div', { poster, class: player.config.classNames.embedContainer });\n wrapper.appendChild(iframe);\n player.media = replaceElement(wrapper, player.media);\n\n // Get poster image\n fetch(format(player.config.urls.vimeo.api, id), 'json').then(response => {\n if (is.empty(response)) {\n return;\n }\n\n // Get the URL for thumbnail\n const url = new URL(response[0].thumbnail_large);\n\n // Get original image\n url.pathname = `${url.pathname.split('_')[0]}.jpg`;\n\n // Set and show poster\n ui.setPoster.call(player, url.href).catch(() => {});\n });\n\n // Setup instance\n // https://github.com/vimeo/player.js\n player.embed = new window.Vimeo.Player(iframe, {\n autopause: player.config.autopause,\n muted: player.muted,\n });\n\n player.media.paused = true;\n player.media.currentTime = 0;\n\n // Disable native text track rendering\n if (player.supported.ui) {\n player.embed.disableTextTrack();\n }\n\n // Create a faux HTML5 API using the Vimeo API\n player.media.play = () => {\n assurePlaybackState.call(player, true);\n return player.embed.play();\n };\n\n player.media.pause = () => {\n assurePlaybackState.call(player, false);\n return player.embed.pause();\n };\n\n player.media.stop = () => {\n player.pause();\n player.currentTime = 0;\n };\n\n // Seeking\n let { currentTime } = player.media;\n Object.defineProperty(player.media, 'currentTime', {\n get() {\n return currentTime;\n },\n set(time) {\n // Vimeo will automatically play on seek if the video hasn't been played before\n\n // Get current paused state and volume etc\n const { embed, media, paused, volume } = player;\n const restorePause = paused && !embed.hasPlayed;\n\n // Set seeking state and trigger event\n media.seeking = true;\n triggerEvent.call(player, media, 'seeking');\n\n // If paused, mute until seek is complete\n Promise.resolve(restorePause && embed.setVolume(0))\n // Seek\n .then(() => embed.setCurrentTime(time))\n // Restore paused\n .then(() => restorePause && embed.pause())\n // Restore volume\n .then(() => restorePause && embed.setVolume(volume))\n .catch(() => {\n // Do nothing\n });\n },\n });\n\n // Playback speed\n let speed = player.config.speed.selected;\n Object.defineProperty(player.media, 'playbackRate', {\n get() {\n return speed;\n },\n set(input) {\n player.embed\n .setPlaybackRate(input)\n .then(() => {\n speed = input;\n triggerEvent.call(player, player.media, 'ratechange');\n })\n .catch(error => {\n // Hide menu item (and menu if empty)\n if (error.name === 'Error') {\n controls.setSpeedMenu.call(player, []);\n }\n });\n },\n });\n\n // Volume\n let { volume } = player.config;\n Object.defineProperty(player.media, 'volume', {\n get() {\n return volume;\n },\n set(input) {\n player.embed.setVolume(input).then(() => {\n volume = input;\n triggerEvent.call(player, player.media, 'volumechange');\n });\n },\n });\n\n // Muted\n let { muted } = player.config;\n Object.defineProperty(player.media, 'muted', {\n get() {\n return muted;\n },\n set(input) {\n const toggle = is.boolean(input) ? input : false;\n\n player.embed.setVolume(toggle ? 0 : player.config.volume).then(() => {\n muted = toggle;\n triggerEvent.call(player, player.media, 'volumechange');\n });\n },\n });\n\n // Loop\n let { loop } = player.config;\n Object.defineProperty(player.media, 'loop', {\n get() {\n return loop;\n },\n set(input) {\n const toggle = is.boolean(input) ? input : player.config.loop.active;\n\n player.embed.setLoop(toggle).then(() => {\n loop = toggle;\n });\n },\n });\n\n // Source\n let currentSrc;\n player.embed\n .getVideoUrl()\n .then(value => {\n currentSrc = value;\n })\n .catch(error => {\n this.debug.warn(error);\n });\n\n Object.defineProperty(player.media, 'currentSrc', {\n get() {\n return currentSrc;\n },\n });\n\n // Ended\n Object.defineProperty(player.media, 'ended', {\n get() {\n return player.currentTime === player.duration;\n },\n });\n\n // Set aspect ratio based on video size\n Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then(dimensions => {\n const ratio = getAspectRatio(dimensions[0], dimensions[1]);\n vimeo.setAspectRatio.call(this, ratio);\n });\n\n // Set autopause\n player.embed.setAutopause(player.config.autopause).then(state => {\n player.config.autopause = state;\n });\n\n // Get title\n player.embed.getVideoTitle().then(title => {\n player.config.title = title;\n ui.setTitle.call(this);\n });\n\n // Get current time\n player.embed.getCurrentTime().then(value => {\n currentTime = value;\n triggerEvent.call(player, player.media, 'timeupdate');\n });\n\n // Get duration\n player.embed.getDuration().then(value => {\n player.media.duration = value;\n triggerEvent.call(player, player.media, 'durationchange');\n });\n\n // Get captions\n player.embed.getTextTracks().then(tracks => {\n player.media.textTracks = tracks;\n captions.setup.call(player);\n });\n\n player.embed.on('cuechange', ({ cues = [] }) => {\n const strippedCues = cues.map(cue => stripHTML(cue.text));\n captions.updateCues.call(player, strippedCues);\n });\n\n player.embed.on('loaded', () => {\n // Assure state and events are updated on autoplay\n player.embed.getPaused().then(paused => {\n assurePlaybackState.call(player, !paused);\n if (!paused) {\n triggerEvent.call(player, player.media, 'playing');\n }\n });\n\n if (is.element(player.embed.element) && player.supported.ui) {\n const frame = player.embed.element;\n\n // Fix keyboard focus issues\n // https://github.com/sampotts/plyr/issues/317\n frame.setAttribute('tabindex', -1);\n }\n });\n\n player.embed.on('play', () => {\n assurePlaybackState.call(player, true);\n triggerEvent.call(player, player.media, 'playing');\n });\n\n player.embed.on('pause', () => {\n assurePlaybackState.call(player, false);\n });\n\n player.embed.on('timeupdate', data => {\n player.media.seeking = false;\n currentTime = data.seconds;\n triggerEvent.call(player, player.media, 'timeupdate');\n });\n\n player.embed.on('progress', data => {\n player.media.buffered = data.percent;\n triggerEvent.call(player, player.media, 'progress');\n\n // Check all loaded\n if (parseInt(data.percent, 10) === 1) {\n triggerEvent.call(player, player.media, 'canplaythrough');\n }\n\n // Get duration as if we do it before load, it gives an incorrect value\n // https://github.com/sampotts/plyr/issues/891\n player.embed.getDuration().then(value => {\n if (value !== player.media.duration) {\n player.media.duration = value;\n triggerEvent.call(player, player.media, 'durationchange');\n }\n });\n });\n\n player.embed.on('seeked', () => {\n player.media.seeking = false;\n triggerEvent.call(player, player.media, 'seeked');\n });\n\n player.embed.on('ended', () => {\n player.media.paused = true;\n triggerEvent.call(player, player.media, 'ended');\n });\n\n player.embed.on('error', detail => {\n player.media.error = detail;\n triggerEvent.call(player, player.media, 'error');\n });\n\n // Rebuild UI\n setTimeout(() => ui.build.call(player), 0);\n },\n};\n\nexport default vimeo;\n","// ==========================================================================\n// YouTube plugin\n// ==========================================================================\n\nimport controls from './../controls';\nimport ui from './../ui';\nimport { dedupe } from './../utils/arrays';\nimport { createElement, replaceElement, toggleClass } from './../utils/elements';\nimport { triggerEvent } from './../utils/events';\nimport fetch from './../utils/fetch';\nimport is from './../utils/is';\nimport loadImage from './../utils/loadImage';\nimport loadScript from './../utils/loadScript';\nimport { format, generateId } from './../utils/strings';\n\n// Parse YouTube ID from URL\nfunction parseId(url) {\n if (is.empty(url)) {\n return null;\n }\n\n const regex = /^.*(youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=|&v=)([^#&?]*).*/;\n return url.match(regex) ? RegExp.$2 : url;\n}\n\n// Standardise YouTube quality unit\nfunction mapQualityUnit(input) {\n const qualities = {\n hd2160: 2160,\n hd1440: 1440,\n hd1080: 1080,\n hd720: 720,\n large: 480,\n medium: 360,\n small: 240,\n tiny: 144,\n };\n\n const entry = Object.entries(qualities).find(entry => entry.includes(input));\n\n if (entry) {\n // Get the match corresponding to the input\n return entry.find(value => value !== input);\n }\n\n return 'default';\n}\n\nfunction mapQualityUnits(levels) {\n if (is.empty(levels)) {\n return levels;\n }\n\n return dedupe(levels.map(level => mapQualityUnit(level)));\n}\n\n// Set playback state and trigger change (only on actual change)\nfunction assurePlaybackState(play) {\n if (play && !this.embed.hasPlayed) {\n this.embed.hasPlayed = true;\n }\n if (this.media.paused === play) {\n this.media.paused = !play;\n triggerEvent.call(this, this.media, play ? 'play' : 'pause');\n }\n}\n\nconst youtube = {\n setup() {\n // Add embed class for responsive\n toggleClass(this.elements.wrapper, this.config.classNames.embed, true);\n\n // Set aspect ratio\n youtube.setAspectRatio.call(this);\n\n // Setup API\n if (is.object(window.YT) && is.function(window.YT.Player)) {\n youtube.ready.call(this);\n } else {\n // Load the API\n loadScript(this.config.urls.youtube.sdk).catch(error => {\n this.debug.warn('YouTube API failed to load', error);\n });\n\n // Setup callback for the API\n // YouTube has it's own system of course...\n window.onYouTubeReadyCallbacks = window.onYouTubeReadyCallbacks || [];\n\n // Add to queue\n window.onYouTubeReadyCallbacks.push(() => {\n youtube.ready.call(this);\n });\n\n // Set callback to process queue\n window.onYouTubeIframeAPIReady = () => {\n window.onYouTubeReadyCallbacks.forEach(callback => {\n callback();\n });\n };\n }\n },\n\n // Get the media title\n getTitle(videoId) {\n // Try via undocumented API method first\n // This method disappears now and then though...\n // https://github.com/sampotts/plyr/issues/709\n if (is.function(this.embed.getVideoData)) {\n const { title } = this.embed.getVideoData();\n\n if (is.empty(title)) {\n this.config.title = title;\n ui.setTitle.call(this);\n return;\n }\n }\n\n // Or via Google API\n const key = this.config.keys.google;\n if (is.string(key) && !is.empty(key)) {\n const url = format(this.config.urls.youtube.api, videoId, key);\n\n fetch(url)\n .then(result => {\n if (is.object(result)) {\n this.config.title = result.items[0].snippet.title;\n ui.setTitle.call(this);\n }\n })\n .catch(() => {});\n }\n },\n\n // Set aspect ratio\n setAspectRatio() {\n const ratio = this.config.ratio.split(':');\n this.elements.wrapper.style.paddingBottom = `${100 / ratio[0] * ratio[1]}%`;\n },\n\n // API ready\n ready() {\n const player = this;\n\n // Ignore already setup (race condition)\n const currentId = player.media.getAttribute('id');\n if (!is.empty(currentId) && currentId.startsWith('youtube-')) {\n return;\n }\n\n // Get the source URL or ID\n let source = player.media.getAttribute('src');\n\n // Get from <div> if needed\n if (is.empty(source)) {\n source = player.media.getAttribute(this.config.attributes.embed.id);\n }\n\n // Replace the <iframe> with a <div> due to YouTube API issues\n const videoId = parseId(source);\n const id = generateId(player.provider);\n\n // Get poster, if already set\n const { poster } = player;\n\n // Replace media element\n const container = createElement('div', { id, poster });\n player.media = replaceElement(container, player.media);\n\n // Id to poster wrapper\n const posterSrc = format => `https://img.youtube.com/vi/${videoId}/${format}default.jpg`;\n\n // Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)\n loadImage(posterSrc('maxres'), 121) // Higest quality and unpadded\n .catch(() => loadImage(posterSrc('sd'), 121)) // 480p padded 4:3\n .catch(() => loadImage(posterSrc('hq'))) // 360p padded 4:3. Always exists\n .then(image => ui.setPoster.call(player, image.src))\n .then(posterSrc => {\n // If the image is padded, use background-size \"cover\" instead (like youtube does too with their posters)\n if (!posterSrc.includes('maxres')) {\n player.elements.poster.style.backgroundSize = 'cover';\n }\n })\n .catch(() => {});\n\n // Setup instance\n // https://developers.google.com/youtube/iframe_api_reference\n player.embed = new window.YT.Player(id, {\n videoId,\n playerVars: {\n autoplay: player.config.autoplay ? 1 : 0, // Autoplay\n controls: player.supported.ui ? 0 : 1, // Only show controls if not fully supported\n rel: 0, // No related vids\n showinfo: 0, // Hide info\n iv_load_policy: 3, // Hide annotations\n modestbranding: 1, // Hide logos as much as possible (they still show one in the corner when paused)\n disablekb: 1, // Disable keyboard as we handle it\n playsinline: 1, // Allow iOS inline playback\n\n // Tracking for stats\n // origin: window ? `${window.location.protocol}//${window.location.host}` : null,\n widget_referrer: window ? window.location.href : null,\n\n // Captions are flaky on YouTube\n cc_load_policy: player.captions.active ? 1 : 0,\n cc_lang_pref: player.config.captions.language,\n },\n events: {\n onError(event) {\n // YouTube may fire onError twice, so only handle it once\n if (!player.media.error) {\n const code = event.data;\n // Messages copied from https://developers.google.com/youtube/iframe_api_reference#onError\n const message =\n {\n 2: 'The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.',\n 5: 'The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.',\n 100: 'The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.',\n 101: 'The owner of the requested video does not allow it to be played in embedded players.',\n 150: 'The owner of the requested video does not allow it to be played in embedded players.',\n }[code] || 'An unknown error occured';\n\n player.media.error = { code, message };\n\n triggerEvent.call(player, player.media, 'error');\n }\n },\n onPlaybackQualityChange() {\n triggerEvent.call(player, player.media, 'qualitychange', false, {\n quality: player.media.quality,\n });\n },\n onPlaybackRateChange(event) {\n // Get the instance\n const instance = event.target;\n\n // Get current speed\n player.media.playbackRate = instance.getPlaybackRate();\n\n triggerEvent.call(player, player.media, 'ratechange');\n },\n onReady(event) {\n // Get the instance\n const instance = event.target;\n\n // Get the title\n youtube.getTitle.call(player, videoId);\n\n // Create a faux HTML5 API using the YouTube API\n player.media.play = () => {\n assurePlaybackState.call(player, true);\n instance.playVideo();\n };\n\n player.media.pause = () => {\n assurePlaybackState.call(player, false);\n instance.pauseVideo();\n };\n\n player.media.stop = () => {\n instance.stopVideo();\n };\n\n player.media.duration = instance.getDuration();\n player.media.paused = true;\n\n // Seeking\n player.media.currentTime = 0;\n Object.defineProperty(player.media, 'currentTime', {\n get() {\n return Number(instance.getCurrentTime());\n },\n set(time) {\n // If paused, mute audio preventively (YouTube starts playing on seek if the video hasn't been played yet).\n if (player.paused) {\n player.embed.mute();\n }\n\n // Set seeking state and trigger event\n player.media.seeking = true;\n triggerEvent.call(player, player.media, 'seeking');\n\n // Seek after events sent\n instance.seekTo(time);\n },\n });\n\n // Playback speed\n Object.defineProperty(player.media, 'playbackRate', {\n get() {\n return instance.getPlaybackRate();\n },\n set(input) {\n instance.setPlaybackRate(input);\n },\n });\n\n // Quality\n Object.defineProperty(player.media, 'quality', {\n get() {\n return mapQualityUnit(instance.getPlaybackQuality());\n },\n set(input) {\n instance.setPlaybackQuality(mapQualityUnit(input));\n },\n });\n\n // Volume\n let { volume } = player.config;\n Object.defineProperty(player.media, 'volume', {\n get() {\n return volume;\n },\n set(input) {\n volume = input;\n instance.setVolume(volume * 100);\n triggerEvent.call(player, player.media, 'volumechange');\n },\n });\n\n // Muted\n let { muted } = player.config;\n Object.defineProperty(player.media, 'muted', {\n get() {\n return muted;\n },\n set(input) {\n const toggle = is.boolean(input) ? input : muted;\n muted = toggle;\n instance[toggle ? 'mute' : 'unMute']();\n triggerEvent.call(player, player.media, 'volumechange');\n },\n });\n\n // Source\n Object.defineProperty(player.media, 'currentSrc', {\n get() {\n return instance.getVideoUrl();\n },\n });\n\n // Ended\n Object.defineProperty(player.media, 'ended', {\n get() {\n return player.currentTime === player.duration;\n },\n });\n\n // Get available speeds\n player.options.speed = instance.getAvailablePlaybackRates();\n\n // Set the tabindex to avoid focus entering iframe\n if (player.supported.ui) {\n player.media.setAttribute('tabindex', -1);\n }\n\n triggerEvent.call(player, player.media, 'timeupdate');\n triggerEvent.call(player, player.media, 'durationchange');\n\n // Reset timer\n clearInterval(player.timers.buffering);\n\n // Setup buffering\n player.timers.buffering = setInterval(() => {\n // Get loaded % from YouTube\n player.media.buffered = instance.getVideoLoadedFraction();\n\n // Trigger progress only when we actually buffer something\n if (player.media.lastBuffered === null || player.media.lastBuffered < player.media.buffered) {\n triggerEvent.call(player, player.media, 'progress');\n }\n\n // Set last buffer point\n player.media.lastBuffered = player.media.buffered;\n\n // Bail if we're at 100%\n if (player.media.buffered === 1) {\n clearInterval(player.timers.buffering);\n\n // Trigger event\n triggerEvent.call(player, player.media, 'canplaythrough');\n }\n }, 200);\n\n // Rebuild UI\n setTimeout(() => ui.build.call(player), 50);\n },\n onStateChange(event) {\n // Get the instance\n const instance = event.target;\n\n // Reset timer\n clearInterval(player.timers.playing);\n\n const seeked = player.media.seeking && [1, 2].includes(event.data);\n\n if (seeked) {\n // Unset seeking and fire seeked event\n player.media.seeking = false;\n triggerEvent.call(player, player.media, 'seeked');\n }\n\n // Handle events\n // -1 Unstarted\n // 0 Ended\n // 1 Playing\n // 2 Paused\n // 3 Buffering\n // 5 Video cued\n switch (event.data) {\n case -1:\n // Update scrubber\n triggerEvent.call(player, player.media, 'timeupdate');\n\n // Get loaded % from YouTube\n player.media.buffered = instance.getVideoLoadedFraction();\n triggerEvent.call(player, player.media, 'progress');\n\n break;\n\n case 0:\n assurePlaybackState.call(player, false);\n\n // YouTube doesn't support loop for a single video, so mimick it.\n if (player.media.loop) {\n // YouTube needs a call to `stopVideo` before playing again\n instance.stopVideo();\n instance.playVideo();\n } else {\n triggerEvent.call(player, player.media, 'ended');\n }\n\n break;\n\n case 1:\n // Restore paused state (YouTube starts playing on seek if the video hasn't been played yet)\n if (player.media.paused && !player.embed.hasPlayed) {\n player.media.pause();\n } else {\n assurePlaybackState.call(player, true);\n\n triggerEvent.call(player, player.media, 'playing');\n\n // Poll to get playback progress\n player.timers.playing = setInterval(() => {\n triggerEvent.call(player, player.media, 'timeupdate');\n }, 50);\n\n // Check duration again due to YouTube bug\n // https://github.com/sampotts/plyr/issues/374\n // https://code.google.com/p/gdata-issues/issues/detail?id=8690\n if (player.media.duration !== instance.getDuration()) {\n player.media.duration = instance.getDuration();\n triggerEvent.call(player, player.media, 'durationchange');\n }\n\n // Get quality\n controls.setQualityMenu.call(\n player,\n mapQualityUnits(instance.getAvailableQualityLevels()),\n );\n }\n\n break;\n\n case 2:\n // Restore audio (YouTube starts playing on seek if the video hasn't been played yet)\n if (!player.muted) {\n player.embed.unMute();\n }\n assurePlaybackState.call(player, false);\n\n break;\n\n default:\n break;\n }\n\n triggerEvent.call(player, player.elements.container, 'statechange', false, {\n code: event.data,\n });\n },\n },\n });\n },\n};\n\nexport default youtube;\n","// ==========================================================================\n// Plyr Media\n// ==========================================================================\n\nimport html5 from './html5';\nimport vimeo from './plugins/vimeo';\nimport youtube from './plugins/youtube';\nimport { createElement, toggleClass, wrap } from './utils/elements';\n\nconst media = {\n // Setup media\n setup() {\n // If there's no media, bail\n if (!this.media) {\n this.debug.warn('No media element found!');\n return;\n }\n\n // Add type class\n toggleClass(this.elements.container, this.config.classNames.type.replace('{0}', this.type), true);\n\n // Add provider class\n toggleClass(this.elements.container, this.config.classNames.provider.replace('{0}', this.provider), true);\n\n // Add video class for embeds\n // This will require changes if audio embeds are added\n if (this.isEmbed) {\n toggleClass(this.elements.container, this.config.classNames.type.replace('{0}', 'video'), true);\n }\n\n // Inject the player wrapper\n if (this.isVideo) {\n // Create the wrapper div\n this.elements.wrapper = createElement('div', {\n class: this.config.classNames.video,\n });\n\n // Wrap the video in a container\n wrap(this.media, this.elements.wrapper);\n\n // Faux poster container\n this.elements.poster = createElement('div', {\n class: this.config.classNames.poster,\n });\n\n this.elements.wrapper.appendChild(this.elements.poster);\n }\n\n if (this.isHTML5) {\n html5.extend.call(this);\n } else if (this.isYouTube) {\n youtube.setup.call(this);\n } else if (this.isVimeo) {\n vimeo.setup.call(this);\n }\n },\n};\n\nexport default media;\n","// ==========================================================================\n// Advertisement plugin using Google IMA HTML5 SDK\n// Create an account with our ad partner, vi here:\n// https://www.vi.ai/publisher-video-monetization/\n// ==========================================================================\n\n/* global google */\n\nimport i18n from '../i18n';\nimport { createElement } from './../utils/elements';\nimport { triggerEvent } from './../utils/events';\nimport is from './../utils/is';\nimport loadScript from './../utils/loadScript';\nimport { formatTime } from './../utils/time';\nimport { buildUrlParams } from './../utils/urls';\n\nclass Ads {\n /**\n * Ads constructor.\n * @param {object} player\n * @return {Ads}\n */\n constructor(player) {\n this.player = player;\n this.publisherId = player.config.ads.publisherId;\n this.playing = false;\n this.initialized = false;\n this.elements = {\n container: null,\n displayContainer: null,\n };\n this.manager = null;\n this.loader = null;\n this.cuePoints = null;\n this.events = {};\n this.safetyTimer = null;\n this.countdownTimer = null;\n\n // Setup a promise to resolve when the IMA manager is ready\n this.managerPromise = new Promise((resolve, reject) => {\n // The ad is loaded and ready\n this.on('loaded', resolve);\n\n // Ads failed\n this.on('error', reject);\n });\n\n this.load();\n }\n\n get enabled() {\n return this.player.isVideo && this.player.config.ads.enabled && !is.empty(this.publisherId);\n }\n\n /**\n * Load the IMA SDK\n */\n load() {\n if (this.enabled) {\n // Check if the Google IMA3 SDK is loaded or load it ourselves\n if (!is.object(window.google) || !is.object(window.google.ima)) {\n loadScript(this.player.config.urls.googleIMA.sdk)\n .then(() => {\n this.ready();\n })\n .catch(() => {\n // Script failed to load or is blocked\n this.trigger('error', new Error('Google IMA SDK failed to load'));\n });\n } else {\n this.ready();\n }\n }\n }\n\n /**\n * Get the ads instance ready\n */\n ready() {\n // Start ticking our safety timer. If the whole advertisement\n // thing doesn't resolve within our set time; we bail\n this.startSafetyTimer(12000, 'ready()');\n\n // Clear the safety timer\n this.managerPromise.then(() => {\n this.clearSafetyTimer('onAdsManagerLoaded()');\n });\n\n // Set listeners on the Plyr instance\n this.listeners();\n\n // Setup the IMA SDK\n this.setupIMA();\n }\n\n // Build the default tag URL\n get tagUrl() {\n const params = {\n AV_PUBLISHERID: '58c25bb0073ef448b1087ad6',\n AV_CHANNELID: '5a0458dc28a06145e4519d21',\n AV_URL: location.hostname,\n cb: Date.now(),\n AV_WIDTH: 640,\n AV_HEIGHT: 480,\n AV_CDIM2: this.publisherId,\n };\n\n const base = 'https://go.aniview.com/api/adserver6/vast/';\n\n return `${base}?${buildUrlParams(params)}`;\n }\n\n /**\n * In order for the SDK to display ads for our video, we need to tell it where to put them,\n * so here we define our ad container. This div is set up to render on top of the video player.\n * Using the code below, we tell the SDK to render ads within that div. We also provide a\n * handle to the content video player - the SDK will poll the current time of our player to\n * properly place mid-rolls. After we create the ad display container, we initialize it. On\n * mobile devices, this initialization is done as the result of a user action.\n */\n setupIMA() {\n // Create the container for our advertisements\n this.elements.container = createElement('div', {\n class: this.player.config.classNames.ads,\n });\n this.player.elements.container.appendChild(this.elements.container);\n\n // So we can run VPAID2\n google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED);\n\n // Set language\n google.ima.settings.setLocale(this.player.config.ads.language);\n\n // We assume the adContainer is the video container of the plyr element\n // that will house the ads\n this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container);\n\n // Request video ads to be pre-loaded\n this.requestAds();\n }\n\n /**\n * Request advertisements\n */\n requestAds() {\n const { container } = this.player.elements;\n\n try {\n // Create ads loader\n this.loader = new google.ima.AdsLoader(this.elements.displayContainer);\n\n // Listen and respond to ads loaded and error events\n this.loader.addEventListener(\n google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,\n event => this.onAdsManagerLoaded(event),\n false,\n );\n this.loader.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error), false);\n\n // Request video ads\n const request = new google.ima.AdsRequest();\n request.adTagUrl = this.tagUrl;\n\n // Specify the linear and nonlinear slot sizes. This helps the SDK\n // to select the correct creative if multiple are returned\n request.linearAdSlotWidth = container.offsetWidth;\n request.linearAdSlotHeight = container.offsetHeight;\n request.nonLinearAdSlotWidth = container.offsetWidth;\n request.nonLinearAdSlotHeight = container.offsetHeight;\n\n // We only overlay ads as we only support video.\n request.forceNonLinearFullSlot = false;\n\n // Mute based on current state\n request.setAdWillPlayMuted(!this.player.muted);\n\n this.loader.requestAds(request);\n } catch (e) {\n this.onAdError(e);\n }\n }\n\n /**\n * Update the ad countdown\n * @param {boolean} start\n */\n pollCountdown(start = false) {\n if (!start) {\n clearInterval(this.countdownTimer);\n this.elements.container.removeAttribute('data-badge-text');\n return;\n }\n\n const update = () => {\n const time = formatTime(Math.max(this.manager.getRemainingTime(), 0));\n const label = `${i18n.get('advertisement', this.player.config)} - ${time}`;\n this.elements.container.setAttribute('data-badge-text', label);\n };\n\n this.countdownTimer = setInterval(update, 100);\n }\n\n /**\n * This method is called whenever the ads are ready inside the AdDisplayContainer\n * @param {Event} adsManagerLoadedEvent\n */\n onAdsManagerLoaded(event) {\n // Get the ads manager\n const settings = new google.ima.AdsRenderingSettings();\n\n // Tell the SDK to save and restore content video state on our behalf\n settings.restoreCustomPlaybackStateOnAdBreakComplete = true;\n settings.enablePreloading = true;\n\n // The SDK is polling currentTime on the contentPlayback. And needs a duration\n // so it can determine when to start the mid- and post-roll\n this.manager = event.getAdsManager(this.player, settings);\n\n // Get the cue points for any mid-rolls by filtering out the pre- and post-roll\n this.cuePoints = this.manager.getCuePoints();\n\n // Add advertisement cue's within the time line if available\n if (!is.empty(this.cuePoints)) {\n this.cuePoints.forEach(cuePoint => {\n if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < this.player.duration) {\n const seekElement = this.player.elements.progress;\n\n if (is.element(seekElement)) {\n const cuePercentage = 100 / this.player.duration * cuePoint;\n const cue = createElement('span', {\n class: this.player.config.classNames.cues,\n });\n\n cue.style.left = `${cuePercentage.toString()}%`;\n seekElement.appendChild(cue);\n }\n }\n });\n }\n\n // Get skippable state\n // TODO: Skip button\n // this.player.debug.warn(this.manager.getAdSkippableState());\n\n // Set volume to match player\n this.manager.setVolume(this.player.volume);\n\n // Add listeners to the required events\n // Advertisement error events\n this.manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error));\n\n // Advertisement regular events\n Object.keys(google.ima.AdEvent.Type).forEach(type => {\n this.manager.addEventListener(google.ima.AdEvent.Type[type], event => this.onAdEvent(event));\n });\n\n // Resolve our adsManager\n this.trigger('loaded');\n }\n\n /**\n * This is where all the event handling takes place. Retrieve the ad from the event. Some\n * events (e.g. ALL_ADS_COMPLETED) don't have the ad object associated\n * https://developers.google.com/interactive-media-ads/docs/sdks/html5/v3/apis#ima.AdEvent.Type\n * @param {Event} event\n */\n onAdEvent(event) {\n const { container } = this.player.elements;\n\n // Retrieve the ad from the event. Some events (e.g. ALL_ADS_COMPLETED)\n // don't have ad object associated\n const ad = event.getAd();\n\n // Proxy event\n const dispatchEvent = type => {\n const event = `ads${type.replace(/_/g, '').toLowerCase()}`;\n triggerEvent.call(this.player, this.player.media, event);\n };\n\n switch (event.type) {\n case google.ima.AdEvent.Type.LOADED:\n // This is the first event sent for an ad - it is possible to determine whether the\n // ad is a video ad or an overlay\n this.trigger('loaded');\n\n // Bubble event\n dispatchEvent(event.type);\n\n // Start countdown\n this.pollCountdown(true);\n\n if (!ad.isLinear()) {\n // Position AdDisplayContainer correctly for overlay\n ad.width = container.offsetWidth;\n ad.height = container.offsetHeight;\n }\n\n // console.info('Ad type: ' + event.getAd().getAdPodInfo().getPodIndex());\n // console.info('Ad time: ' + event.getAd().getAdPodInfo().getTimeOffset());\n break;\n\n case google.ima.AdEvent.Type.ALL_ADS_COMPLETED:\n // All ads for the current videos are done. We can now request new advertisements\n // in case the video is re-played\n\n // Fire event\n dispatchEvent(event.type);\n\n // TODO: Example for what happens when a next video in a playlist would be loaded.\n // So here we load a new video when all ads are done.\n // Then we load new ads within a new adsManager. When the video\n // Is started - after - the ads are loaded, then we get ads.\n // You can also easily test cancelling and reloading by running\n // player.ads.cancel() and player.ads.play from the console I guess.\n // this.player.source = {\n // type: 'video',\n // title: 'View From A Blue Moon',\n // sources: [{\n // src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4', type:\n // 'video/mp4', }], poster:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg', tracks:\n // [ { kind: 'captions', label: 'English', srclang: 'en', src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt',\n // default: true, }, { kind: 'captions', label: 'French', srclang: 'fr', src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt', }, ],\n // };\n\n // TODO: So there is still this thing where a video should only be allowed to start\n // playing when the IMA SDK is ready or has failed\n\n this.loadAds();\n break;\n\n case google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED:\n // This event indicates the ad has started - the video player can adjust the UI,\n // for example display a pause button and remaining time. Fired when content should\n // be paused. This usually happens right before an ad is about to cover the content\n\n dispatchEvent(event.type);\n\n this.pauseContent();\n\n break;\n\n case google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED:\n // This event indicates the ad has finished - the video player can perform\n // appropriate UI actions, such as removing the timer for remaining time detection.\n // Fired when content should be resumed. This usually happens when an ad finishes\n // or collapses\n\n dispatchEvent(event.type);\n\n this.pollCountdown();\n\n this.resumeContent();\n\n break;\n\n case google.ima.AdEvent.Type.STARTED:\n case google.ima.AdEvent.Type.MIDPOINT:\n case google.ima.AdEvent.Type.COMPLETE:\n case google.ima.AdEvent.Type.IMPRESSION:\n case google.ima.AdEvent.Type.CLICK:\n dispatchEvent(event.type);\n break;\n\n default:\n break;\n }\n }\n\n /**\n * Any ad error handling comes through here\n * @param {Event} event\n */\n onAdError(event) {\n this.cancel();\n this.player.debug.warn('Ads error', event);\n }\n\n /**\n * Setup hooks for Plyr and window events. This ensures\n * the mid- and post-roll launch at the correct time. And\n * resize the advertisement when the player resizes\n */\n listeners() {\n const { container } = this.player.elements;\n let time;\n\n // Add listeners to the required events\n this.player.on('ended', () => {\n this.loader.contentComplete();\n });\n\n this.player.on('seeking', () => {\n time = this.player.currentTime;\n return time;\n });\n\n this.player.on('seeked', () => {\n const seekedTime = this.player.currentTime;\n\n if (is.empty(this.cuePoints)) {\n return;\n }\n\n this.cuePoints.forEach((cuePoint, index) => {\n if (time < cuePoint && cuePoint < seekedTime) {\n this.manager.discardAdBreak();\n this.cuePoints.splice(index, 1);\n }\n });\n });\n\n // Listen to the resizing of the window. And resize ad accordingly\n // TODO: eventually implement ResizeObserver\n window.addEventListener('resize', () => {\n if (this.manager) {\n this.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);\n }\n });\n }\n\n /**\n * Initialize the adsManager and start playing advertisements\n */\n play() {\n const { container } = this.player.elements;\n\n if (!this.managerPromise) {\n this.resumeContent();\n }\n\n // Play the requested advertisement whenever the adsManager is ready\n this.managerPromise\n .then(() => {\n // Initialize the container. Must be done via a user action on mobile devices\n this.elements.displayContainer.initialize();\n\n try {\n if (!this.initialized) {\n // Initialize the ads manager. Ad rules playlist will start at this time\n this.manager.init(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);\n\n // Call play to start showing the ad. Single video and overlay ads will\n // start at this time; the call will be ignored for ad rules\n this.manager.start();\n }\n\n this.initialized = true;\n } catch (adError) {\n // An error may be thrown if there was a problem with the\n // VAST response\n this.onAdError(adError);\n }\n })\n .catch(() => {});\n }\n\n /**\n * Resume our video\n */\n resumeContent() {\n // Hide the advertisement container\n this.elements.container.style.zIndex = '';\n\n // Ad is stopped\n this.playing = false;\n\n // Play our video\n if (this.player.currentTime < this.player.duration) {\n this.player.play();\n }\n }\n\n /**\n * Pause our video\n */\n pauseContent() {\n // Show the advertisement container\n this.elements.container.style.zIndex = 3;\n\n // Ad is playing.\n this.playing = true;\n\n // Pause our video.\n this.player.pause();\n }\n\n /**\n * Destroy the adsManager so we can grab new ads after this. If we don't then we're not\n * allowed to call new ads based on google policies, as they interpret this as an accidental\n * video requests. https://developers.google.com/interactive-\n * media-ads/docs/sdks/android/faq#8\n */\n cancel() {\n // Pause our video\n if (this.initialized) {\n this.resumeContent();\n }\n\n // Tell our instance that we're done for now\n this.trigger('error');\n\n // Re-create our adsManager\n this.loadAds();\n }\n\n /**\n * Re-create our adsManager\n */\n loadAds() {\n // Tell our adsManager to go bye bye\n this.managerPromise\n .then(() => {\n // Destroy our adsManager\n if (this.manager) {\n this.manager.destroy();\n }\n\n // Re-set our adsManager promises\n this.managerPromise = new Promise(resolve => {\n this.on('loaded', resolve);\n this.player.debug.log(this.manager);\n });\n\n // Now request some new advertisements\n this.requestAds();\n })\n .catch(() => {});\n }\n\n /**\n * Handles callbacks after an ad event was invoked\n * @param {string} event - Event type\n */\n trigger(event, ...args) {\n const handlers = this.events[event];\n\n if (is.array(handlers)) {\n handlers.forEach(handler => {\n if (is.function(handler)) {\n handler.apply(this, args);\n }\n });\n }\n }\n\n /**\n * Add event listeners\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n * @return {Ads}\n */\n on(event, callback) {\n if (!is.array(this.events[event])) {\n this.events[event] = [];\n }\n\n this.events[event].push(callback);\n\n return this;\n }\n\n /**\n * Setup a safety timer for when the ad network doesn't respond for whatever reason.\n * The advertisement has 12 seconds to get its things together. We stop this timer when the\n * advertisement is playing, or when a user action is required to start, then we clear the\n * timer on ad ready\n * @param {number} time\n * @param {string} from\n */\n startSafetyTimer(time, from) {\n this.player.debug.log(`Safety timer invoked from: ${from}`);\n\n this.safetyTimer = setTimeout(() => {\n this.cancel();\n this.clearSafetyTimer('startSafetyTimer()');\n }, time);\n }\n\n /**\n * Clear our safety timer(s)\n * @param {string} from\n */\n clearSafetyTimer(from) {\n if (!is.nullOrUndefined(this.safetyTimer)) {\n this.player.debug.log(`Safety timer cleared from: ${from}`);\n\n clearTimeout(this.safetyTimer);\n this.safetyTimer = null;\n }\n }\n}\n\nexport default Ads;\n","// ==========================================================================\n// Plyr source update\n// ==========================================================================\n\nimport { providers } from './config/types';\nimport html5 from './html5';\nimport media from './media';\nimport support from './support';\nimport ui from './ui';\nimport { createElement, insertElement, removeElement } from './utils/elements';\nimport is from './utils/is';\nimport { getDeep } from './utils/objects';\n\nconst source = {\n // Add elements to HTML5 media (source, tracks, etc)\n insertElements(type, attributes) {\n if (is.string(attributes)) {\n insertElement(type, this.media, {\n src: attributes,\n });\n } else if (is.array(attributes)) {\n attributes.forEach(attribute => {\n insertElement(type, this.media, attribute);\n });\n }\n },\n\n // Update source\n // Sources are not checked for support so be careful\n change(input) {\n if (!getDeep(input, 'sources.length')) {\n this.debug.warn('Invalid source format');\n return;\n }\n\n // Cancel current network requests\n html5.cancelRequests.call(this);\n\n // Destroy instance and re-setup\n this.destroy.call(\n this,\n () => {\n // Reset quality options\n this.options.quality = [];\n\n // Remove elements\n removeElement(this.media);\n this.media = null;\n\n // Reset class name\n if (is.element(this.elements.container)) {\n this.elements.container.removeAttribute('class');\n }\n\n // Set the type and provider\n const { sources, type } = input;\n const [{ provider = providers.html5, src }] = sources;\n const tagName = provider === 'html5' ? type : 'div';\n const attributes = provider === 'html5' ? {} : { src };\n\n Object.assign(this, {\n provider,\n type,\n // Check for support\n supported: support.check(type, provider, this.config.playsinline),\n // Create new element\n media: createElement(tagName, attributes),\n });\n\n // Inject the new element\n this.elements.container.appendChild(this.media);\n\n // Autoplay the new source?\n if (is.boolean(input.autoplay)) {\n this.config.autoplay = input.autoplay;\n }\n\n // Set attributes for audio and video\n if (this.isHTML5) {\n if (this.config.crossorigin) {\n this.media.setAttribute('crossorigin', '');\n }\n if (this.config.autoplay) {\n this.media.setAttribute('autoplay', '');\n }\n if (!is.empty(input.poster)) {\n this.poster = input.poster;\n }\n if (this.config.loop.active) {\n this.media.setAttribute('loop', '');\n }\n if (this.config.muted) {\n this.media.setAttribute('muted', '');\n }\n if (this.config.playsinline) {\n this.media.setAttribute('playsinline', '');\n }\n }\n\n // Restore class hook\n ui.addStyleHook.call(this);\n\n // Set new sources for html5\n if (this.isHTML5) {\n source.insertElements.call(this, 'source', sources);\n }\n\n // Set video title\n this.config.title = input.title;\n\n // Set up from scratch\n media.setup.call(this);\n\n // HTML5 stuff\n if (this.isHTML5) {\n // Setup captions\n if ('tracks' in input) {\n source.insertElements.call(this, 'track', input.tracks);\n }\n\n // Load HTML5 sources\n this.media.load();\n }\n\n // If HTML5 or embed but not fully supported, setupInterface and call ready now\n if (this.isHTML5 || (this.isEmbed && !this.supported.ui)) {\n // Setup interface\n ui.build.call(this);\n }\n\n // Update the fullscreen support\n this.fullscreen.update();\n },\n true,\n );\n },\n};\n\nexport default source;\n","// ==========================================================================\n// Plyr\n// plyr.js v3.3.15\n// https://github.com/sampotts/plyr\n// License: The MIT License (MIT)\n// ==========================================================================\n\nimport captions from './captions';\nimport defaults from './config/defaults';\nimport { getProviderByUrl, providers, types } from './config/types';\nimport Console from './console';\nimport controls from './controls';\nimport Fullscreen from './fullscreen';\nimport Listeners from './listeners';\nimport media from './media';\nimport Ads from './plugins/ads';\nimport source from './source';\nimport Storage from './storage';\nimport support from './support';\nimport ui from './ui';\nimport { closest } from './utils/arrays';\nimport { createElement, hasClass, removeElement, replaceElement, toggleClass, wrap } from './utils/elements';\nimport { off, on, once, triggerEvent, unbindListeners } from './utils/events';\nimport is from './utils/is';\nimport loadSprite from './utils/loadSprite';\nimport { cloneDeep, extend } from './utils/objects';\nimport { parseUrl } from './utils/urls';\n\n// Private properties\n// TODO: Use a WeakMap for private globals\n// const globals = new WeakMap();\n\n// Plyr instance\nclass Plyr {\n constructor(target, options) {\n this.timers = {};\n\n // State\n this.ready = false;\n this.loading = false;\n this.failed = false;\n\n // Touch device\n this.touch = support.touch;\n\n // Set the media element\n this.media = target;\n\n // String selector passed\n if (is.string(this.media)) {\n this.media = document.querySelectorAll(this.media);\n }\n\n // jQuery, NodeList or Array passed, use first element\n if ((window.jQuery && this.media instanceof jQuery) || is.nodeList(this.media) || is.array(this.media)) {\n // eslint-disable-next-line\n this.media = this.media[0];\n }\n\n // Set config\n this.config = extend(\n {},\n defaults,\n Plyr.defaults,\n options || {},\n (() => {\n try {\n return JSON.parse(this.media.getAttribute('data-plyr-config'));\n } catch (e) {\n return {};\n }\n })(),\n );\n\n // Elements cache\n this.elements = {\n container: null,\n captions: null,\n buttons: {},\n display: {},\n progress: {},\n inputs: {},\n settings: {\n popup: null,\n menu: null,\n panels: {},\n buttons: {},\n },\n };\n\n // Captions\n this.captions = {\n active: null,\n currentTrack: -1,\n meta: new WeakMap(),\n };\n\n // Fullscreen\n this.fullscreen = {\n active: false,\n };\n\n // Options\n this.options = {\n speed: [],\n quality: [],\n };\n\n // Debugging\n // TODO: move to globals\n this.debug = new Console(this.config.debug);\n\n // Log config options and support\n this.debug.log('Config', this.config);\n this.debug.log('Support', support);\n\n // We need an element to setup\n if (is.nullOrUndefined(this.media) || !is.element(this.media)) {\n this.debug.error('Setup failed: no suitable element passed');\n return;\n }\n\n // Bail if the element is initialized\n if (this.media.plyr) {\n this.debug.warn('Target already setup');\n return;\n }\n\n // Bail if not enabled\n if (!this.config.enabled) {\n this.debug.error('Setup failed: disabled by config');\n return;\n }\n\n // Bail if disabled or no basic support\n // You may want to disable certain UAs etc\n if (!support.check().api) {\n this.debug.error('Setup failed: no support');\n return;\n }\n\n // Cache original element state for .destroy()\n const clone = this.media.cloneNode(true);\n clone.autoplay = false;\n this.elements.original = clone;\n\n // Set media type based on tag or data attribute\n // Supported: video, audio, vimeo, youtube\n const type = this.media.tagName.toLowerCase();\n\n // Embed properties\n let iframe = null;\n let url = null;\n\n // Different setup based on type\n switch (type) {\n case 'div':\n // Find the frame\n iframe = this.media.querySelector('iframe');\n\n // <iframe> type\n if (is.element(iframe)) {\n // Detect provider\n url = parseUrl(iframe.getAttribute('src'));\n this.provider = getProviderByUrl(url.toString());\n\n // Rework elements\n this.elements.container = this.media;\n this.media = iframe;\n\n // Reset classname\n this.elements.container.className = '';\n\n // Get attributes from URL and set config\n if (url.searchParams.length) {\n const truthy = ['1', 'true'];\n\n if (truthy.includes(url.searchParams.get('autoplay'))) {\n this.config.autoplay = true;\n }\n if (truthy.includes(url.searchParams.get('loop'))) {\n this.config.loop.active = true;\n }\n\n // TODO: replace fullscreen.iosNative with this playsinline config option\n // YouTube requires the playsinline in the URL\n if (this.isYouTube) {\n this.config.playsinline = truthy.includes(url.searchParams.get('playsinline'));\n } else {\n this.config.playsinline = true;\n }\n }\n } else {\n // <div> with attributes\n this.provider = this.media.getAttribute(this.config.attributes.embed.provider);\n\n // Remove attribute\n this.media.removeAttribute(this.config.attributes.embed.provider);\n }\n\n // Unsupported or missing provider\n if (is.empty(this.provider) || !Object.keys(providers).includes(this.provider)) {\n this.debug.error('Setup failed: Invalid provider');\n return;\n }\n\n // Audio will come later for external providers\n this.type = types.video;\n\n break;\n\n case 'video':\n case 'audio':\n this.type = type;\n this.provider = providers.html5;\n\n // Get config from attributes\n if (this.media.hasAttribute('crossorigin')) {\n this.config.crossorigin = true;\n }\n if (this.media.hasAttribute('autoplay')) {\n this.config.autoplay = true;\n }\n if (this.media.hasAttribute('playsinline')) {\n this.config.playsinline = true;\n }\n if (this.media.hasAttribute('muted')) {\n this.config.muted = true;\n }\n if (this.media.hasAttribute('loop')) {\n this.config.loop.active = true;\n }\n\n break;\n\n default:\n this.debug.error('Setup failed: unsupported type');\n return;\n }\n\n // Check for support again but with type\n this.supported = support.check(this.type, this.provider, this.config.playsinline);\n\n // If no support for even API, bail\n if (!this.supported.api) {\n this.debug.error('Setup failed: no support');\n return;\n }\n\n this.eventListeners = [];\n\n // Create listeners\n this.listeners = new Listeners(this);\n\n // Setup local storage for user settings\n this.storage = new Storage(this);\n\n // Store reference\n this.media.plyr = this;\n\n // Wrap media\n if (!is.element(this.elements.container)) {\n this.elements.container = createElement('div');\n wrap(this.media, this.elements.container);\n }\n\n // Add style hook\n ui.addStyleHook.call(this);\n\n // Setup media\n media.setup.call(this);\n\n // Listen for events if debugging\n if (this.config.debug) {\n on.call(this, this.elements.container, this.config.events.join(' '), event => {\n this.debug.log(`event: ${event.type}`);\n });\n }\n\n // Setup interface\n // If embed but not fully supported, build interface now to avoid flash of controls\n if (this.isHTML5 || (this.isEmbed && !this.supported.ui)) {\n ui.build.call(this);\n }\n\n // Container listeners\n this.listeners.container();\n\n // Global listeners\n this.listeners.global();\n\n // Setup fullscreen\n this.fullscreen = new Fullscreen(this);\n\n // Setup ads if provided\n this.ads = new Ads(this);\n\n // Autoplay if required\n if (this.config.autoplay) {\n this.play();\n }\n }\n\n // ---------------------------------------\n // API\n // ---------------------------------------\n\n /**\n * Types and provider helpers\n */\n get isHTML5() {\n return Boolean(this.provider === providers.html5);\n }\n get isEmbed() {\n return Boolean(this.isYouTube || this.isVimeo);\n }\n get isYouTube() {\n return Boolean(this.provider === providers.youtube);\n }\n get isVimeo() {\n return Boolean(this.provider === providers.vimeo);\n }\n get isVideo() {\n return Boolean(this.type === types.video);\n }\n get isAudio() {\n return Boolean(this.type === types.audio);\n }\n\n /**\n * Play the media, or play the advertisement (if they are not blocked)\n */\n play() {\n if (!is.function(this.media.play)) {\n return null;\n }\n\n // Return the promise (for HTML5)\n return this.media.play();\n }\n\n /**\n * Pause the media\n */\n pause() {\n if (!this.playing || !is.function(this.media.pause)) {\n return;\n }\n\n this.media.pause();\n }\n\n /**\n * Get playing state\n */\n get playing() {\n return Boolean(this.ready && !this.paused && !this.ended);\n }\n\n /**\n * Get paused state\n */\n get paused() {\n return Boolean(this.media.paused);\n }\n\n /**\n * Get stopped state\n */\n get stopped() {\n return Boolean(this.paused && this.currentTime === 0);\n }\n\n /**\n * Get ended state\n */\n get ended() {\n return Boolean(this.media.ended);\n }\n\n /**\n * Toggle playback based on current status\n * @param {boolean} input\n */\n togglePlay(input) {\n // Toggle based on current state if nothing passed\n const toggle = is.boolean(input) ? input : !this.playing;\n\n if (toggle) {\n this.play();\n } else {\n this.pause();\n }\n }\n\n /**\n * Stop playback\n */\n stop() {\n if (this.isHTML5) {\n this.pause();\n this.restart();\n } else if (is.function(this.media.stop)) {\n this.media.stop();\n }\n }\n\n /**\n * Restart playback\n */\n restart() {\n this.currentTime = 0;\n }\n\n /**\n * Rewind\n * @param {number} seekTime - how far to rewind in seconds. Defaults to the config.seekTime\n */\n rewind(seekTime) {\n this.currentTime = this.currentTime - (is.number(seekTime) ? seekTime : this.config.seekTime);\n }\n\n /**\n * Fast forward\n * @param {number} seekTime - how far to fast forward in seconds. Defaults to the config.seekTime\n */\n forward(seekTime) {\n this.currentTime = this.currentTime + (is.number(seekTime) ? seekTime : this.config.seekTime);\n }\n\n /**\n * Seek to a time\n * @param {number} input - where to seek to in seconds. Defaults to 0 (the start)\n */\n set currentTime(input) {\n // Bail if media duration isn't available yet\n if (!this.duration) {\n return;\n }\n\n // Validate input\n const inputIsValid = is.number(input) && input > 0;\n\n // Set\n this.media.currentTime = inputIsValid ? Math.min(input, this.duration) : 0;\n\n // Logging\n this.debug.log(`Seeking to ${this.currentTime} seconds`);\n }\n\n /**\n * Get current time\n */\n get currentTime() {\n return Number(this.media.currentTime);\n }\n\n /**\n * Get buffered\n */\n get buffered() {\n const { buffered } = this.media;\n\n // YouTube / Vimeo return a float between 0-1\n if (is.number(buffered)) {\n return buffered;\n }\n\n // HTML5\n // TODO: Handle buffered chunks of the media\n // (i.e. seek to another section buffers only that section)\n if (buffered && buffered.length && this.duration > 0) {\n return buffered.end(0) / this.duration;\n }\n\n return 0;\n }\n\n /**\n * Get seeking status\n */\n get seeking() {\n return Boolean(this.media.seeking);\n }\n\n /**\n * Get the duration of the current media\n */\n get duration() {\n // Faux duration set via config\n const fauxDuration = parseFloat(this.config.duration);\n\n // Media duration can be NaN before the media has loaded\n const duration = (this.media || {}).duration || 0;\n\n // If config duration is funky, use regular duration\n return fauxDuration || duration;\n }\n\n /**\n * Set the player volume\n * @param {number} value - must be between 0 and 1. Defaults to the value from local storage and config.volume if not set in storage\n */\n set volume(value) {\n let volume = value;\n const max = 1;\n const min = 0;\n\n if (is.string(volume)) {\n volume = Number(volume);\n }\n\n // Load volume from storage if no value specified\n if (!is.number(volume)) {\n volume = this.storage.get('volume');\n }\n\n // Use config if all else fails\n if (!is.number(volume)) {\n ({ volume } = this.config);\n }\n\n // Maximum is volumeMax\n if (volume > max) {\n volume = max;\n }\n // Minimum is volumeMin\n if (volume < min) {\n volume = min;\n }\n\n // Update config\n this.config.volume = volume;\n\n // Set the player volume\n this.media.volume = volume;\n\n // If muted, and we're increasing volume manually, reset muted state\n if (!is.empty(value) && this.muted && volume > 0) {\n this.muted = false;\n }\n }\n\n /**\n * Get the current player volume\n */\n get volume() {\n return Number(this.media.volume);\n }\n\n /**\n * Increase volume\n * @param {boolean} step - How much to decrease by (between 0 and 1)\n */\n increaseVolume(step) {\n const volume = this.media.muted ? 0 : this.volume;\n this.volume = volume + (is.number(step) ? step : 1);\n }\n\n /**\n * Decrease volume\n * @param {boolean} step - How much to decrease by (between 0 and 1)\n */\n decreaseVolume(step) {\n const volume = this.media.muted ? 0 : this.volume;\n this.volume = volume - (is.number(step) ? step : 1);\n }\n\n /**\n * Set muted state\n * @param {boolean} mute\n */\n set muted(mute) {\n let toggle = mute;\n\n // Load muted state from storage\n if (!is.boolean(toggle)) {\n toggle = this.storage.get('muted');\n }\n\n // Use config if all else fails\n if (!is.boolean(toggle)) {\n toggle = this.config.muted;\n }\n\n // Update config\n this.config.muted = toggle;\n\n // Set mute on the player\n this.media.muted = toggle;\n }\n\n /**\n * Get current muted state\n */\n get muted() {\n return Boolean(this.media.muted);\n }\n\n /**\n * Check if the media has audio\n */\n get hasAudio() {\n // Assume yes for all non HTML5 (as we can't tell...)\n if (!this.isHTML5) {\n return true;\n }\n\n if (this.isAudio) {\n return true;\n }\n\n // Get audio tracks\n return (\n Boolean(this.media.mozHasAudio) ||\n Boolean(this.media.webkitAudioDecodedByteCount) ||\n Boolean(this.media.audioTracks && this.media.audioTracks.length)\n );\n }\n\n /**\n * Set playback speed\n * @param {number} speed - the speed of playback (0.5-2.0)\n */\n set speed(input) {\n let speed = null;\n\n if (is.number(input)) {\n speed = input;\n }\n\n if (!is.number(speed)) {\n speed = this.storage.get('speed');\n }\n\n if (!is.number(speed)) {\n speed = this.config.speed.selected;\n }\n\n // Set min/max\n if (speed < 0.1) {\n speed = 0.1;\n }\n if (speed > 2.0) {\n speed = 2.0;\n }\n\n if (!this.config.speed.options.includes(speed)) {\n this.debug.warn(`Unsupported speed (${speed})`);\n return;\n }\n\n // Update config\n this.config.speed.selected = speed;\n\n // Set media speed\n this.media.playbackRate = speed;\n }\n\n /**\n * Get current playback speed\n */\n get speed() {\n return Number(this.media.playbackRate);\n }\n\n /**\n * Set playback quality\n * Currently HTML5 & YouTube only\n * @param {number} input - Quality level\n */\n set quality(input) {\n const config = this.config.quality;\n const options = this.options.quality;\n\n if (!options.length) {\n return;\n }\n\n let quality = [\n !is.empty(input) && Number(input),\n this.storage.get('quality'),\n config.selected,\n config.default,\n ].find(is.number);\n\n if (!options.includes(quality)) {\n const value = closest(options, quality);\n this.debug.warn(`Unsupported quality option: ${quality}, using ${value} instead`);\n quality = value;\n }\n\n // Trigger request event\n triggerEvent.call(this, this.media, 'qualityrequested', false, { quality });\n\n // Update config\n config.selected = quality;\n\n // Set quality\n this.media.quality = quality;\n }\n\n /**\n * Get current quality level\n */\n get quality() {\n return this.media.quality;\n }\n\n /**\n * Toggle loop\n * TODO: Finish fancy new logic. Set the indicator on load as user may pass loop as config\n * @param {boolean} input - Whether to loop or not\n */\n set loop(input) {\n const toggle = is.boolean(input) ? input : this.config.loop.active;\n this.config.loop.active = toggle;\n this.media.loop = toggle;\n\n // Set default to be a true toggle\n /* const type = ['start', 'end', 'all', 'none', 'toggle'].includes(input) ? input : 'toggle';\n\n switch (type) {\n case 'start':\n if (this.config.loop.end && this.config.loop.end <= this.currentTime) {\n this.config.loop.end = null;\n }\n this.config.loop.start = this.currentTime;\n // this.config.loop.indicator.start = this.elements.display.played.value;\n break;\n\n case 'end':\n if (this.config.loop.start >= this.currentTime) {\n return this;\n }\n this.config.loop.end = this.currentTime;\n // this.config.loop.indicator.end = this.elements.display.played.value;\n break;\n\n case 'all':\n this.config.loop.start = 0;\n this.config.loop.end = this.duration - 2;\n this.config.loop.indicator.start = 0;\n this.config.loop.indicator.end = 100;\n break;\n\n case 'toggle':\n if (this.config.loop.active) {\n this.config.loop.start = 0;\n this.config.loop.end = null;\n } else {\n this.config.loop.start = 0;\n this.config.loop.end = this.duration - 2;\n }\n break;\n\n default:\n this.config.loop.start = 0;\n this.config.loop.end = null;\n break;\n } */\n }\n\n /**\n * Get current loop state\n */\n get loop() {\n return Boolean(this.media.loop);\n }\n\n /**\n * Set new media source\n * @param {object} input - The new source object (see docs)\n */\n set source(input) {\n source.change.call(this, input);\n }\n\n /**\n * Get current source\n */\n get source() {\n return this.media.currentSrc;\n }\n\n /**\n * Set the poster image for a video\n * @param {input} - the URL for the new poster image\n */\n set poster(input) {\n if (!this.isVideo) {\n this.debug.warn('Poster can only be set for video');\n return;\n }\n\n ui.setPoster.call(this, input, false).catch(() => {});\n }\n\n /**\n * Get the current poster image\n */\n get poster() {\n if (!this.isVideo) {\n return null;\n }\n\n return this.media.getAttribute('poster');\n }\n\n /**\n * Set the autoplay state\n * @param {boolean} input - Whether to autoplay or not\n */\n set autoplay(input) {\n const toggle = is.boolean(input) ? input : this.config.autoplay;\n this.config.autoplay = toggle;\n }\n\n /**\n * Get the current autoplay state\n */\n get autoplay() {\n return Boolean(this.config.autoplay);\n }\n\n /**\n * Toggle captions\n * @param {boolean} input - Whether to enable captions\n */\n toggleCaptions(input) {\n captions.toggle.call(this, input, false);\n }\n\n /**\n * Set the caption track by index\n * @param {number} - Caption index\n */\n set currentTrack(input) {\n captions.set.call(this, input, false);\n }\n\n /**\n * Get the current caption track index (-1 if disabled)\n */\n get currentTrack() {\n const { toggled, currentTrack } = this.captions;\n return toggled ? currentTrack : -1;\n }\n\n /**\n * Set the wanted language for captions\n * Since tracks can be added later it won't update the actual caption track until there is a matching track\n * @param {string} - Two character ISO language code (e.g. EN, FR, PT, etc)\n */\n set language(input) {\n captions.setLanguage.call(this, input, false);\n }\n\n /**\n * Get the current track's language\n */\n get language() {\n return (captions.getCurrentTrack.call(this) || {}).language;\n }\n\n /**\n * Toggle picture-in-picture playback on WebKit/MacOS\n * TODO: update player with state, support, enabled\n * TODO: detect outside changes\n */\n set pip(input) {\n const states = {\n pip: 'picture-in-picture',\n inline: 'inline',\n };\n\n // Bail if no support\n if (!support.pip) {\n return;\n }\n\n // Toggle based on current state if not passed\n const toggle = is.boolean(input) ? input : this.pip === states.inline;\n\n // Toggle based on current state\n this.media.webkitSetPresentationMode(toggle ? states.pip : states.inline);\n }\n\n /**\n * Get the current picture-in-picture state\n */\n get pip() {\n if (!support.pip) {\n return null;\n }\n\n return this.media.webkitPresentationMode;\n }\n\n /**\n * Trigger the airplay dialog\n * TODO: update player with state, support, enabled\n */\n airplay() {\n // Show dialog if supported\n if (support.airplay) {\n this.media.webkitShowPlaybackTargetPicker();\n }\n }\n\n /**\n * Toggle the player controls\n * @param {boolean} [toggle] - Whether to show the controls\n */\n toggleControls(toggle) {\n // Don't toggle if missing UI support or if it's audio\n if (this.supported.ui && !this.isAudio) {\n // Get state before change\n const isHidden = hasClass(this.elements.container, this.config.classNames.hideControls);\n\n // Negate the argument if not undefined since adding the class to hides the controls\n const force = typeof toggle === 'undefined' ? undefined : !toggle;\n\n // Apply and get updated state\n const hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force);\n\n // Close menu\n if (hiding && this.config.controls.includes('settings') && !is.empty(this.config.settings)) {\n controls.toggleMenu.call(this, false);\n }\n // Trigger event on change\n if (hiding !== isHidden) {\n const eventName = hiding ? 'controlshidden' : 'controlsshown';\n triggerEvent.call(this, this.media, eventName);\n }\n return !hiding;\n }\n return false;\n }\n\n /**\n * Add event listeners\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n */\n on(event, callback) {\n on.call(this, this.elements.container, event, callback);\n }\n /**\n * Add event listeners once\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n */\n once(event, callback) {\n once.call(this, this.elements.container, event, callback);\n }\n /**\n * Remove event listeners\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n */\n off(event, callback) {\n off(this.elements.container, event, callback);\n }\n\n /**\n * Destroy an instance\n * Event listeners are removed when elements are removed\n * http://stackoverflow.com/questions/12528049/if-a-dom-element-is-removed-are-its-listeners-also-removed-from-memory\n * @param {function} callback - Callback for when destroy is complete\n * @param {boolean} soft - Whether it's a soft destroy (for source changes etc)\n */\n destroy(callback, soft = false) {\n if (!this.ready) {\n return;\n }\n\n const done = () => {\n // Reset overflow (incase destroyed while in fullscreen)\n document.body.style.overflow = '';\n\n // GC for embed\n this.embed = null;\n\n // If it's a soft destroy, make minimal changes\n if (soft) {\n if (Object.keys(this.elements).length) {\n // Remove elements\n removeElement(this.elements.buttons.play);\n removeElement(this.elements.captions);\n removeElement(this.elements.controls);\n removeElement(this.elements.wrapper);\n\n // Clear for GC\n this.elements.buttons.play = null;\n this.elements.captions = null;\n this.elements.controls = null;\n this.elements.wrapper = null;\n }\n\n // Callback\n if (is.function(callback)) {\n callback();\n }\n } else {\n // Unbind listeners\n unbindListeners.call(this);\n\n // Replace the container with the original element provided\n replaceElement(this.elements.original, this.elements.container);\n\n // Event\n triggerEvent.call(this, this.elements.original, 'destroyed', true);\n\n // Callback\n if (is.function(callback)) {\n callback.call(this.elements.original);\n }\n\n // Reset state\n this.ready = false;\n\n // Clear for garbage collection\n setTimeout(() => {\n this.elements = null;\n this.media = null;\n }, 200);\n }\n };\n\n // Stop playback\n this.stop();\n\n // Provider specific stuff\n if (this.isHTML5) {\n // Clear timeout\n clearTimeout(this.timers.loading);\n\n // Restore native video controls\n ui.toggleNativeControls.call(this, true);\n\n // Clean up\n done();\n } else if (this.isYouTube) {\n // Clear timers\n clearInterval(this.timers.buffering);\n clearInterval(this.timers.playing);\n\n // Destroy YouTube API\n if (this.embed !== null && is.function(this.embed.destroy)) {\n this.embed.destroy();\n }\n\n // Clean up\n done();\n } else if (this.isVimeo) {\n // Destroy Vimeo API\n // then clean up (wait, to prevent postmessage errors)\n if (this.embed !== null) {\n this.embed.unload().then(done);\n }\n\n // Vimeo does not always return\n setTimeout(done, 200);\n }\n }\n\n /**\n * Check for support for a mime type (HTML5 only)\n * @param {string} type - Mime type\n */\n supports(type) {\n return support.mime.call(this, type);\n }\n\n /**\n * Check for support\n * @param {string} type - Player type (audio/video)\n * @param {string} provider - Provider (html5/youtube/vimeo)\n * @param {bool} inline - Where player has `playsinline` sttribute\n */\n static supported(type, provider, inline) {\n return support.check(type, provider, inline);\n }\n\n /**\n * Load an SVG sprite into the page\n * @param {string} url - URL for the SVG sprite\n * @param {string} [id] - Unique ID\n */\n static loadSprite(url, id) {\n return loadSprite(url, id);\n }\n\n /**\n * Setup multiple instances\n * @param {*} selector\n * @param {object} options\n */\n static setup(selector, options = {}) {\n let targets = null;\n\n if (is.string(selector)) {\n targets = Array.from(document.querySelectorAll(selector));\n } else if (is.nodeList(selector)) {\n targets = Array.from(selector);\n } else if (is.array(selector)) {\n targets = selector.filter(is.element);\n }\n\n if (is.empty(targets)) {\n return null;\n }\n\n return targets.map(t => new Plyr(t, options));\n }\n}\n\nPlyr.defaults = cloneDeep(defaults);\n\nexport default Plyr;\n"]}
\ No newline at end of file diff --git a/src/js/controls.js b/src/js/controls.js index 607511cb..b3435236 100644 --- a/src/js/controls.js +++ b/src/js/controls.js @@ -661,6 +661,7 @@ const controls = { setQualityMenu(options) { // Menu required if (!is.element(this.elements.settings.panels.quality)) { + console.warn('Not an element'); return; } @@ -673,6 +674,7 @@ const controls = { } // Toggle the pane and tab + console.warn(this.options.quality); const toggle = !is.empty(this.options.quality) && this.options.quality.length > 1; controls.toggleMenuButton.call(this, type, toggle); @@ -1073,7 +1075,10 @@ const controls = { toggleHidden(target, false); // Focus the first item - target.querySelectorAll('[role^="menuitem"]')[0].focus(); + const firstItem = target.querySelector('[role^="menuitem"]'); + if (firstItem) { + firstItem.focus(); + } }, // Build the default HTML |