diff options
author | Sam Potts <me@sampotts.me> | 2017-05-16 09:58:53 +1000 |
---|---|---|
committer | Sam Potts <me@sampotts.me> | 2017-05-16 09:58:53 +1000 |
commit | 966c3d875d68a096b6aaa5b86e3b9ae4d93696b5 (patch) | |
tree | c0c69346e14692b8ab7de9ba71b50dc30cec1bca | |
parent | fe9383bed57e6458fe40c6e1c22402b37987e5de (diff) | |
download | plyr-966c3d875d68a096b6aaa5b86e3b9ae4d93696b5.tar.lz plyr-966c3d875d68a096b6aaa5b86e3b9ae4d93696b5.tar.xz plyr-966c3d875d68a096b6aaa5b86e3b9ae4d93696b5.zip |
Single instance only
-rw-r--r-- | bundles.json | 9 | ||||
-rw-r--r-- | demo/dist/demo.js | 2 | ||||
-rw-r--r-- | demo/index.html | 2 | ||||
-rw-r--r-- | demo/src/js/lib/sprite.js | 89 | ||||
-rw-r--r-- | demo/src/js/main.js | 43 | ||||
-rw-r--r-- | dist/plyr.js | 4 | ||||
-rw-r--r-- | notes.md | 19 | ||||
-rw-r--r-- | readme.md | 10 | ||||
-rw-r--r-- | src/js/plyr.js | 1017 |
9 files changed, 596 insertions, 599 deletions
diff --git a/bundles.json b/bundles.json index d6fdf733..245c1d43 100644 --- a/bundles.json +++ b/bundles.json @@ -1,22 +1,23 @@ { "plyr": { "less": { - "plyr.css": ["src/less/plyr.less"] + "plyr.css": ["src/less/plyr.less"] }, "scss": { - "plyr.css": ["src/scss/plyr.scss"] + "plyr.css": ["src/scss/plyr.scss"] }, "js": { - "plyr.js": ["src/js/plyr.js"] + "plyr.js": ["src/js/plyr.js"] } }, "demo": { "less": { - "demo.css": ["demo/src/less/demo.less"] + "demo.css": ["demo/src/less/demo.less"] }, "js": { "demo.js": [ "demo/src/js/lib/classlist.js", + "demo/src/js/lib/sprite.js", "demo/src/js/main.js" ] } diff --git a/demo/dist/demo.js b/demo/dist/demo.js index 8e183fe8..5418f747 100644 --- a/demo/dist/demo.js +++ b/demo/dist/demo.js @@ -1 +1 @@ -"document"in self&&("classList"in document.createElement("_")?!function(){"use strict";var e=document.createElement("_");if(e.classList.add("c1","c2"),!e.classList.contains("c2")){var t=function(e){var t=DOMTokenList.prototype[e];DOMTokenList.prototype[e]=function(e){var i,s=arguments.length;for(i=0;i<s;i++)e=arguments[i],t.call(this,e)}};t("add"),t("remove")}if(e.classList.toggle("c3",!1),e.classList.contains("c3")){var i=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(e,t){return 1 in arguments&&!this.contains(e)==!t?t:i.call(this,e)}}e=null}():!function(e){"use strict";if("Element"in e){var t="classList",i="prototype",s=e.Element[i],o=Object,n=String[i].trim||function(){return this.replace(/^\s+|\s+$/g,"")},r=Array[i].indexOf||function(e){for(var t=0,i=this.length;t<i;t++)if(t in this&&this[t]===e)return t;return-1},a=function(e,t){this.name=e,this.code=DOMException[e],this.message=t},c=function(e,t){if(""===t)throw new a("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(t))throw new a("INVALID_CHARACTER_ERR","String contains an invalid character");return r.call(e,t)},l=function(e){for(var t=n.call(e.getAttribute("class")||""),i=t?t.split(/\s+/):[],s=0,o=i.length;s<o;s++)this.push(i[s]);this._updateClassName=function(){e.setAttribute("class",this.toString())}},u=l[i]=[],p=function(){return new l(this)};if(a[i]=Error[i],u.item=function(e){return this[e]||null},u.contains=function(e){return e+="",c(this,e)!==-1},u.add=function(){var e,t=arguments,i=0,s=t.length,o=!1;do e=t[i]+"",c(this,e)===-1&&(this.push(e),o=!0);while(++i<s);o&&this._updateClassName()},u.remove=function(){var e,t,i=arguments,s=0,o=i.length,n=!1;do for(e=i[s]+"",t=c(this,e);t!==-1;)this.splice(t,1),n=!0,t=c(this,e);while(++s<o);n&&this._updateClassName()},u.toggle=function(e,t){e+="";var i=this.contains(e),s=i?t!==!0&&"remove":t!==!1&&"add";return s&&this[s](e),t===!0||t===!1?t:!i},u.toString=function(){return this.join(" ")},o.defineProperty){var d={get:p,enumerable:!0,configurable:!0};try{o.defineProperty(s,t,d)}catch(e){e.number===-2146823252&&(d.enumerable=!1,o.defineProperty(s,t,d))}}else o[i].__defineGetter__&&s.__defineGetter__(t,p)}}(self)),function(){function e(e,t,i){if(e)if(e.classList)e.classList[i?"add":"remove"](t);else{var s=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=s+(i?" "+t:"")}}function t(t,i){if(t in n&&(i||t!==r)&&(r.length||t!==n.video)){switch(t){case n.video:s.source({type:"video",title:"View From A Blue Moon",sources:[{src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.mp4",type:"video/mp4"}],poster:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.jpg",tracks:[{kind:"captions",label:"English",srclang:"en",src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.en.vtt",default:!0}]});break;case n.audio:s.source({type:"audio",title:"Kishi Bashi – “It All Began With A Burst”",sources:[{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3",type:"audio/mp3"},{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg",type:"audio/ogg"}]});break;case n.youtube:s.source({type:"video",title:"View From A Blue Moon",sources:[{src:"https://www.youtube.com/watch?v=bTqVqk7FSmY",type:"youtube"}]});break;case n.vimeo:s.source({type:"video",title:"View From A Blue Moon",sources:[{src:"https://vimeo.com/76979871",type:"vimeo"}]})}r=t;for(var a=o.length-1;a>=0;a--)e(o[a].parentElement,"active",!1);e(document.querySelector('[data-source="'+t+'"]').parentElement,"active",!0)}}var i=plyr.setup({debug:!0,title:"Video demo",iconUrl:"../dist/plyr.svg",tooltips:{controls:!0},captions:{defaultActive:!0},controls:["play-large","play","progress","current-time","mute","volume","captions","settings","fullscreen","pip","airplay"]});plyr.loadSprite("dist/demo.svg");for(var s=i[0],o=document.querySelectorAll("[data-source]"),n={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},r=window.location.hash.replace("#",""),a=window.history&&window.history.pushState,c=o.length-1;c>=0;c--)o[c].addEventListener("click",function(){var e=this.getAttribute("data-source");t(e),a&&history.pushState({type:e},"","#"+e)});if(window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&t(e.state.type)}),a){var l=!r.length;l&&(r=n.video),r in n&&history.replaceState({type:r},"",l?"":"#"+r),r!==n.video&&t(r,!0)}}(),document.domain.indexOf("plyr.io")>-1&&(!function(e,t,i,s,o,n,r){e.GoogleAnalyticsObject=o,e[o]=e[o]||function(){(e[o].q=e[o].q||[]).push(arguments)},e[o].l=1*new Date,n=t.createElement(i),r=t.getElementsByTagName(i)[0],n.async=1,n.src=s,r.parentNode.insertBefore(n,r)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),ga("create","UA-40881672-11","auto"),ga("send","pageview"));
\ No newline at end of file +"document"in self&&("classList"in document.createElement("_")?!function(){"use strict";var e=document.createElement("_");if(e.classList.add("c1","c2"),!e.classList.contains("c2")){var t=function(e){var t=DOMTokenList.prototype[e];DOMTokenList.prototype[e]=function(e){var i,n=arguments.length;for(i=0;i<n;i++)e=arguments[i],t.call(this,e)}};t("add"),t("remove")}if(e.classList.toggle("c3",!1),e.classList.contains("c3")){var i=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(e,t){return 1 in arguments&&!this.contains(e)==!t?t:i.call(this,e)}}e=null}():!function(e){"use strict";if("Element"in e){var t="classList",i="prototype",n=e.Element[i],o=Object,r=String[i].trim||function(){return this.replace(/^\s+|\s+$/g,"")},s=Array[i].indexOf||function(e){for(var t=0,i=this.length;t<i;t++)if(t in this&&this[t]===e)return t;return-1},a=function(e,t){this.name=e,this.code=DOMException[e],this.message=t},c=function(e,t){if(""===t)throw new a("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(t))throw new a("INVALID_CHARACTER_ERR","String contains an invalid character");return s.call(e,t)},l=function(e){for(var t=r.call(e.getAttribute("class")||""),i=t?t.split(/\s+/):[],n=0,o=i.length;n<o;n++)this.push(i[n]);this._updateClassName=function(){e.setAttribute("class",this.toString())}},u=l[i]=[],d=function(){return new l(this)};if(a[i]=Error[i],u.item=function(e){return this[e]||null},u.contains=function(e){return e+="",c(this,e)!==-1},u.add=function(){var e,t=arguments,i=0,n=t.length,o=!1;do e=t[i]+"",c(this,e)===-1&&(this.push(e),o=!0);while(++i<n);o&&this._updateClassName()},u.remove=function(){var e,t,i=arguments,n=0,o=i.length,r=!1;do for(e=i[n]+"",t=c(this,e);t!==-1;)this.splice(t,1),r=!0,t=c(this,e);while(++n<o);r&&this._updateClassName()},u.toggle=function(e,t){e+="";var i=this.contains(e),n=i?t!==!0&&"remove":t!==!1&&"add";return n&&this[n](e),t===!0||t===!1?t:!i},u.toString=function(){return this.join(" ")},o.defineProperty){var p={get:d,enumerable:!0,configurable:!0};try{o.defineProperty(n,t,p)}catch(e){e.number===-2146823252&&(p.enumerable=!1,o.defineProperty(n,t,p))}}else o[i].__defineGetter__&&n.__defineGetter__(t,d)}}(self)),function(){window.loadSprite=function(e,t){function i(e,t){e.innerHTML=t,n.insertBefore(e,n.childNodes[0])}if("string"==typeof e){var n=document.body,o="cache-",r="string"==typeof t,s=!1,a=function(){if(!r)return!1;var e="___test";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}}();if(!r||0===document.querySelectorAll("#"+t).length){var c=document.createElement("div");if(c.setAttribute("hidden",""),r&&c.setAttribute("id",t),a){var l=localStorage.getItem(o+t);if(s=null!==l){var u=JSON.parse(l);i(c,u.content)}}var d=new XMLHttpRequest;if(!("withCredentials"in d))return;d.open("GET",e,!0),d.onload=function(){a&&localStorage.setItem(o+t,JSON.stringify({content:d.responseText})),i(c,d.responseText)},d.send()}}}}(),function(){function e(e,t,i){if(e)if(e.classList)e.classList[i?"add":"remove"](t);else{var n=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=n+(i?" "+t:"")}}function t(t,s){if(t in o&&(s||t!==r)&&(r.length||t!==o.video)){switch(t){case o.video:i.source({type:"video",title:"View From A Blue Moon",sources:[{src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.mp4",type:"video/mp4"}],poster:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.jpg",tracks:[{kind:"captions",label:"English",srclang:"en",src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.en.vtt",default:!0}]});break;case o.audio:i.source({type:"audio",title:"Kishi Bashi – “It All Began With A Burst”",sources:[{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3",type:"audio/mp3"},{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg",type:"audio/ogg"}]});break;case o.youtube:i.source({type:"video",title:"View From A Blue Moon",sources:[{src:"https://www.youtube.com/watch?v=bTqVqk7FSmY",type:"youtube"}]});break;case o.vimeo:i.source({type:"video",title:"View From A Blue Moon",sources:[{src:"https://vimeo.com/76979871",type:"vimeo"}]})}r=t;for(var a=n.length-1;a>=0;a--)e(n[a].parentElement,"active",!1);e(document.querySelector('[data-source="'+t+'"]').parentElement,"active",!0)}}document.body.addEventListener("ready",function(e){console.log(e)});var i=new Plyr("#player",{debug:!0,title:"View From A Blue Moon",iconUrl:"../dist/plyr.svg",tooltips:{controls:!0},captions:{defaultActive:!0},controls:["play-large","play","progress","current-time","mute","volume","captions","settings","fullscreen","pip","airplay"]});window.loadSprite("dist/demo.svg","demo-sprite");var n=document.querySelectorAll("[data-source]"),o={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},r=window.location.hash.replace("#",""),s=window.history&&window.history.pushState;if([].forEach.call(n,function(e){e.addEventListener("click",function(){var e=this.getAttribute("data-source");t(e),s&&history.pushState({type:e},"","#"+e)})}),window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&t(e.state.type)}),s){var a=!r.length;a&&(r=o.video),r in o&&history.replaceState({type:r},"",a?"":"#"+r),r!==o.video&&t(r,!0)}}(),document.domain.indexOf("plyr.io")>-1&&(!function(e,t,i,n,o,r,s){e.GoogleAnalyticsObject=o,e[o]=e[o]||function(){(e[o].q=e[o].q||[]).push(arguments)},e[o].l=1*new Date,r=t.createElement(i),s=t.getElementsByTagName(i)[0],r.async=1,r.src=n,s.parentNode.insertBefore(r,s)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),window.ga("create","UA-40881672-11","auto"),window.ga("send","pageview"));
\ No newline at end of file diff --git a/demo/index.html b/demo/index.html index 483e0db6..9877cf3c 100644 --- a/demo/index.html +++ b/demo/index.html @@ -51,7 +51,7 @@ </ul> </nav> <section> - <video poster="https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.jpg" controls crossorigin playsinline> + <video controls crossorigin playsinline poster="https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.jpg" id="player"> <!-- Video files --> <source src="https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.mp4" type="video/mp4"> diff --git a/demo/src/js/lib/sprite.js b/demo/src/js/lib/sprite.js new file mode 100644 index 00000000..bcd8a0b7 --- /dev/null +++ b/demo/src/js/lib/sprite.js @@ -0,0 +1,89 @@ +// ========================================================================== +// SVG sprite loading and caching +// This file should be at the top of the body to avoid a flash +// Usage: loadSprite('https://cdn.com/path/to/sprite.svg', 'sprite-id'); +// The second argument is optional but prevents loading twice +// ========================================================================== + +(function() { + window.loadSprite = function(url, id) { + if (typeof url !== "string") { + return; + } + + var body = document.body; + var prefix = "cache-"; + var hasId = typeof id === "string"; + var isCached = false; + + // Check for *actual* storage support + var cacheSupported = (function() { + if (!hasId) { + return false; + } + var test = '___test'; + try { + localStorage.setItem(test, test); + localStorage.removeItem(test); + return true; + } catch (e) { + return false; + } + })(); + + function updateSprite(container, data) { + // Inject content + container.innerHTML = data; + + // Inject the SVG to the body + body.insertBefore(container, body.childNodes[0]); + } + + // Only load once + if (!hasId || document.querySelectorAll("#" + id).length === 0) { + // Create container + var container = document.createElement("div"); + container.setAttribute("hidden", ""); + + if (hasId) { + container.setAttribute("id", id); + } + + // Check in cache + if (cacheSupported) { + var cached = localStorage.getItem(prefix + id); + isCached = cached !== null; + + if (isCached) { + var data = JSON.parse(cached); + updateSprite(container, data.content); + } + } + + // ReSharper disable once InconsistentNaming + var xhr = new XMLHttpRequest(); + + // XHR for Chrome/Firefox/Opera/Safari + if ("withCredentials" in xhr) { + xhr.open("GET", url, true); + } + // Not supported + else { + return; + } + + // Once loaded, inject to container and body + xhr.onload = function() { + if (cacheSupported) { + localStorage.setItem(prefix + id, JSON.stringify({ + content: xhr.responseText + })); + } + + updateSprite(container, xhr.responseText); + }; + + xhr.send(); + } + } +})(); diff --git a/demo/src/js/main.js b/demo/src/js/main.js index b3b6f517..b5d5ad15 100644 --- a/demo/src/js/main.js +++ b/demo/src/js/main.js @@ -4,16 +4,18 @@ // Please see readme.md in the root or github.com/selz/plyr // ========================================================================== -/*global plyr*/ +/*global Plyr*/ // General functions (function() { - //document.body.addEventListener('ready', function(event) { console.log(event); }); + document.body.addEventListener('ready', function(event) { + console.log(event); + }); // Setup the player - var instances = plyr.setup({ + var player = new Plyr('#player', { debug: true, - title: 'Video demo', + title: 'View From A Blue Moon', iconUrl: '../dist/plyr.svg', tooltips: { controls: true @@ -35,25 +37,22 @@ 'airplay' ] }); - plyr.loadSprite('dist/demo.svg'); - - // Plyr returns an array regardless - var player = instances[0]; + window.loadSprite('dist/demo.svg', 'demo-sprite'); // Setup type toggle - var buttons = document.querySelectorAll('[data-source]'), - types = { - video: 'video', - audio: 'audio', - youtube: 'youtube', - vimeo: 'vimeo' - }, - currentType = window.location.hash.replace('#', ''), - historySupport = (window.history && window.history.pushState); + var buttons = document.querySelectorAll('[data-source]'); + var types = { + video: 'video', + audio: 'audio', + youtube: 'youtube', + vimeo: 'vimeo' + }; + var currentType = window.location.hash.replace('#', ''); + var historySupport = (window.history && window.history.pushState); // Bind to each button - for (var i = buttons.length - 1; i >= 0; i--) { - buttons[i].addEventListener('click', function() { + [].forEach.call(buttons, function(button) { + button.addEventListener('click', function() { var type = this.getAttribute('data-source'); newSource(type); @@ -64,7 +63,7 @@ }, '', '#' + type); } }); - } + }); // List for backwards/forwards window.addEventListener('popstate', function(event) { @@ -199,6 +198,6 @@ if (document.domain.indexOf('plyr.io') > -1) { a.src = g; m.parentNode.insertBefore(a, m) })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga'); - ga('create', 'UA-40881672-11', 'auto'); - ga('send', 'pageview'); + window.ga('create', 'UA-40881672-11', 'auto'); + window.ga('send', 'pageview'); } diff --git a/dist/plyr.js b/dist/plyr.js index 440e7b8e..569d3673 100644 --- a/dist/plyr.js +++ b/dist/plyr.js @@ -1,2 +1,2 @@ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=t(e,document):"function"==typeof define&&define.amd?define([],function(){return t(e,document)}):e.plyr=t(e,document)}("undefined"!=typeof window?window:this,function(e,t){"use strict";function n(n,s){function f(e,t,n,a){d.event(e,t,n,d.extend({},a,{plyr:De}))}function y(e){return Re.elements.container.querySelectorAll(e)}function g(e){return y(e)[0]}function b(e){c.string(e)?(d.removeElement(Re.elements[e]),Re.elements[e]=null):d.removeElement(e)}function v(){function e(e){9===e.which&&Re.fullscreen.active&&(e.target!==a||e.shiftKey?e.target===n&&e.shiftKey&&(e.preventDefault(),a.focus()):(e.preventDefault(),n.focus()))}var t=y("input:not([disabled]), button:not([disabled])"),n=t[0],a=t[t.length-1];d.on(Re.elements.container,"keydown",e,!1)}function h(e,t){c.string(t)?d.insertElement(e,Re.elements.media,{src:t}):c.array(t)&&t.forEach(function(t){d.insertElement(e,Re.elements.media,t)})}function k(){return{url:s.iconUrl,absolute:0===s.iconUrl.indexOf("http")||Re.browser.isIE}}function C(e,n){var a="http://www.w3.org/2000/svg",l=k(),r=(l.absolute?"":l.url)+"#"+s.iconPrefix,i=t.createElementNS(a,"svg");d.setAttributes(i,d.extend(n,{role:"presentation"}));var o=t.createElementNS(a,"use");return o.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",r+"-"+e),i.appendChild(o),i}function E(e){var t=s.i18n[e];switch(e){case"pip":t="PIP";break;case"airplay":t="AirPlay"}return d.createElement("span",{class:s.classes.hidden},t)}function A(e){var t=d.createElement("span",{class:s.classes.menu.value});return t.appendChild(d.createElement("span",{class:s.classes.menu.badge},e)),t}function w(e,t){var n,a,l,r=d.createElement("button");switch(c.object(t)||(t={}),"class"in t?t.class.indexOf(s.classes.control)===-1&&(t.class+=" "+s.classes.control):t.class=s.classes.control,e){case"mute":l="toggleMute",n="volume",a="muted";break;case"captions":l="toggleCaptions",n="captions-off",a="captions-on";break;case"fullscreen":l="toggleFullscreen",n="enter-fullscreen",a="exit-fullscreen";break;case"play-large":t.class="plyr__play-large",e="play",l="play",n="play";break;default:l=e,n=e}return d.extend(t,d.getAttributesFromSelector(s.selectors.buttons[e],t)),c.string(a)&&r.appendChild(C(a,{class:"icon--"+a})),r.appendChild(C(n)),r.appendChild(E(l)),d.setAttributes(r,t),Re.elements.buttons[e]=r,r}function S(e,t){var n=d.createElement("label",{for:t.id,class:s.classes.hidden},s.i18n[e]),a=d.createElement("input",d.extend(d.getAttributesFromSelector(s.selectors.inputs[e]),{type:"range",min:0,max:100,step:.1,value:0,autocomplete:"off"},t));return Re.elements.inputs[e]=a,{label:n,input:a}}function T(e,t){var n=d.createElement("progress",d.extend(d.getAttributesFromSelector(s.selectors.display[e]),{min:0,max:100,value:0},t));if("volume"!==e){n.appendChild(d.createElement("span",null,"0"));var a="";switch(e){case"played":a=s.i18n.played;break;case"buffer":a=s.i18n.buffered}n.textContent="% "+a.toLowerCase()}return Re.elements.display[e]=n,n}function x(e){var t=d.createElement("span",{class:"plyr__time"});return t.appendChild(d.createElement("span",{class:s.classes.hidden},s.i18n[e])),t.appendChild(d.createElement("span",d.getAttributesFromSelector(s.selectors.display[e]),"00:00")),Re.elements.display[e]=t,t}function F(e){var t=d.createElement("div",d.getAttributesFromSelector(s.selectors.controls.wrapper));if(d.inArray(s.controls,"restart")&&t.appendChild(w("restart")),d.inArray(s.controls,"rewind")&&t.appendChild(w("rewind")),d.inArray(s.controls,"play")&&(t.appendChild(w("play")),t.appendChild(w("pause"))),d.inArray(s.controls,"fast-forward")&&t.appendChild(w("fast-forward")),d.inArray(s.controls,"progress")){var n=d.createElement("span",d.getAttributesFromSelector(s.selectors.progress)),a=S("seek",{id:"plyr-seek-"+e.id});if(n.appendChild(a.label),n.appendChild(a.input),n.appendChild(T("played")),n.appendChild(T("buffer")),s.tooltips.seek){var l=d.createElement("span",{role:"tooltip",class:s.classes.tooltip},"00:00");n.appendChild(l),Re.elements.display.seekTooltip=l}Re.elements.progress=n,t.appendChild(Re.elements.progress)}if(d.inArray(s.controls,"current-time")&&t.appendChild(x("currentTime")),d.inArray(s.controls,"duration")&&t.appendChild(x("duration")),d.inArray(s.controls,"mute")&&t.appendChild(w("mute")),d.inArray(s.controls,"volume")){var r=d.createElement("span",{class:"plyr__volume"}),i={max:10,value:s.volume},o=S("volume",d.extend(i,{id:"plyr-volume-"+e.id}));r.appendChild(o.label),r.appendChild(o.input);var u=T("volume",i);r.appendChild(u),t.appendChild(r)}if(d.inArray(s.controls,"captions")&&t.appendChild(w("captions")),d.inArray(s.controls,"settings")){var c=d.createElement("span",d.extend(d.getAttributesFromSelector(s.selectors.buttons.settings),{class:"plyr__menu"}));c.appendChild(w("settings",{id:"plyr-settings-toggle-"+e.id,"aria-haspopup":!0,"aria-controls":"plyr-settings-"+e.id,"aria-expanded":!1}));var p=d.createElement("form",{class:"plyr__menu__container",id:"plyr-settings-"+e.id,"aria-hidden":!0,"aria-labelled-by":"plyr-settings-toggle-"+e.id,role:"tablist",tabindex:-1}),f=d.createElement("div"),y=d.createElement("div",{id:"plyr-settings-"+e.id+"-home","aria-hidden":!1,"aria-labelled-by":"plyr-settings-toggle-"+e.id,role:"tabpanel"}),g=d.createElement("ul",{role:"tablist"});["captions","quality","speed","loop"].forEach(function(t){var n=d.createElement("li",{role:"tab"}),a=d.createElement("button",d.extend(d.getAttributesFromSelector(s.selectors.buttons.settings),{type:"button",class:s.classes.control+" "+s.classes.control+"--forward",id:"plyr-settings-"+e.id+"-"+t+"-tab","aria-haspopup":!0,"aria-controls":"plyr-settings-"+e.id+"-"+t,"aria-expanded":!1}),s.i18n[t]),l=d.createElement("span",{class:s.classes.menu.value});l.innerHTML=e[t],a.appendChild(l),n.appendChild(a),g.appendChild(n),Re.elements.settings.tabs[t]=n}),y.appendChild(g),f.appendChild(y),["captions","quality","speed","loop"].forEach(function(t){var n=d.createElement("div",{id:"plyr-settings-"+e.id+"-"+t,"aria-hidden":!0,"aria-labelled-by":"plyr-settings-"+e.id+"-"+t+"-tab",role:"tabpanel",tabindex:-1}),a=d.createElement("button",{type:"button",class:s.classes.control+" "+s.classes.control+"--back","aria-haspopup":!0,"aria-controls":"plyr-settings-"+e.id+"-home","aria-expanded":!1},s.i18n[t]);n.appendChild(a);var l=d.createElement("ul");n.appendChild(l),f.appendChild(n),Re.elements.settings.panes[t]=n}),p.appendChild(f),c.appendChild(p),t.appendChild(c),Re.elements.settings.menu=c}return d.inArray(s.controls,"pip")&&m.pip&&t.appendChild(w("pip")),d.inArray(s.controls,"airplay")&&m.airplay&&t.appendChild(w("airplay")),d.inArray(s.controls,"fullscreen")&&t.appendChild(w("fullscreen")),Re.elements.controls=t,P(),N(),t}function _(e,n){function a(e){var t="";switch(e){case"hd2160":t="4K";break;case"hd1440":t="WQHD";break;case"hd1080":t="HD";break;case"hd720":t="HD"}return t.length?A(t):null}function l(e){switch(e){case"hd2160":return"2160P";case"hd1440":return"1440P";case"hd1080":return"1080P";case"hd720":return"720P";case"large":return"480P";case"medium":return"360P";case"small":return"240P";default:return"Auto"}}var r=Re.elements.settings.panes.quality.querySelector("ul");d.emptyElement(r),c.array(e)&&!c.empty(e)&&e.filter(function(e){return!d.inArray(["tiny","small"],e)}).forEach(function(e){var n=d.createElement("li"),i=d.createElement("label",{class:s.classes.control,for:"plyr-quality-"+e}),o=d.createElement("input",d.extend(d.getAttributesFromSelector(s.selectors.inputs.quality),{type:"radio",id:"plyr-quality-"+e,name:"plyr-quality",value:e}));e===s.quality.selected&&o.setAttribute("checked",""),i.appendChild(o),i.appendChild(t.createTextNode(l(e)));var u=a(e);c.htmlElement(u)&&i.appendChild(u),n.appendChild(i),r.appendChild(n)})}function P(){var e=["start","end","all","reset"],t=Re.elements.settings.panes.loop.querySelector("ul");d.emptyElement(t),e.forEach(function(e){var n=d.createElement("li"),a=d.createElement("button",d.extend(d.getAttributesFromSelector(s.selectors.buttons.loop),{type:"button",class:s.classes.control,"data-plyr-loop-action":e}),s.i18n[e]);if(d.inArray(["start","end"],e)){var l=A("0:00");a.appendChild(l)}n.appendChild(a),t.appendChild(n)})}function I(){var e=Re.elements.settings.panes.captions.querySelector("ul");if(d.emptyElement(e),!c.empty(Re.captions.tracks)){var n=[].map.call(Re.captions.tracks,function(e){return{language:e.language,badge:!0,label:c.empty(e.label)?e.language.toUpperCase():e.label}});n.unshift({language:"off",label:s.i18n.none}),n.forEach(function(n){var a=d.createElement("li"),l=d.createElement("label",{class:s.classes.control,for:"plyr-language-"+n.language}),r=d.createElement("input",d.extend(d.getAttributesFromSelector(s.selectors.inputs.language),{type:"radio",id:"plyr-language-"+n.language,name:"plyr-language",value:n.language}));n.language===s.captions.language.toLowerCase()&&r.setAttribute("checked",""),l.appendChild(r),l.appendChild(t.createTextNode(n.label||n.language)),n.badge&&l.appendChild(A(n.language.toUpperCase())),a.appendChild(l),e.appendChild(a)})}}function N(e){var t=Re.elements.settings.panes.speed.querySelector("ul");d.emptyElement(t),c.array(e)||(e=s.speed.options),e.forEach(function(e){var n=d.createElement("li"),a=d.createElement("label",{class:s.classes.control,for:"plyr-speed-"+e.toString().replace(".","-")}),l=d.createElement("input",d.extend(d.getAttributesFromSelector(s.selectors.inputs.speed),{type:"radio",id:"plyr-speed-"+e.toString().replace(".","-"),name:"plyr-speed",value:e}));e===s.speed.selected&&l.setAttribute("checked",""),a.appendChild(l),a.insertAdjacentHTML("beforeend","×"+e),n.appendChild(a),t.appendChild(n)})}function L(){if(Re.supported.full&&("audio"!==Re.type||s.fullscreen.allowAudio)&&s.fullscreen.enabled){var e=m.fullscreen;e||s.fullscreen.fallback&&!d.inFrame()?(We((e?"Native":"Fallback")+" fullscreen enabled"),d.toggleClass(Re.elements.container,s.classes.fullscreen.enabled,!0)):We("Fullscreen not supported and fallback disabled"),Re.elements.buttons&&Re.elements.buttons.fullscreen&&d.toggleState(Re.elements.buttons.fullscreen,!1),v()}}function q(e){if(d.inArray(["video","vimeo"],Re.type)&&("video"!==Re.type||m.textTracks)&&(c.htmlElement(Re.elements.captions)||(Re.elements.captions=d.createElement("div",d.getAttributesFromSelector(s.selectors.captions)),d.insertAfter(Re.elements.captions,Re.elements.wrapper)),Re.captions.tracks=c.array(e)?e:Re.elements.media.textTracks,d.toggleClass(Re.elements.container,s.classes.captions.enabled,!c.empty(Re.captions.tracks)),!c.empty(Re.captions.tracks))){if(D(),"video"===Re.type){var t=s.captions.language.toLowerCase();[].forEach.call(Re.captions.tracks,function(e){d.off(e,"cuechange",j),e.mode="hidden",e.language===t&&(Re.captions.currentTrack=e)}),c.track(Re.captions.currentTrack)||(Ye("No language found to match "+t+" in tracks"),Re.captions.currentTrack=Re.captions.tracks[0]);var n=Re.captions.currentTrack;c.track(n)&&d.inArray(["captions","subtitles"],n.kind)&&(d.on(n,"cuechange",j),n.activeCues&&n.activeCues.length>0&&j(n))}I()}}function O(){return!m.textTracks||c.empty(Re.captions.tracks)?"No Subs":Re.captions.enabled?Re.captions.currentTrack.label:"Disabled"}function j(e){c.event(e)&&(e=e.target);var t=e.activeCues[0];c.cue(t)?V(t.getCueAsHTML()):V()}function M(e){c.string(e)?s.captions.language=e.toLowerCase():c.event(e)&&(s.captions.language=e.target.value.toLowerCase()),V(),q()}function V(e){if(c.htmlElement(Re.elements.captions)){var t=d.createElement("span");d.emptyElement(Re.elements.captions),c.undefined(e)&&(e=""),c.string(e)?t.textContent=e.trim():t.appendChild(e),Re.elements.captions.appendChild(t)}else Ye("No captions element to render to")}function D(){if(Re.elements.buttons.captions){var e=Re.storage.captions;c.boolean(e)?s.captions.active=e:e=s.captions.active,e&&(d.toggleClass(Re.elements.container,s.classes.captions.active,!0),d.toggleState(Re.elements.buttons.captions,!0))}}function R(e){Re.supported.full&&Re.elements.buttons.captions&&(c.boolean(e)||(e=Re.elements.container.className.indexOf(s.classes.captions.active)===-1),Re.captions.enabled=e,d.toggleState(Re.elements.buttons.captions,Re.captions.enabled),d.toggleClass(Re.elements.container,s.classes.captions.active,Re.captions.enabled),f(Re.elements.container,Re.captions.enabled?"captionsenabled":"captionsdisabled",!0),Q({captions:Re.captions.enabled}))}function B(){if(s.loadSprite){var e=k();e.absolute?(We("AJAX loading absolute SVG sprite"+(Re.browser.isIE?" (due to IE)":"")),a(e.url,"sprite-plyr")):We("Sprite will be used as external resource directly")}d.inArray(s.controls,"play-large")&&(Re.elements.buttons.playLarge=w("play-large"),Re.elements.container.appendChild(Re.elements.buttons.playLarge)),Re.id=Math.floor(1e4*Math.random());var n=null;n=c.string(s.controls)?s.controls:c.function(s.controls)?s.controls({id:Re.id,seektime:s.seekTime}):F({id:Re.id,seektime:s.seekTime,speed:se(),quality:"HD",captions:O(),loop:"None"});var l;if(c.string(s.selectors.controls.container)&&(l=t.querySelector(s.selectors.controls.container)),c.htmlElement(l)||(l=Re.elements.container),c.htmlElement(n)?l.appendChild(n):l.insertAdjacentHTML("beforeend",n),c.htmlElement(Re.elements.controls)&&H(),s.tooltips.controls)for(var r=y([s.selectors.controls.wrapper," ",s.selectors.labels," .",s.classes.hidden].join("")),i=r.length-1;i>=0;i--){var o=r[i];d.toggleClass(o,s.classes.hidden,!1),d.toggleClass(o,s.classes.tooltip,!0)}}function H(){try{return Re.elements.controls=g(s.selectors.controls.wrapper),Re.elements.buttons={play:y(s.selectors.buttons.play),pause:g(s.selectors.buttons.pause),restart:g(s.selectors.buttons.restart),rewind:g(s.selectors.buttons.rewind),forward:g(s.selectors.buttons.forward),mute:g(s.selectors.buttons.mute),pip:g(s.selectors.buttons.pip),airplay:g(s.selectors.buttons.airplay),settings:g(s.selectors.buttons.settings),captions:g(s.selectors.buttons.captions),fullscreen:g(s.selectors.buttons.fullscreen)},Re.elements.progress=g(s.selectors.progress),Re.elements.inputs={seek:g(s.selectors.inputs.seek),volume:g(s.selectors.inputs.volume)},Re.elements.display={buffer:g(s.selectors.display.buffer),played:g(s.selectors.display.played),volume:g(s.selectors.display.volume),duration:g(s.selectors.display.duration),currentTime:g(s.selectors.display.currentTime)},c.htmlElement(Re.elements.progress)&&(Re.elements.display.seekTooltip=Re.elements.progress.querySelector("."+s.classes.tooltip)),!0}catch(e){return Ye("It looks like there is a problem with your custom controls HTML",e),Y(!0),!1}}function W(){d.toggleClass(Re.elements.container,s.selectors.container.replace(".",""),Re.supported.full)}function Y(e){e&&d.inArray(u.html5,Re.type)?Re.elements.media.setAttribute("controls",""):Re.elements.media.removeAttribute("controls")}function U(e){var t=s.i18n.play;if(c.string(s.title)&&!c.empty(s.title)&&(t+=", "+s.title,Re.elements.container.setAttribute("aria-label",s.title)),Re.supported.full&&(c.htmlElement(Re.elements.buttons.play)&&Re.elements.buttons.play.setAttribute("aria-label",t),c.htmlElement(Re.elements.buttons.playLarge)&&Re.elements.buttons.playLarge.setAttribute("aria-label",t)),c.htmlElement(e)){var n=c.string(s.title)&&!c.empty(s.title)?s.title:"video";e.setAttribute("title",s.i18n.frameTitle.replace("{title}",n))}}function K(){var t=null;Re.storage={},m.storage&&s.storage.enabled&&(e.localStorage.removeItem("plyr-volume"),t=e.localStorage.getItem(s.storage.key),t&&(/^\d+(\.\d+)?$/.test(t)?Q({volume:parseFloat(t)}):Re.storage=JSON.parse(t)))}function Q(t){m.storage&&s.storage.enabled&&(d.extend(Re.storage,t),e.localStorage.setItem(s.storage.key,JSON.stringify(Re.storage)))}function X(){return Re.elements.media?(Re.supported.full&&(d.toggleClass(Re.elements.container,s.classes.type.replace("{0}",Re.type),!0),d.inArray(u.embed,Re.type)&&d.toggleClass(Re.elements.container,s.classes.type.replace("{0}","video"),!0),d.toggleClass(Re.elements.container,s.classes.pip.enabled,m.pip&&"video"===Re.type),d.toggleClass(Re.elements.container,s.classes.airplay.enabled,m.airplay&&d.inArray(u.html5,Re.type)),d.toggleClass(Re.elements.container,s.classes.stopped,s.autoplay),d.toggleClass(Re.elements.container,s.classes.isIos,Re.browser.isIos),d.toggleClass(Re.elements.container,s.classes.isTouch,m.touch)),d.inArray(["video","youtube","vimeo"],Re.type)&&(Re.elements.wrapper=d.createElement("div",{class:s.classes.videoWrapper}),d.wrap(Re.elements.media,Re.elements.wrapper)),void(d.inArray(u.embed,Re.type)&&z())):void Ye("No media element found!")}function z(){var t,n=Re.type+"-"+Math.floor(1e4*Math.random());switch(Re.type){case"youtube":t=d.parseYouTubeId(Re.embedId);break;default:t=Re.embedId}for(var a=y('[id^="'+Re.type+'-"]'),l=a.length-1;l>=0;l--)d.removeElement(a[l]);if(d.toggleClass(Re.elements.wrapper,s.classes.embedWrapper,!0),"youtube"===Re.type)Re.elements.media.setAttribute("id",n),c.object(e.YT)?G(t):(d.injectScript(s.urls.youtube.api),e.onYouTubeReadyCallbacks=e.onYouTubeReadyCallbacks||[],e.onYouTubeReadyCallbacks.push(function(){G(t)}),e.onYouTubeIframeAPIReady=function(){e.onYouTubeReadyCallbacks.forEach(function(e){e()})});else if("vimeo"===Re.type)if(Re.elements.media.setAttribute("id",n),c.object(e.Vimeo))J(t);else{d.injectScript(s.urls.vimeo.api);var r=e.setInterval(function(){c.object(e.Vimeo)&&(e.clearInterval(r),J(t))},50)}else if("soundcloud"===Re.type){var i=d.createElement("iframe");i.loaded=!1,d.on(i,"load",function(){i.loaded=!0}),d.setAttributes(i,{src:"https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/"+t,id:n}),Re.elements.media.appendChild(i),e.SC||d.injectScript(s.urls.soundcloud.api);var o=e.setInterval(function(){e.SC&&i.loaded&&(e.clearInterval(o),Z.call(i))},50)}}function $(){Re.supported.full&&(Me(),Ve()),U(g("iframe"))}function G(t){Re.embed=new e.YT.Player(Re.elements.media.id,{videoId:t,playerVars:{autoplay:s.autoplay?1:0,controls:Re.supported.full?0:1,rel:0,showinfo:0,iv_load_policy:3,cc_load_policy:s.captions.active?1:0,cc_lang_pref:"en",wmode:"transparent",modestbranding:1,disablekb:1,playsinline:1,origin:e.location.href},events:{onError:function(e){f(Re.elements.container,"error",!0,{code:e.data,embed:e.target})},onPlaybackQualityChange:function(e){var t=e.target,n=t.getPlaybackQuality();console.warn(n)},onReady:function(t){var n=t.target;Re.elements.media.play=function(){n.playVideo(),Re.elements.media.paused=!1},Re.elements.media.pause=function(){n.pauseVideo(),Re.elements.media.paused=!0},Re.elements.media.stop=function(){n.stopVideo(),Re.elements.media.paused=!0},Re.elements.media.duration=n.getDuration(),Re.elements.media.paused=!0,Re.elements.media.currentTime=0,Re.elements.media.muted=n.isMuted();var a=n.getPlaybackRate(),l=n.getAvailablePlaybackRates();console.warn(a,l),s.title=n.getVideoData().title,Re.supported.full&&Re.elements.media.setAttribute("tabindex",-1),$(),f(Re.elements.media,"timeupdate"),f(Re.elements.media,"durationchange"),e.clearInterval(Be.buffering),Be.buffering=e.setInterval(function(){Re.elements.media.buffered=n.getVideoLoadedFraction(),(null===Re.elements.media.lastBuffered||Re.elements.media.lastBuffered<Re.elements.media.buffered)&&f(Re.elements.media,"progress"),Re.elements.media.lastBuffered=Re.elements.media.buffered,1===Re.elements.media.buffered&&(e.clearInterval(Be.buffering),f(Re.elements.media,"canplaythrough"))},200)},onStateChange:function(t){var n=t.target;switch(e.clearInterval(Be.playing),t.data){case 0:if(s.loop.active){n.stopVideo(),n.playVideo();break}Re.elements.media.paused=!0,f(Re.elements.media,"ended");break;case 1:Re.elements.media.paused=!1,Re.elements.media.seeking&&f(Re.elements.media,"seeked"),Re.elements.media.seeking=!1,f(Re.elements.media,"play"),f(Re.elements.media,"playing"),Be.playing=e.setInterval(function(){Re.elements.media.currentTime=n.getCurrentTime(),f(Re.elements.media,"timeupdate")},100),Re.elements.media.duration!==n.getDuration()&&(Re.elements.media.duration=n.getDuration(),f(Re.elements.media,"durationchange"));var a=n.getAvailableQualityLevels(),l=n.getPlaybackQuality();_(a,l);break;case 2:Re.elements.media.paused=!0,f(Re.elements.media,"pause")}f(Re.elements.container,"statechange",!1,{code:t.data})}}})}function J(t){Re.embed=new e.Vimeo.Player(Re.elements.media,{id:t,loop:s.loop.active,autoplay:s.autoplay,byline:!1,portrait:!1,title:!1}),Re.elements.media.play=function(){Re.embed.play(),Re.elements.media.paused=!1},Re.elements.media.pause=function(){Re.embed.pause(),Re.elements.media.paused=!0},Re.elements.media.stop=function(){Re.embed.stop(),Re.elements.media.paused=!0},Re.elements.media.paused=!0,Re.elements.media.currentTime=0,$(),Re.embed.getCurrentTime().then(function(e){Re.elements.media.currentTime=e,f(Re.elements.media,"timeupdate")}),Re.embed.getDuration().then(function(e){Re.elements.media.duration=e,f(Re.elements.media,"durationchange")}),Re.embed.getTextTracks().then(function(e){q(e),s.captions.active&&Re.embed.enableTextTrack(s.captions.language.toLowerCase())}),Re.embed.on("cuechange",function(e){var t=null;e.cues.length&&(t=d.stripHTML(e.cues[0].text)),V(t)}),Re.embed.on("loaded",function(){c.htmlElement(Re.embed.element)&&Re.supported.full&&Re.embed.element.setAttribute("tabindex",-1)}),Re.embed.on("play",function(){Re.elements.media.paused=!1,f(Re.elements.media,"play"),f(Re.elements.media,"playing")}),Re.embed.on("pause",function(){Re.elements.media.paused=!0,f(Re.elements.media,"pause")}),Re.embed.on("timeupdate",function(e){Re.elements.media.seeking=!1,Re.elements.media.currentTime=e.seconds,f(Re.elements.media,"timeupdate")}),Re.embed.on("progress",function(e){Re.elements.media.buffered=e.percent,f(Re.elements.media,"progress"),1===parseInt(e.percent)&&f(Re.elements.media,"canplaythrough")}),Re.embed.on("seeked",function(){Re.elements.media.seeking=!1,f(Re.elements.media,"seeked"),f(Re.elements.media,"play")}),Re.embed.on("ended",function(){Re.elements.media.paused=!0,f(Re.elements.media,"ended")})}function Z(){Re.embed=e.SC.Widget(this),Re.embed.bind(e.SC.Widget.Events.READY,function(){Re.elements.media.play=function(){Re.embed.play(),Re.elements.media.paused=!1},Re.elements.media.pause=function(){Re.embed.pause(),Re.elements.media.paused=!0},Re.elements.media.stop=function(){Re.embed.seekTo(0),Re.embed.pause(),Re.elements.media.paused=!0},Re.elements.media.paused=!0,Re.elements.media.currentTime=0,Re.embed.getDuration(function(e){Re.elements.media.duration=e/1e3,$()}),Re.embed.getPosition(function(e){Re.elements.media.currentTime=e,f(Re.elements.media,"timeupdate")}),Re.embed.bind(e.SC.Widget.Events.PLAY,function(){Re.elements.media.paused=!1,f(Re.elements.media,"play"),f(Re.elements.media,"playing")}),Re.embed.bind(e.SC.Widget.Events.PAUSE,function(){Re.elements.media.paused=!0,f(Re.elements.media,"pause")}),Re.embed.bind(e.SC.Widget.Events.PLAY_PROGRESS,function(e){Re.elements.media.seeking=!1,Re.elements.media.currentTime=e.currentPosition/1e3,f(Re.elements.media,"timeupdate")}),Re.embed.bind(e.SC.Widget.Events.LOAD_PROGRESS,function(e){Re.elements.media.buffered=e.loadProgress,f(Re.elements.media,"progress"),1===parseInt(e.loadProgress)&&f(Re.elements.media,"canplaythrough")}),Re.embed.bind(e.SC.Widget.Events.FINISH,function(){Re.elements.media.paused=!0,f(Re.elements.media,"ended")})})}function ee(){"play"in Re.elements.media&&Re.elements.media.play()}function te(){"pause"in Re.elements.media&&Re.elements.media.pause()}function ne(e){return c.boolean(e)||(e=Re.elements.media.paused),e?ee():te(),e}function ae(e){d.inArray(["start","end","all","none","toggle"],e)||(e="toggle");var n=Number(Re.elements.media.currentTime);switch(e){case"start":s.loop.end&&s.loop.end<=n&&(s.loop.end=null),s.loop.start=n,s.loop.indicator.start=Re.elements.display.played.value;break;case"end":if(s.loop.start>=n)return;s.loop.end=n,s.loop.indicator.end=Re.elements.display.played.value;break;case"all":s.loop.start=0,s.loop.end=Re.elements.media.duration-2,s.loop.indicator.start=0,s.loop.indicator.end=100;break;case"toggle":s.loop.active?(s.loop.start=0,s.loop.end=null):(s.loop.start=0,s.loop.end=Re.elements.media.duration-2);break;default:s.loop.start=0,s.loop.end=null}s.loop.active=c.number(s.loop.start)&&c.number(s.loop.end);var a=(Ae(s.loop.start,g('[data-plyr-loop="start"]')),null);c.number(s.loop.end)&&(a=Ae(s.loop.end,t.querySelector('[data-loop__value="loopout"]'))),s.loop.active}function le(e){return c.event(e)?e=parseFloat(e.target.value):c.number(e)||(e=parseFloat(Re.storage.speed||s.speed.selected)),e<.1&&(e=.1),e>2&&(e=2),c.array(s.speed.options)?(s.speed.selected=e,Re.elements.media.playbackRate=e,void Q({speed:e})):void Ye("Invalid speeds format")}function se(){return s.speed.selected.toFixed(1).toString().replace(".0","")+"×"}function re(e){c.number(e)||(e=s.seekTime),oe(Re.elements.media.currentTime-e)}function ie(e){c.number(e)||(e=s.seekTime),oe(Re.elements.media.currentTime+e)}function oe(e){var t=0,n=Re.elements.media.paused,a=ue();c.number(e)?t=e:c.event(e)&&d.inArray(["input","change"],e.type)&&(t=e.target.value/e.target.max*a),t<0?t=0:t>a&&(t=a),Te(t);try{Re.elements.media.currentTime=t.toFixed(4)}catch(e){}if(d.inArray(u.embed,Re.type)){switch(Re.type){case"youtube":Re.embed.seekTo(t);break;case"vimeo":Re.embed.setCurrentTime(t.toFixed(0));break;case"soundcloud":Re.embed.seekTo(1e3*t)}n&&te(),f(Re.elements.media,"timeupdate"),Re.elements.media.seeking=!0,f(Re.elements.media,"seeking")}We("Seeking to "+Re.elements.media.currentTime+" seconds")}function ue(){var e=parseInt(s.duration),t=0;return null===Re.elements.media.duration||isNaN(Re.elements.media.duration)||(t=Re.elements.media.duration),isNaN(e)?t:e}function ce(){d.toggleClass(Re.elements.container,s.classes.playing,!Re.elements.media.paused),d.toggleClass(Re.elements.container,s.classes.stopped,Re.elements.media.paused),Fe(Re.elements.media.paused)}function de(){i={x:e.pageXOffset||0,y:e.pageYOffset||0}}function pe(){e.scrollTo(i.x,i.y)}function me(e){var n=m.fullscreen;if(n){if(!e||e.type!==p.eventType)return p.isFullScreen(Re.elements.container)?p.cancelFullScreen():(de(),p.requestFullScreen(Re.elements.container)),void(Re.fullscreen.active=p.isFullScreen(Re.elements.container));Re.fullscreen.active=p.isFullScreen(Re.elements.container)}else Re.fullscreen.active=!Re.fullscreen.active,t.body.style.overflow=Re.fullscreen.active?"hidden":"";d.toggleClass(Re.elements.container,s.classes.fullscreen.active,Re.fullscreen.active),v(Re.fullscreen.active),Re.elements.buttons&&Re.elements.buttons.fullscreen&&d.toggleState(Re.elements.buttons.fullscreen,Re.fullscreen.active),f(Re.elements.container,Re.fullscreen.active?"enterfullscreen":"exitfullscreen",!0),!Re.fullscreen.active&&n&&pe()}function fe(n){var a=Re.elements.settings.menu.parentNode,l=n.target,s=t.getElementById(l.getAttribute("aria-controls")),r="false"===l.getAttribute("aria-expanded");if(c.htmlElement(s)){var i,o,u,p="tabpanel"===s.getAttribute("role");if(p){var m=a.querySelector('[role="tabpanel"][aria-hidden="false"]');u=m.parentNode,[].forEach.call(a.querySelectorAll('[aria-controls="'+m.getAttribute("id")+'"]'),function(e){e.setAttribute("aria-expanded",!1)}),u.style.width=m.scrollWidth+"px",u.style.height=m.scrollHeight+"px",m.setAttribute("aria-hidden",!0),m.setAttribute("tabindex",-1);var f=s.cloneNode(!0);f.style.position="absolute",f.style.opacity=0,f.setAttribute("aria-hidden",!1),u.appendChild(f),i=f.scrollWidth,o=f.scrollHeight,d.removeElement(f)}s.setAttribute("aria-hidden",!r),l.setAttribute("aria-expanded",r),s.removeAttribute("tabindex"),p&&(u.style.width=i+"px",u.style.height=o+"px",e.setTimeout(function(){u.style.width="",u.style.height=""},300))}}function ye(e){if(c.boolean(e)||(e=!Re.elements.media.muted),d.toggleState(Re.elements.buttons.mute,e),Re.elements.media.muted=e,0===Re.elements.media.volume&&ge(s.volume),d.inArray(u.embed,Re.type)){switch(Re.type){case"youtube":Re.embed[Re.elements.media.muted?"mute":"unMute"]();break;case"vimeo":case"soundcloud":Re.embed.setVolume(Re.elements.media.muted?0:parseFloat(s.volume/10))}f(Re.elements.media,"volumechange")}}function ge(e){var t=10,n=0;if(c.event(e)&&(e=e.target.value),c.undefined(e)&&(e=Re.storage.volume),(null===e||isNaN(e))&&(e=s.volume),e>t&&(e=t),e<n&&(e=n),Re.elements.media.volume=parseFloat(e/t),Re.elements.display.volume&&(Re.elements.display.volume.value=e),d.inArray(u.embed,Re.type)){switch(Re.type){case"youtube":Re.embed.setVolume(100*Re.elements.media.volume);break;case"vimeo":case"soundcloud":Re.embed.setVolume(Re.elements.media.volume)}f(Re.elements.media,"volumechange")}0===e?Re.elements.media.muted=!0:Re.elements.media.muted&&e>0&&ye()}function be(e){var t=Re.elements.media.muted?0:10*Re.elements.media.volume;c.number(e)||(e=1),ge(t+e)}function ve(e){var t=Re.elements.media.muted?0:10*Re.elements.media.volume;c.number(e)||(e=1),ge(t-e)}function he(){var e=Re.elements.media.muted?0:10*Re.elements.media.volume;Re.supported.full&&(Re.elements.inputs.volume&&(Re.elements.inputs.volume.value=e),Re.elements.display.volume&&(Re.elements.display.volume.value=e)),Q({volume:e}),d.toggleClass(Re.elements.container,s.classes.muted,0===e),Re.supported.full&&Re.elements.buttons.mute&&d.toggleState(Re.elements.buttons.mute,0===e)}function ke(e){var t="waiting"===e.type;clearTimeout(Be.loading),Be.loading=setTimeout(function(){d.toggleClass(Re.elements.container,s.classes.loading,t),Fe(t)},t?250:0)}function Ce(e){if(Re.supported.full){var t=Re.elements.display.played,n=0,a=ue();if(e)switch(e.type){case"timeupdate":case"seeking":if(Re.elements.controls.pressed)return;n=d.getPercentage(Re.elements.media.currentTime,a),"timeupdate"===e.type&&Re.elements.inputs.seek&&(Re.elements.inputs.seek.value=n);break;case"playing":case"progress":t=Re.elements.display.buffer,n=function(){var e=Re.elements.media.buffered;return e&&e.length?d.getPercentage(e.end(0),a):c.number(e)?100*e:0}()}c.number(s.loop.start)&&c.number(s.loop.end)&&Re.elements.media.currentTime>=s.loop.end&&oe(s.loop.start),Ee(t,n)}}function Ee(e,t){if(Re.supported.full){if(c.undefined(t)&&(t=0),c.undefined(e)){if(!c.htmlElement(Re.elements.display.buffer))return;e=Re.elements.display.buffer}if(c.htmlElement(e)){e.value=t;var n=e.getElementsByTagName("span")[0];c.htmlElement(n)&&(n.childNodes[0].nodeValue=t)}}}function Ae(e,t){if(t){isNaN(e)&&(e=0);var n=parseInt(e%60),a=parseInt(e/60%60),l=parseInt(e/60/60%60),s=parseInt(ue()/60/60%60)>0;n=("0"+n).slice(-2),a=("0"+a).slice(-2);var r=(s?l+":":"")+a+":"+n;return t.textContent=r,r}}function we(){if(Re.supported.full){var e=ue()||0;!Re.elements.display.duration&&s.displayDuration&&Re.elements.media.paused&&Ae(e,Re.elements.display.currentTime),Re.elements.display.duration&&Ae(e,Re.elements.display.duration),xe()}}function Se(e){Ae(Re.elements.media.currentTime,Re.elements.display.currentTime),e&&"timeupdate"===e.type&&Re.elements.media.seeking||Ce(e)}function Te(e){c.number(e)||(e=0);var t=ue(),n=d.getPercentage(e,t);Re.elements.progress&&Re.elements.display.played&&(Re.elements.display.played.value=n),Re.elements.buttons&&Re.elements.inputs.seek&&(Re.elements.inputs.seek.value=n)}function xe(e){var t=ue();if(s.tooltips.seek&&c.htmlElement(Re.elements.inputs.seek)&&c.htmlElement(Re.elements.display.seekTooltip)&&0!==t){var n=Re.elements.inputs.seek.getBoundingClientRect(),a=0,l=s.classes.tooltip+"--visible";if(c.event(e))a=100/n.width*(e.pageX-n.left);else{if(!d.hasClass(Re.elements.display.seekTooltip,l))return;a=Re.elements.display.seekTooltip.style.left.replace("%","")}a<0?a=0:a>100&&(a=100),Ae(t/100*a,Re.elements.display.seekTooltip),Re.elements.display.seekTooltip.style.left=a+"%",c.event(e)&&d.inArray(["mouseenter","mouseleave"],e.type)&&d.toggleClass(Re.elements.display.seekTooltip,l,"mouseenter"===e.type)}}function Fe(t){if(s.hideControls&&"audio"!==Re.type){var n=0,a=!1,l=t,r=d.hasClass(Re.elements.container,s.classes.loading);if(c.boolean(t)||(t&&t.type?(a="enterfullscreen"===t.type, -l=d.inArray(["mousemove","touchstart","mouseenter","focus"],t.type),d.inArray(["mousemove","touchmove"],t.type)&&(n=2e3),"focus"===t.type&&(n=3e3)):l=d.hasClass(Re.elements.container,s.classes.hideControls)),e.clearTimeout(Be.hover),l||Re.elements.media.paused||r){if(d.toggleClass(Re.elements.container,s.classes.hideControls,!1),Re.elements.media.paused||r)return;m.touch&&(n=3e3)}l&&Re.elements.media.paused||(Be.hover=e.setTimeout(function(){(!Re.elements.controls.pressed&&!Re.elements.controls.hover||a)&&d.toggleClass(Re.elements.container,s.classes.hideControls,!0)},n))}}function _e(e){if(!c.undefined(e))return void Pe(e);var t;switch(Re.type){case"youtube":t=Re.embed.getVideoUrl();break;case"vimeo":Re.embed.getVideoUrl.then(function(e){t=e});break;case"soundcloud":Re.embed.getCurrentSound(function(e){t=e.permalink_url});break;default:t=Re.elements.media.currentSrc}return t||""}function Pe(e){function t(){if(Re.embed=null,b("media"),b("captions"),b("wrapper"),Re.elements.container&&Re.elements.container.removeAttribute("class"),"type"in e&&(Re.type=e.type,"video"===Re.type)){var t=e.sources[0];"type"in t&&d.inArray(u.embed,t.type)&&(Re.type=t.type)}switch(Re.supported=l(Re.type,s.inline),Re.type){case"video":Re.elements.media=d.createElement("video");break;case"audio":Re.elements.media=d.createElement("audio");break;case"youtube":case"vimeo":case"soundcloud":Re.elements.media=d.createElement("div"),Re.embedId=e.sources[0].src}d.prependChild(Re.elements.container,Re.elements.media),c.boolean(e.autoplay)&&(s.autoplay=e.autoplay),d.inArray(u.html5,Re.type)&&(s.crossorigin&&Re.elements.media.setAttribute("crossorigin",""),s.autoplay&&Re.elements.media.setAttribute("autoplay",""),"poster"in e&&Re.elements.media.setAttribute("poster",e.poster),s.loop.active&&Re.elements.media.setAttribute("loop",""),s.inline&&Re.elements.media.setAttribute("playsinline","")),d.toggleClass(Re.elements.container,s.classes.fullscreen.active,Re.fullscreen.active),d.toggleClass(Re.elements.container,s.classes.captions.active,Re.captions.enabled),W(),d.inArray(u.html5,Re.type)&&h("source",e.sources),X(),d.inArray(u.html5,Re.type)&&("tracks"in e&&h("track",e.tracks),Re.elements.media.load()),(d.inArray(u.html5,Re.type)||d.inArray(u.embed,Re.type)&&!Re.supported.full)&&(Me(),Ve()),s.title=e.title,U()}return c.object(e)&&"sources"in e&&e.sources.length?(d.toggleClass(Re.elements.container,s.classes.ready,!1),te(),Te(),Ee(),qe(),void Oe(t,!1)):void Ye("Invalid source format")}function Ie(e){"video"===Re.type&&Re.elements.media.setAttribute("poster",e)}function Ne(){function n(){var e=ne(),t=Re.elements.buttons[e?"play":"pause"],n=Re.elements.buttons[e?"pause":"play"];if(n){var a=d.hasClass(t,s.classes.tabFocus);setTimeout(function(){c.htmlElement(n)&&n.focus(),a&&(d.toggleClass(t,s.classes.tabFocus,!1),d.toggleClass(n,s.classes.tabFocus,!0))},100)}}function a(e){return e.keyCode?e.keyCode:e.which}function l(e){d.toggleClass(y("."+s.classes.tabFocus),s.classes.tabFocus,!1),Re.elements.container.contains(e)&&d.toggleClass(e,s.classes.tabFocus,!0)}function i(e){function t(){var e=Re.elements.media.duration;c.number(e)&&oe(e/10*(l-48))}var l=a(e),s="keydown"===e.type,r=s&&l===u;if(c.number(l))if(s){var i=[48,49,50,51,52,53,54,56,57,32,75,38,40,77,39,37,70,67,73,76,79],o=[38,40];if(d.inArray(o,l)){var p=d.getFocusElement();if(c.htmlElement(p)&&"radio"===d.getFocusElement().type)return}switch(d.inArray(i,l)&&(e.preventDefault(),e.stopPropagation()),l){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:r||t();break;case 32:case 75:r||n();break;case 38:be();break;case 40:ve();break;case 77:r||ye();break;case 39:ie();break;case 37:re();break;case 70:me();break;case 67:r||R();break;case 73:ae("start");break;case 76:ae();break;case 79:ae("end")}!m.fullscreen&&Re.fullscreen.active&&27===l&&me(),u=l}else u=null}var o=Re.browser.isIE?"change":"input";if(s.keyboardShortcuts.focused){var u=null;s.keyboardShortcuts.global&&d.on(e,"keydown keyup",function(e){var t=a(e),n=d.getFocusElement(),l=[48,49,50,51,52,53,54,56,57,75,77,70,67,73,76,79],o=r().length;1!==o||!d.inArray(l,t)||c.htmlElement(n)&&d.matches(n,s.selectors.editable)||i(e)},!1),d.on(Re.elements.container,"keydown keyup",i,!1)}d.on(e,"keyup",function(e){var t=a(e),n=d.getFocusElement();9===t&&l(n)}),d.on(t.body,"click",function(){d.toggleClass(g("."+s.classes.tabFocus),s.classes.tabFocus,!1)});for(var f in Re.elements.buttons){var b=Re.elements.buttons[f];d.on(b,"blur",function(){d.toggleClass(b,"tab-focus",!1)})}var v=function(e,t,n){c.function(t)&&t.call(this,e),c.function(n)&&n.call(this,e)};d.proxy(Re.elements.buttons.play,"click",s.listeners.play,n),d.proxy(Re.elements.buttons.playLarge,"click",s.listeners.play,n),d.proxy(Re.elements.buttons.pause,"click",s.listeners.pause,n),d.proxy(Re.elements.buttons.restart,"click",s.listeners.restart,oe),d.proxy(Re.elements.buttons.rewind,"click",s.listeners.rewind,re),d.proxy(Re.elements.buttons.forward,"click",s.listeners.forward,ie),d.proxy(Re.elements.buttons.mute,"click",s.listeners.mute,ye),d.proxy(Re.elements.buttons.captions,"click",s.listeners.captions,R),d.proxy(Re.elements.buttons.fullscreen,"click",s.listeners.fullscreen,me),d.proxy(Re.elements.buttons.pip,"click",s.listeners.pip,function(e){m.pip&&Re.elements.media.webkitSetPresentationMode("picture-in-picture"===Re.elements.media.webkitPresentationMode?"inline":"picture-in-picture")}),d.proxy(Re.elements.buttons.airplay,"click",s.listeners.airplay,function(e){m.airplay&&Re.elements.media.webkitShowPlaybackTargetPicker()}),d.on(Re.elements.settings.menu,"click",fe),d.on(t.body,"click",function(e){var t=Re.elements.settings.menu,n=t.querySelector("form");"true"===n.getAttribute("aria-hidden")||t.contains(e.target)||n.setAttribute("aria-hidden",!0)}),d.on(Re.elements.settings.menu,"click",function(e){d.matches(e.target,s.selectors.inputs.language)?v.call(this,e,s.listeners.language,M):d.matches(e.target,s.selectors.inputs.quality)?v.call(this,e,s.listeners.quality,function(){Ye("Set quality")}):d.matches(e.target,s.selectors.inputs.speed)?v.call(this,e,s.listeners.speed,le):d.matches(e.target,s.selectors.buttons.loop)&&v.call(this,e,s.listeners.loop,function(){var t=e.target.getAttribute("data-loop__value")||e.target.getAttribute("data-loop__type");d.inArray(["start","end","all","none"],t)&&ae(t)})}),d.proxy(Re.elements.inputs.seek,o,s.listeners.seek,oe),d.proxy(Re.elements.inputs.volume,o,s.listeners.volume,ge),d.on(Re.elements.progress,"mouseenter mouseleave mousemove",xe),s.hideControls&&(d.on(Re.elements.container,"mouseenter mouseleave mousemove touchstart touchend touchcancel touchmove enterfullscreen",Fe),d.on(Re.elements.controls,"mouseenter mouseleave",function(e){Re.elements.controls.hover="mouseenter"===e.type}),d.on(Re.elements.controls,"mousedown mouseup touchstart touchend touchcancel",function(e){Re.elements.controls.pressed=d.inArray(["mousedown","touchstart"],e.type)}),d.on(Re.elements.controls,"focus blur",Fe,!0,!0)),d.proxy(Re.elements.inputs.volume,"wheel",s.listeners.volume,function(e){var t=e.webkitDirectionInvertedFromDevice,n=.2,a=0;(e.deltaY<0||e.deltaX>0)&&(t?(ve(n),a=-1):(be(n),a=1)),(e.deltaY>0||e.deltaX<0)&&(t?(be(n),a=1):(ve(n),a=-1)),(1===a&&Re.elements.media.volume<1||a===-1&&Re.elements.media.volume>0)&&e.preventDefault()},!1),m.fullscreen&&d.on(t,p.eventType,me)}function Le(){if(d.on(Re.elements.media,"timeupdate seeking",Se),d.on(Re.elements.media,"durationchange loadedmetadata",we),d.on(Re.elements.media,"ended",function(){"video"===Re.type&&s.showPosterOnEnd&&("video"===Re.type&&V(),oe(),Re.elements.media.load())}),d.on(Re.elements.media,"progress playing",Ce),d.on(Re.elements.media,"volumechange",he),d.on(Re.elements.media,"play pause ended",ce),d.on(Re.elements.media,"waiting canplay seeked",ke),s.clickToPlay&&"audio"!==Re.type){var e=g("."+s.classes.videoWrapper);if(!e)return;e.style.cursor="pointer",d.on(e,"click",function(){s.hideControls&&m.touch&&!Re.elements.media.paused||(Re.elements.media.paused?ee():Re.elements.media.ended?(oe(),ee()):te())})}s.disableContextMenu&&d.on(Re.elements.media,"contextmenu",function(e){e.preventDefault()},!1),d.on(Re.elements.media,s.events.concat(["keyup","keydown"]).join(" "),function(e){f(Re.elements.container,e.type,!0)})}function qe(){if(d.inArray(u.html5,Re.type)){for(var e=Re.elements.media.querySelectorAll("source"),t=0;t<e.length;t++)d.removeElement(e[t]);Re.elements.media.setAttribute("src","https://cdn.selz.com/plyr/blank.mp4"),Re.elements.media.load(),We("Cancelled network requests")}}function Oe(n,a){function l(){c.boolean(a)||(a=!0),c.function(n)&&n.call(He),a&&(Re.init=!1,Re.elements.container.parentNode.replaceChild(He,Re.elements.container),t.body.style.overflow="",f(He,"destroyed",!0))}if(!Re.init)return null;switch(Re.type){case"youtube":e.clearInterval(Be.buffering),e.clearInterval(Be.playing),Re.embed.destroy(),l();break;case"vimeo":Re.embed.unload().then(l),e.setTimeout(l,200);break;case"video":case"audio":Y(!0),l()}}function je(){if(Re.init)return null;if(Re.browser=d.getBrowser(),c.htmlElement(Re.elements.media)){K();var e=n.tagName.toLowerCase();"div"===e?(Re.type=n.getAttribute("data-type"),Re.embedId=n.getAttribute("data-video-id"),n.removeAttribute("data-type"),n.removeAttribute("data-video-id")):(Re.type=e,s.crossorigin=null!==n.getAttribute("crossorigin"),s.autoplay=s.autoplay||null!==n.getAttribute("autoplay"),s.inline=null!==n.getAttribute("playsinline"),s.loop.active=s.loop||null!==n.getAttribute("loop")),Re.supported=l(Re.type,s.inline),Re.supported.basic&&(Re.elements.container=d.wrap(n,d.createElement("div")),Re.elements.container.setAttribute("tabindex",0),W(),We(""+Re.browser.name+" "+Re.browser.version),X(),(d.inArray(u.html5,Re.type)||d.inArray(u.embed,Re.type)&&!Re.supported.full)&&(Me(),Ve(),U()),Re.init=!0)}}function Me(){return Re.supported.full?(c.htmlElement(Re.elements.controls)||(B(),Ne()),void(c.htmlElement(Re.elements.controls)&&(Le(),Y(),L(),q(),ge(),he(),le(),ae(),Se(),ce()))):(Ye("Basic support only",Re.type),b("controls"),b("buttons.play"),void Y(!0))}function Ve(){d.toggleClass(Re.elements.media,o.classes.setup,!0),d.toggleClass(Re.elements.container,s.classes.ready,!0),Re.elements.media.plyr=De,e.setTimeout(function(){f(Re.elements.media,"ready")},0),s.autoplay&&ee()}var De,Re=this,Be={};Re.fullscreen={active:!1},Re.elements={container:null,buttons:{},display:{},progress:{},inputs:{},settings:{menu:null,panes:{},tabs:{}},media:n,captions:null},Re.captions={enabled:!1,captions:[],tracks:[],currentTrack:null};var He=n.cloneNode(!0),We=function(){},Ye=function(){};return s.debug&&"console"in e&&(We=e.console.log,Ye=e.console.warn),We("Config",s),We("Support",m),De={getOriginal:function(){return He},getContainer:function(){return Re.elements.container},getEmbed:function(){return Re.embed},getMedia:function(){return Re.elements.media},getType:function(){return Re.type},getDuration:ue,getCurrentTime:function(){return Re.elements.media.currentTime},getVolume:function(){return Re.elements.media.volume},isMuted:function(){return Re.elements.media.muted},isReady:function(){return d.hasClass(Re.elements.container,s.classes.ready)},isLoading:function(){return d.hasClass(Re.elements.container,s.classes.loading)},isPaused:function(){return Re.elements.media.paused},isLooping:function(){return s.loop.active},on:function(e,t){return d.on(Re.elements.container,e,t),this},play:ee,pause:te,loop:ae,stop:function(){te(),oe()},restart:oe,rewind:re,forward:ie,seek:oe,source:_e,poster:Ie,setVolume:ge,setSpeed:le,togglePlay:ne,toggleMute:ye,toggleCaptions:R,toggleFullscreen:me,toggleControls:Fe,setLanguage:M,isFullscreen:function(){return Re.fullscreen.active||!1},support:function(e){return m.mime(Re,e)},destroy:Oe},je(),Re.init?De:null}function a(e,n){var a=new XMLHttpRequest;if(!c.string(n)||!c.htmlElement(t.querySelector("#"+n))){var l=d.createElement("div");l.setAttribute("hidden",""),c.string(n)&&l.setAttribute("id",n),t.body.insertBefore(l,t.body.childNodes[0]),"withCredentials"in a&&(a.open("GET",e,!0),a.onload=function(){l.innerHTML=a.responseText},a.send())}}function l(e,t){var n=!1,a=!1,l=d.getBrowser(),s=l.isIPhone&&t&&m.inline;switch(e){case"video":n=m.video,a=n&&!l.isOldIE&&(!l.isIPhone||s);break;case"audio":n=m.audio,a=n&&!l.isOldIE;break;case"youtube":n=m.video,a=n&&!l.isOldIE&&(!l.isIPhone||s);break;case"vimeo":case"soundcloud":n=!0,a=!l.isOldIE&&!l.isIos;break;default:n=m.audio&&m.video,a=n&&!l.isOldIE}return{basic:n,full:a}}function s(a,s){function r(e,t){d.hasClass(t,o.classes.hook)||i.push({target:e,media:t})}var i=[],u=[],p=[o.selectors.html5,o.selectors.embed].join(",");if(c.string(a)?a=t.querySelectorAll(a):c.htmlElement(a)?a=[a]:c.nodeList(a)||c.array(a)||c.string(a)||(c.undefined(s)&&c.object(a)&&(s=a),a=t.querySelectorAll(p)),c.nodeList(a)&&(a=Array.prototype.slice.call(a)),!l().basic||!a.length)return!1;for(var m=0;m<a.length;m++){var f=a[m],y=f.querySelectorAll(p);if(y.length)for(var g=0;g<y.length;g++)r(f,y[g]);else d.matches(f,p)&&r(f,f)}return i.forEach(function(t){var a=t.target,l=t.media,r=!1;l===a&&(r=!0);var i={};try{i=JSON.parse(a.getAttribute("data-plyr"))}catch(e){}var p=d.extend({},o,s,i);if(!p.enabled)return null;var m=new n(l,p);if(c.object(m)){if(p.debug){var f=p.events.concat(["setup","statechange","enterfullscreen","exitfullscreen","captionsenabled","captionsdisabled"]);d.on(m.getContainer(),f.join(" "),function(t){e.console.log([p.logPrefix,"event:",t.type].join(" ").trim())})}d.event(m.getContainer(),"setup",!0,{plyr:m}),u.push(m)}}),u}function r(e){if(c.string(e)?e=t.querySelector(e):c.undefined(e)&&(e=t.body),c.htmlElement(e)){var n=e.querySelectorAll("."+o.classes.setup),a=[];return Array.prototype.slice.call(n).forEach(function(e){c.object(e.plyr)&&a.push(e.plyr)}),a}return[]}var i={x:0,y:0},o={enabled:!0,title:"",debug:!1,autoplay:!1,seekTime:10,volume:10,duration:null,displayDuration:!0,loadSprite:!0,iconPrefix:"plyr",iconUrl:"https://cdn.plyr.io/2.0.10/plyr.svg",clickToPlay:!0,hideControls:!0,showPosterOnEnd:!1,disableContextMenu:!0,quality:{default:"auto",selected:"auto"},loop:{active:!1,start:0,end:null,indicator:{start:0,end:0}},speed:{selected:1,options:[.25,.5,.75,1,1.25,1.5,2]},keyboardShortcuts:{focused:!0,global:!1},tooltips:{controls:!1,seek:!0},selectors:{html5:"video, audio",embed:"[data-type]",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"]',forward:'[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",played:".plyr__progress--played",loop:".plyr__progress--loop",volume:".plyr__volume--display"},progress:".plyr__progress",captions:".plyr__captions",menu:{quality:".js-plyr__menu__list--quality"}},classes:{setup:"plyr--setup",ready:"plyr--ready",videoWrapper:"plyr__video-wrapper",embedWrapper:"plyr__video-embed",control:"plyr__control",type:"plyr--{0}",stopped:"plyr--stopped",playing:"plyr--playing",muted:"plyr--muted",loading:"plyr--loading",hover:"plyr--hover",tooltip:"plyr__tooltip",hidden:"plyr__sr-only",hideControls:"plyr--hide-controls",isIos:"plyr--is-ios",isTouch:"plyr--is-touch",menu:{value:"plyr__menu__value",badge:"plyr__badge"},captions:{enabled:"plyr--captions-enabled",active:"plyr--captions-active"},fullscreen:{enabled:"plyr--fullscreen-enabled",active:"plyr--fullscreen-active"},pip:{enabled:"plyr--pip-enabled",active:"plyr--pip-active"},airplay:{enabled:"plyr--airplay-enabled",active:"plyr--airplay-active"},tabFocus:"tab-focus"},captions:{active:!1,language:e.navigator.language.split("-")[0]},fullscreen:{enabled:!0,fallback:!0,allowAudio:!1},storage:{enabled:!0,key:"plyr"},controls:["play-large","play","progress","current-time","mute","volume","captions","settings","pip","airplay","fullscreen"],i18n:{restart:"Restart",rewind:"Rewind {seektime} secs",play:"Play",pause:"Pause",forward:"Forward {seektime} secs",seek:"Seek",played:"Played",buffered:"Buffered",currentTime:"Current time",duration:"Duration",volume:"Volume",toggleMute:"Toggle Mute",toggleCaptions:"Toggle Captions",toggleFullscreen:"Toggle Fullscreen",frameTitle:"Player for {title}",captions:"Captions",settings:"Settings",speed:"Speed",quality:"Quality",loop:"Loop",start:"Start",end:"End",all:"All",reset:"Reset",none:"None"},urls:{vimeo:{api:"https://player.vimeo.com/api/player.js"},youtube:{api:"https://www.youtube.com/iframe_api"},soundcloud:{api:"https://w.soundcloud.com/player/api.js"}},listeners:{seek:null,play:null,pause:null,restart:null,rewind:null,forward:null,mute:null,volume:null,captions:null,fullscreen:null,pip:null,airplay:null,speed:null,quality:null,loop:null,language:null},events:["ready","ended","progress","stalled","playing","waiting","canplay","canplaythrough","loadstart","loadeddata","loadedmetadata","timeupdate","volumechange","play","pause","error","seeking","seeked","emptied"],logPrefix:""},u={embed:["youtube","vimeo","soundcloud"],html5:["video","audio"]},c={object:function(e){return null!==e&&"object"==typeof e&&e.constructor===Object},array:function(e){return null!==e&&Array.isArray(e)},number:function(e){return null!==e&&("number"==typeof e&&!isNaN(e-0)||"object"==typeof e&&e.constructor===Number)},string:function(e){return null!==e&&("string"==typeof e||"object"==typeof e&&e.constructor===String)},boolean:function(e){return null!==e&&"boolean"==typeof e},nodeList:function(e){return null!==e&&e instanceof NodeList},htmlElement:function(e){return null!==e&&e instanceof HTMLElement},function:function(e){return null!==e&&"function"==typeof e},event:function(e){return null!==e&&e instanceof Event},cue:function(t){return null!==t&&(t instanceof e.TextTrackCue||t instanceof e.VTTCue)},track:function(t){return null!==t&&t instanceof e.TextTrack},undefined:function(e){return null!==e&&"undefined"==typeof e},empty:function(e){return null===e||this.undefined(e)||(this.string(e)||this.array(e)||this.nodeList(e))&&0===e.length||this.object(e)&&0===Object.keys(e).length}},d={getBrowser:function(){var e,t,n,a=navigator.userAgent,l=navigator.appName,s=""+parseFloat(navigator.appVersion),r=parseInt(navigator.appVersion,10),i=!1,o=!1,u=!1,c=!1;return navigator.appVersion.indexOf("Windows NT")!==-1&&navigator.appVersion.indexOf("rv:11")!==-1?(i=!0,l="IE",s="11"):(t=a.indexOf("MSIE"))!==-1?(i=!0,l="IE",s=a.substring(t+5)):(t=a.indexOf("Chrome"))!==-1?(u=!0,l="Chrome",s=a.substring(t+7)):(t=a.indexOf("Safari"))!==-1?(c=!0,l="Safari",s=a.substring(t+7),(t=a.indexOf("Version"))!==-1&&(s=a.substring(t+8))):(t=a.indexOf("Firefox"))!==-1?(o=!0,l="Firefox",s=a.substring(t+8)):(e=a.lastIndexOf(" ")+1)<(t=a.lastIndexOf("/"))&&(l=a.substring(e,t),s=a.substring(t+1),l.toLowerCase()===l.toUpperCase()&&(l=navigator.appName)),(n=s.indexOf(";"))!==-1&&(s=s.substring(0,n)),(n=s.indexOf(" "))!==-1&&(s=s.substring(0,n)),r=parseInt(""+s,10),isNaN(r)&&(s=""+parseFloat(navigator.appVersion),r=parseInt(navigator.appVersion,10)),{name:l,version:r,isIE:i,isOldIE:i&&r<=9,isFirefox:o,isChrome:u,isSafari:c,isIPhone:/(iPhone|iPod)/gi.test(navigator.platform),isIos:/(iPad|iPhone|iPod)/gi.test(navigator.platform)}},injectScript:function(e){if(!t.querySelectorAll('script[src="'+e+'"]').length){var n=t.createElement("script");n.src=e;var a=t.getElementsByTagName("script")[0];a.parentNode.insertBefore(n,a)}},inFrame:function(){try{return e.self!==e.top}catch(e){return!0}},inArray:function(e,t){return c.array(e)&&e.indexOf(t)!==-1},replaceAll:function(e,t,n){return e.replace(new RegExp(t.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g,"\\$1"),"g"),n)},wrap:function(e,t){e.length||(e=[e]);for(var n=e.length-1;n>=0;n--){var a=n>0?t.cloneNode(!0):t,l=e[n],s=l.parentNode,r=l.nextSibling;return a.appendChild(l),r?s.insertBefore(a,r):s.appendChild(a),a}},removeElement:function(e){c.htmlElement(e)&&c.htmlElement(e.parentNode)&&e.parentNode.removeChild(e)},prependChild:function(e,t){e.insertBefore(t,e.firstChild)},insertAfter:function(e,t){t.parentNode.insertBefore(e,t.nextSibling)},createElement:function(e,n,a){var l=t.createElement(e);return c.object(n)&&d.setAttributes(l,n),c.string(a)&&(l.textContent=a),l},insertElement:function(e,t,n,a){var l=d.createElement(e,n,a);d.prependChild(t,l)},emptyElement:function(e){for(var t=e.childNodes.length;t--;)e.removeChild(e.lastChild)},setAttributes:function(e,t){for(var n in t)e.setAttribute(n,t[n])},getAttributesFromSelector:function(e,t){if(!c.string(e)||c.empty(e))return{};var n={};return e.split(",").forEach(function(e){e=e.trim();var a=e.charAt(0);switch(a){case".":var l=e.replace(".","");c.object(t)&&c.string(t.class)&&(t.class+=" "+l),n.class=l;break;case"#":n.id=e.replace("#","");break;case"[":e=e.replace(/[\[\]]/g,"");var s=e.split("="),r=s[0],i=s.length>1?s[1].replace(/[\"\']/g,""):"";n[r]=i}}),n},toggleClass:function(e,t,n){if(e)if(e.classList)e.classList[n?"add":"remove"](t);else{var a=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=a+(n?" "+t:"")}},hasClass:function(e,t){return!!e&&(e.classList?e.classList.contains(t):new RegExp("(\\s|^)"+t+"(\\s|$)").test(e.className))},matches:function(e,n){var a=Element.prototype,l=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.msMatchesSelector||function(e){return[].indexOf.call(t.querySelectorAll(e),this)!==-1};return l.call(e,n)},getFocusElement:function(){var e=t.activeElement;return e=e&&e!==t.body?t.querySelector(":focus"):null},proxy:function(e,t,n,a,l,s){d.on(e,t,function(t){n&&n.apply(e,[t]),a.apply(e,[t])},l,s)},toggleListener:function(e,t,n,a,l,s){if(t=t.split(" "),c.boolean(s)||(s=!1),c.boolean(l)||(l=!0),e instanceof NodeList){var r=1===arguments.length?[arguments[0]]:Array.apply(null,arguments);return r.shift(),void[].forEach.call(e,function(e){e instanceof Node&&d.toggleListener.apply(null,[e].concat(r))})}var i=s;m.passiveListeners&&(i={passive:l,capture:s}),t.forEach(function(t){e[a?"addEventListener":"removeEventListener"](t,n,i)})},on:function(e,t,n,a,l){c.undefined(e)||d.toggleListener(e,t,n,!0,a,l)},off:function(e,t,n,a,l){c.undefined(e)||d.toggleListener(e,t,n,!1,a,l)},event:function(e,t,n,a){if(e&&t){c.boolean(n)||(n=!1);var l=new CustomEvent(t,{bubbles:n,detail:a});e.dispatchEvent(l)}},toggleState:function(e,t){if(e)return t=c.boolean(t)?t:!e.getAttribute("aria-pressed"),e.setAttribute("aria-pressed",t),t},getPercentage:function(e,t){return 0===e||0===t||isNaN(e)||isNaN(t)?0:(e/t*100).toFixed(2)},extend:function(){var e=arguments;if(e.length){if(1===e.length)return e[0];var t=Array.prototype.shift.call(e);c.object(t)||(t={});for(var n=e.length,a=0;a<n;a++){var l=e[a];c.object(l)||(l={});for(var s in l)l[s]&&l[s].constructor&&l[s].constructor===Object?(t[s]=t[s]||{},d.extend(t[s],l[s])):t[s]=l[s]}return t}},parseYouTubeId:function(e){var t=/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;return e.match(t)?RegExp.$2:e},stripHTML:function(e){var n=t.createDocumentFragment(),a=t.createElement("div");return n.appendChild(a),a.innerHTML=e,n.firstChild.innerText}},p=function(){var e=function(){var e=!1;return c.function(t.cancelFullScreen)?e="":["webkit","o","moz","ms","khtml"].some(function(n){return c.function(t[n+"CancelFullScreen"])?(e=n,!0):c.function(t.msExitFullscreen)&&t.msFullscreenEnabled?(e="ms",!0):void 0}),e}();return{prefix:e,eventType:"ms"===e?"MSFullscreenChange":e+"fullscreenchange",isFullScreen:function(n){if(!m.fullscreen)return!1;switch(c.undefined(n)&&(n=t.body),this.prefix){case"":return t.fullscreenElement===n;case"moz":return t.mozFullScreenElement===n;default:return t[e+"FullscreenElement"]===n}},requestFullScreen:function(n){return!!m.fullscreen&&(c.htmlElement(n)||(n=t.body),""===e?n.requestFullScreen():n[e+("ms"===e?"RequestFullscreen":"RequestFullScreen")]())},cancelFullScreen:function(){return!!m.fullscreen&&(""===e?t.cancelFullScreen():t[e+("ms"===e?"ExitFullscreen":"CancelFullScreen")]())},element:function(){return m.fullscreen?""===e?t.fullscreenElement:t[e+"FullscreenElement"]:null}}}(),m={audio:"canPlayType"in t.createElement("audio"),video:"canPlayType"in t.createElement("video"),fullscreen:p.prefix!==!1,storage:function(){if(!("localStorage"in e))return!1;try{e.localStorage.setItem("___test","OK");var t=e.localStorage.getItem("___test");return e.localStorage.removeItem("___test"),"OK"===t}catch(e){return!1}return!1}(),pip:function(){var e=d.getBrowser();return!e.isIPhone&&c.function(d.createElement("video").webkitSetPresentationMode)}(),airplay:c.function(e.WebKitPlaybackTargetAvailabilityEvent),inline:"playsInline"in t.createElement("video"),mime:function(e,t){var n=e.media;try{if(!c.function(n.canPlayType))return!1;if("video"===e.type)switch(t){case"video/webm":return n.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/no/,"");case"video/mp4":return n.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/,"");case"video/ogg":return n.canPlayType('video/ogg; codecs="theora"').replace(/no/,"")}else if("audio"===e.type)switch(t){case"audio/mpeg":return n.canPlayType("audio/mpeg;").replace(/no/,"");case"audio/ogg":return n.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/,"");case"audio/wav":return n.canPlayType('audio/wav; codecs="1"').replace(/no/,"")}}catch(e){return!1}return!1},textTracks:"textTracks"in t.createElement("video"),passiveListeners:function(){var t=!1;try{var n=Object.defineProperty({},"passive",{get:function(){t=!0}});e.addEventListener("test",null,n)}catch(e){}return t}(),touch:"ontouchstart"in t.documentElement};return{setup:s,supported:l,loadSprite:a,get:r}}),function(){function e(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),n}"function"!=typeof window.CustomEvent&&(e.prototype=window.Event.prototype,window.CustomEvent=e)}();
\ No newline at end of file +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=t(e,document):"function"==typeof define&&define.amd?define([],function(){return t(e,document)}):e.Plyr=t(e,document)}("undefined"!=typeof window?window:this,function(e,t){"use strict";function n(n,u){function c(e,t,n,s){r.event(e,t,n,r.extend({},s,{plyr:Me}))}function d(e){return Oe.elements.container.querySelectorAll(e)}function p(e){return d(e)[0]}function m(e){r.is.string(e)?(r.removeElement(Oe.elements[e]),Oe.elements[e]=null):r.removeElement(e)}function f(){function e(e){9===e.which&&Oe.fullscreen.active&&(e.target!==s||e.shiftKey?e.target===n&&e.shiftKey&&(e.preventDefault(),s.focus()):(e.preventDefault(),n.focus()))}var t=d("input:not([disabled]), button:not([disabled])"),n=t[0],s=t[t.length-1];r.on(Oe.elements.container,"keydown",e,!1)}function y(e,t){r.is.string(t)?r.insertElement(e,Oe.elements.media,{src:t}):r.is.array(t)&&t.forEach(function(t){r.insertElement(e,Oe.elements.media,t)})}function g(){return{url:Ve.iconUrl,absolute:0===Ve.iconUrl.indexOf("http")||Oe.browser.isIE}}function b(e,n){var s="http://www.w3.org/2000/svg",a=g(),l=(a.absolute?"":a.url)+"#"+Ve.iconPrefix,i=t.createElementNS(s,"svg");r.setAttributes(i,r.extend(n,{role:"presentation"}));var o=t.createElementNS(s,"use");return o.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",l+"-"+e),i.appendChild(o),i}function v(e){var t=Ve.i18n[e];switch(e){case"pip":t="PIP";break;case"airplay":t="AirPlay"}return r.createElement("span",{class:Ve.classes.hidden},t)}function h(e){var t=r.createElement("span",{class:Ve.classes.menu.value});return t.appendChild(r.createElement("span",{class:Ve.classes.menu.badge},e)),t}function k(e,t){var n,s,a,l=r.createElement("button");switch(r.is.object(t)||(t={}),"class"in t?t.class.indexOf(Ve.classes.control)===-1&&(t.class+=" "+Ve.classes.control):t.class=Ve.classes.control,e){case"mute":a="toggleMute",n="volume",s="muted";break;case"captions":a="toggleCaptions",n="captions-off",s="captions-on";break;case"fullscreen":a="toggleFullscreen",n="enter-fullscreen",s="exit-fullscreen";break;case"play-large":t.class="plyr__play-large",e="play",a="play",n="play";break;default:a=e,n=e}return r.extend(t,r.getAttributesFromSelector(Ve.selectors.buttons[e],t)),r.is.string(s)&&l.appendChild(b(s,{class:"icon--"+s})),l.appendChild(b(n)),l.appendChild(v(a)),r.setAttributes(l,t),Oe.elements.buttons[e]=l,l}function C(e,t){var n=r.createElement("label",{for:t.id,class:Ve.classes.hidden},Ve.i18n[e]),s=r.createElement("input",r.extend(r.getAttributesFromSelector(Ve.selectors.inputs[e]),{type:"range",min:0,max:100,step:.1,value:0,autocomplete:"off"},t));return Oe.elements.inputs[e]=s,{label:n,input:s}}function E(e,t){var n=r.createElement("progress",r.extend(r.getAttributesFromSelector(Ve.selectors.display[e]),{min:0,max:100,value:0},t));if("volume"!==e){n.appendChild(r.createElement("span",null,"0"));var s="";switch(e){case"played":s=Ve.i18n.played;break;case"buffer":s=Ve.i18n.buffered}n.textContent="% "+s.toLowerCase()}return Oe.elements.display[e]=n,n}function A(e){var t=r.createElement("span",{class:"plyr__time"});return t.appendChild(r.createElement("span",{class:Ve.classes.hidden},Ve.i18n[e])),t.appendChild(r.createElement("span",r.getAttributesFromSelector(Ve.selectors.display[e]),"00:00")),Oe.elements.display[e]=t,t}function w(e){var t=r.createElement("div",r.getAttributesFromSelector(Ve.selectors.controls.wrapper));if(r.inArray(Ve.controls,"restart")&&t.appendChild(k("restart")),r.inArray(Ve.controls,"rewind")&&t.appendChild(k("rewind")),r.inArray(Ve.controls,"play")&&(t.appendChild(k("play")),t.appendChild(k("pause"))),r.inArray(Ve.controls,"fast-forward")&&t.appendChild(k("fast-forward")),r.inArray(Ve.controls,"progress")){var n=r.createElement("span",r.getAttributesFromSelector(Ve.selectors.progress)),s=C("seek",{id:"plyr-seek-"+e.id});if(n.appendChild(s.label),n.appendChild(s.input),n.appendChild(E("played")),n.appendChild(E("buffer")),Ve.tooltips.seek){var a=r.createElement("span",{role:"tooltip",class:Ve.classes.tooltip},"00:00");n.appendChild(a),Oe.elements.display.seekTooltip=a}Oe.elements.progress=n,t.appendChild(Oe.elements.progress)}if(r.inArray(Ve.controls,"current-time")&&t.appendChild(A("currentTime")),r.inArray(Ve.controls,"duration")&&t.appendChild(A("duration")),r.inArray(Ve.controls,"mute")&&t.appendChild(k("mute")),r.inArray(Ve.controls,"volume")){var l=r.createElement("span",{class:"plyr__volume"}),i={max:10,value:Ve.volume},u=C("volume",r.extend(i,{id:"plyr-volume-"+e.id}));l.appendChild(u.label),l.appendChild(u.input);var c=E("volume",i);l.appendChild(c),t.appendChild(l)}if(r.inArray(Ve.controls,"captions")&&t.appendChild(k("captions")),r.inArray(Ve.controls,"settings")){var d=r.createElement("span",r.extend(r.getAttributesFromSelector(Ve.selectors.buttons.settings),{class:"plyr__menu"}));d.appendChild(k("settings",{id:"plyr-settings-toggle-"+e.id,"aria-haspopup":!0,"aria-controls":"plyr-settings-"+e.id,"aria-expanded":!1}));var p=r.createElement("form",{class:"plyr__menu__container",id:"plyr-settings-"+e.id,"aria-hidden":!0,"aria-labelled-by":"plyr-settings-toggle-"+e.id,role:"tablist",tabindex:-1}),m=r.createElement("div"),f=r.createElement("div",{id:"plyr-settings-"+e.id+"-home","aria-hidden":!1,"aria-labelled-by":"plyr-settings-toggle-"+e.id,role:"tabpanel"}),y=r.createElement("ul",{role:"tablist"});["captions","quality","speed","loop"].forEach(function(t){var n=r.createElement("li",{role:"tab"}),s=r.createElement("button",r.extend(r.getAttributesFromSelector(Ve.selectors.buttons.settings),{type:"button",class:Ve.classes.control+" "+Ve.classes.control+"--forward",id:"plyr-settings-"+e.id+"-"+t+"-tab","aria-haspopup":!0,"aria-controls":"plyr-settings-"+e.id+"-"+t,"aria-expanded":!1}),Ve.i18n[t]),a=r.createElement("span",{class:Ve.classes.menu.value});a.innerHTML=e[t],s.appendChild(a),n.appendChild(s),y.appendChild(n),Oe.elements.settings.tabs[t]=n}),f.appendChild(y),m.appendChild(f),["captions","quality","speed","loop"].forEach(function(t){var n=r.createElement("div",{id:"plyr-settings-"+e.id+"-"+t,"aria-hidden":!0,"aria-labelled-by":"plyr-settings-"+e.id+"-"+t+"-tab",role:"tabpanel",tabindex:-1}),s=r.createElement("button",{type:"button",class:Ve.classes.control+" "+Ve.classes.control+"--back","aria-haspopup":!0,"aria-controls":"plyr-settings-"+e.id+"-home","aria-expanded":!1},Ve.i18n[t]);n.appendChild(s);var a=r.createElement("ul");n.appendChild(a),m.appendChild(n),Oe.elements.settings.panes[t]=n}),p.appendChild(m),d.appendChild(p),t.appendChild(d),Oe.elements.settings.menu=d}return r.inArray(Ve.controls,"pip")&&o.pip&&t.appendChild(k("pip")),r.inArray(Ve.controls,"airplay")&&o.airplay&&t.appendChild(k("airplay")),r.inArray(Ve.controls,"fullscreen")&&t.appendChild(k("fullscreen")),Oe.elements.controls=t,T(),F(),t}function S(e,n){function s(e){var t="";switch(e){case"hd2160":t="4K";break;case"hd1440":t="WQHD";break;case"hd1080":t="HD";break;case"hd720":t="HD"}return t.length?h(t):null}function a(e){switch(e){case"hd2160":return"2160P";case"hd1440":return"1440P";case"hd1080":return"1080P";case"hd720":return"720P";case"large":return"480P";case"medium":return"360P";case"small":return"240P";default:return"Auto"}}var l=Oe.elements.settings.panes.quality.querySelector("ul");r.emptyElement(l),r.is.array(e)&&!r.is.empty(e)&&e.filter(function(e){return!r.inArray(["tiny","small"],e)}).forEach(function(e){var n=r.createElement("li"),i=r.createElement("label",{class:Ve.classes.control,for:"plyr-quality-"+e}),o=r.createElement("input",r.extend(r.getAttributesFromSelector(Ve.selectors.inputs.quality),{type:"radio",id:"plyr-quality-"+e,name:"plyr-quality",value:e}));e===Ve.quality.selected&&o.setAttribute("checked",""),i.appendChild(o),i.appendChild(t.createTextNode(a(e)));var u=s(e);r.is.htmlElement(u)&&i.appendChild(u),n.appendChild(i),l.appendChild(n)})}function T(){var e=["start","end","all","reset"],t=Oe.elements.settings.panes.loop.querySelector("ul");r.emptyElement(t),e.forEach(function(e){var n=r.createElement("li"),s=r.createElement("button",r.extend(r.getAttributesFromSelector(Ve.selectors.buttons.loop),{type:"button",class:Ve.classes.control,"data-plyr-loop-action":e}),Ve.i18n[e]);if(r.inArray(["start","end"],e)){var a=h("0:00");s.appendChild(a)}n.appendChild(s),t.appendChild(n)})}function x(){var e=Oe.elements.settings.panes.captions.querySelector("ul");if(r.emptyElement(e),!r.is.empty(Oe.captions.tracks)){var n=[].map.call(Oe.captions.tracks,function(e){return{language:e.language,badge:!0,label:r.is.empty(e.label)?e.language.toUpperCase():e.label}});n.unshift({language:"off",label:Ve.i18n.none}),n.forEach(function(n){var s=r.createElement("li"),a=r.createElement("label",{class:Ve.classes.control,for:"plyr-language-"+n.language}),l=r.createElement("input",r.extend(r.getAttributesFromSelector(Ve.selectors.inputs.language),{type:"radio",id:"plyr-language-"+n.language,name:"plyr-language",value:n.language}));n.language===Ve.captions.language.toLowerCase()&&l.setAttribute("checked",""),a.appendChild(l),a.appendChild(t.createTextNode(n.label||n.language)),n.badge&&a.appendChild(h(n.language.toUpperCase())),s.appendChild(a),e.appendChild(s)})}}function F(e){var t=Oe.elements.settings.panes.speed.querySelector("ul");r.emptyElement(t),r.is.array(e)||(e=Ve.speed.options),e.forEach(function(e){var n=r.createElement("li"),s=r.createElement("label",{class:Ve.classes.control,for:"plyr-speed-"+e.toString().replace(".","-")}),a=r.createElement("input",r.extend(r.getAttributesFromSelector(Ve.selectors.inputs.speed),{type:"radio",id:"plyr-speed-"+e.toString().replace(".","-"),name:"plyr-speed",value:e}));e===Ve.speed.selected&&a.setAttribute("checked",""),s.appendChild(a),s.insertAdjacentHTML("beforeend","×"+e),n.appendChild(s),t.appendChild(n)})}function I(){if(Oe.supported.full&&("audio"!==Oe.type||Ve.fullscreen.allowAudio)&&Ve.fullscreen.enabled){var e=o.fullscreen;e||Ve.fullscreen.fallback&&!r.inFrame()?(De((e?"Native":"Fallback")+" fullscreen enabled"),r.toggleClass(Oe.elements.container,Ve.classes.fullscreen.enabled,!0)):De("Fullscreen not supported and fallback disabled"),Oe.elements.buttons&&Oe.elements.buttons.fullscreen&&r.toggleState(Oe.elements.buttons.fullscreen,!1),f()}}function P(e){if(r.inArray(["video","vimeo"],Oe.type)&&("video"!==Oe.type||o.textTracks)&&(r.is.htmlElement(Oe.elements.captions)||(Oe.elements.captions=r.createElement("div",r.getAttributesFromSelector(Ve.selectors.captions)),r.insertAfter(Oe.elements.captions,Oe.elements.wrapper)),Oe.captions.tracks=r.is.array(e)?e:Oe.elements.media.textTracks,r.toggleClass(Oe.elements.container,Ve.classes.captions.enabled,!r.is.empty(Oe.captions.tracks)),!r.is.empty(Oe.captions.tracks))){if(O(),"video"===Oe.type){var t=Ve.captions.language.toLowerCase();[].forEach.call(Oe.captions.tracks,function(e){r.off(e,"cuechange",N),e.mode="hidden",e.language===t&&(Oe.captions.currentTrack=e)}),r.is.track(Oe.captions.currentTrack)||(Re("No language found to match "+t+" in tracks"),Oe.captions.currentTrack=Oe.captions.tracks[0]);var n=Oe.captions.currentTrack;r.is.track(n)&&r.inArray(["captions","subtitles"],n.kind)&&(r.on(n,"cuechange",N),n.activeCues&&n.activeCues.length>0&&N(n))}x()}}function _(){return!o.textTracks||r.is.empty(Oe.captions.tracks)?"No Subs":Oe.captions.enabled?Oe.captions.currentTrack.label:"Disabled"}function N(e){r.is.event(e)&&(e=e.target);var t=e.activeCues[0];r.is.cue(t)?q(t.getCueAsHTML()):q()}function L(e){r.is.string(e)?Ve.captions.language=e.toLowerCase():r.is.event(e)&&(Ve.captions.language=e.target.value.toLowerCase()),q(),P()}function q(e){if(r.is.htmlElement(Oe.elements.captions)){var t=r.createElement("span");r.emptyElement(Oe.elements.captions),r.is.undefined(e)&&(e=""),r.is.string(e)?t.textContent=e.trim():t.appendChild(e),Oe.elements.captions.appendChild(t)}else Re("No captions element to render to")}function O(){if(Oe.elements.buttons.captions){var e=Oe.storage.captions;r.is.boolean(e)?Ve.captions.active=e:e=Ve.captions.active,e&&(r.toggleClass(Oe.elements.container,Ve.classes.captions.active,!0),r.toggleState(Oe.elements.buttons.captions,!0))}}function j(e){Oe.supported.full&&Oe.elements.buttons.captions&&(r.is.boolean(e)||(e=Oe.elements.container.className.indexOf(Ve.classes.captions.active)===-1),Oe.captions.enabled=e,r.toggleState(Oe.elements.buttons.captions,Oe.captions.enabled),r.toggleClass(Oe.elements.container,Ve.classes.captions.active,Oe.captions.enabled),c(Oe.elements.container,Oe.captions.enabled?"captionsenabled":"captionsdisabled",!0),W({captions:Oe.captions.enabled}))}function M(){if(Ve.loadSprite){var e=g();e.absolute?(De("AJAX loading absolute SVG sprite"+(Oe.browser.isIE?" (due to IE)":"")),r.loadSprite(e.url,"sprite-plyr")):De("Sprite will be used as external resource directly")}r.inArray(Ve.controls,"play-large")&&(Oe.elements.buttons.playLarge=k("play-large"),Oe.elements.container.appendChild(Oe.elements.buttons.playLarge)),Oe.id=Math.floor(1e4*Math.random());var n=null;n=r.is.string(Ve.controls)?Ve.controls:r.is.function(Ve.controls)?Ve.controls({id:Oe.id,seektime:Ve.seekTime}):w({id:Oe.id,seektime:Ve.seekTime,speed:te(),quality:"HD",captions:_(),loop:"None"});var s;if(r.is.string(Ve.selectors.controls.container)&&(s=t.querySelector(Ve.selectors.controls.container)),r.is.htmlElement(s)||(s=Oe.elements.container),r.is.htmlElement(n)?s.appendChild(n):s.insertAdjacentHTML("beforeend",n),r.is.htmlElement(Oe.elements.controls)&&V(),Ve.tooltips.controls)for(var a=d([Ve.selectors.controls.wrapper," ",Ve.selectors.labels," .",Ve.classes.hidden].join("")),l=a.length-1;l>=0;l--){var i=a[l];r.toggleClass(i,Ve.classes.hidden,!1),r.toggleClass(i,Ve.classes.tooltip,!0)}}function V(){try{return Oe.elements.controls=p(Ve.selectors.controls.wrapper),Oe.elements.buttons={play:d(Ve.selectors.buttons.play),pause:p(Ve.selectors.buttons.pause),restart:p(Ve.selectors.buttons.restart),rewind:p(Ve.selectors.buttons.rewind),forward:p(Ve.selectors.buttons.forward),mute:p(Ve.selectors.buttons.mute),pip:p(Ve.selectors.buttons.pip),airplay:p(Ve.selectors.buttons.airplay),settings:p(Ve.selectors.buttons.settings),captions:p(Ve.selectors.buttons.captions),fullscreen:p(Ve.selectors.buttons.fullscreen)},Oe.elements.progress=p(Ve.selectors.progress),Oe.elements.inputs={seek:p(Ve.selectors.inputs.seek),volume:p(Ve.selectors.inputs.volume)},Oe.elements.display={buffer:p(Ve.selectors.display.buffer),played:p(Ve.selectors.display.played),volume:p(Ve.selectors.display.volume),duration:p(Ve.selectors.display.duration),currentTime:p(Ve.selectors.display.currentTime)},r.is.htmlElement(Oe.elements.progress)&&(Oe.elements.display.seekTooltip=Oe.elements.progress.querySelector("."+Ve.classes.tooltip)),!0}catch(e){return Re("It looks like there is a problem with your custom controls HTML",e),R(!0),!1}}function D(){r.toggleClass(Oe.elements.container,Ve.selectors.container.replace(".",""),Oe.supported.full)}function R(e){e&&r.inArray(l.html5,Oe.type)?Oe.elements.media.setAttribute("controls",""):Oe.elements.media.removeAttribute("controls")}function B(e){var t=Ve.i18n.play;if(r.is.string(Ve.title)&&!r.is.empty(Ve.title)&&(t+=", "+Ve.title,Oe.elements.container.setAttribute("aria-label",Ve.title)),Oe.supported.full&&(r.is.htmlElement(Oe.elements.buttons.play)&&Oe.elements.buttons.play.setAttribute("aria-label",t),r.is.htmlElement(Oe.elements.buttons.playLarge)&&Oe.elements.buttons.playLarge.setAttribute("aria-label",t)),r.is.htmlElement(e)){var n=r.is.string(Ve.title)&&!r.is.empty(Ve.title)?Ve.title:"video";e.setAttribute("title",Ve.i18n.frameTitle.replace("{title}",n))}}function H(){var t=null;Oe.storage={},o.storage&&Ve.storage.enabled&&(e.localStorage.removeItem("plyr-volume"),t=e.localStorage.getItem(Ve.storage.key),t&&(/^\d+(\.\d+)?$/.test(t)?W({volume:parseFloat(t)}):Oe.storage=JSON.parse(t)))}function W(t){o.storage&&Ve.storage.enabled&&(r.extend(Oe.storage,t),e.localStorage.setItem(Ve.storage.key,JSON.stringify(Oe.storage)))}function Y(){return Oe.elements.media?(Oe.supported.full&&(r.toggleClass(Oe.elements.container,Ve.classes.type.replace("{0}",Oe.type),!0),r.inArray(l.embed,Oe.type)&&r.toggleClass(Oe.elements.container,Ve.classes.type.replace("{0}","video"),!0),r.toggleClass(Oe.elements.container,Ve.classes.pip.enabled,o.pip&&"video"===Oe.type),r.toggleClass(Oe.elements.container,Ve.classes.airplay.enabled,o.airplay&&r.inArray(l.html5,Oe.type)),r.toggleClass(Oe.elements.container,Ve.classes.stopped,Ve.autoplay),r.toggleClass(Oe.elements.container,Ve.classes.isIos,Oe.browser.isIos),r.toggleClass(Oe.elements.container,Ve.classes.isTouch,o.touch)),r.inArray(["video","youtube","vimeo"],Oe.type)&&(Oe.elements.wrapper=r.createElement("div",{class:Ve.classes.videoWrapper}),r.wrap(Oe.elements.media,Oe.elements.wrapper)),void(r.inArray(l.embed,Oe.type)&&U())):void Re("No media element found!")}function U(){var t,n=Oe.type+"-"+Math.floor(1e4*Math.random());switch(Oe.type){case"youtube":t=r.parseYouTubeId(Oe.embedId);break;default:t=Oe.embedId}for(var s=d('[id^="'+Oe.type+'-"]'),a=s.length-1;a>=0;a--)r.removeElement(s[a]);if(r.toggleClass(Oe.elements.wrapper,Ve.classes.embedWrapper,!0),"youtube"===Oe.type)Oe.elements.media.setAttribute("id",n),r.is.object(e.YT)?J(t):(r.injectScript(Ve.urls.youtube.api),e.onYouTubeReadyCallbacks=e.onYouTubeReadyCallbacks||[],e.onYouTubeReadyCallbacks.push(function(){J(t)}),e.onYouTubeIframeAPIReady=function(){e.onYouTubeReadyCallbacks.forEach(function(e){e()})});else if("vimeo"===Oe.type)if(Oe.elements.media.setAttribute("id",n),r.is.object(e.Vimeo))X(t);else{r.injectScript(Ve.urls.vimeo.api);var l=e.setInterval(function(){r.is.object(e.Vimeo)&&(e.clearInterval(l),X(t))},50)}else if("soundcloud"===Oe.type){var i=r.createElement("iframe");i.loaded=!1,r.on(i,"load",function(){i.loaded=!0}),r.setAttributes(i,{src:"https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/"+t,id:n}),Oe.elements.media.appendChild(i),e.SC||r.injectScript(Ve.urls.soundcloud.api);var o=e.setInterval(function(){e.SC&&i.loaded&&(e.clearInterval(o),z.call(i))},50)}}function Q(){Oe.supported.full&&(Ne(),Le()),B(p("iframe"))}function J(t){Oe.embed=new e.YT.Player(Oe.elements.media.id,{videoId:t,playerVars:{autoplay:Ve.autoplay?1:0,controls:Oe.supported.full?0:1,rel:0,showinfo:0,iv_load_policy:3,cc_load_policy:Ve.captions.active?1:0,cc_lang_pref:"en",wmode:"transparent",modestbranding:1,disablekb:1,playsinline:1,origin:e.location.href},events:{onError:function(e){c(Oe.elements.container,"error",!0,{code:e.data,embed:e.target})},onPlaybackQualityChange:function(e){var t=e.target,n=t.getPlaybackQuality();console.warn(n)},onReady:function(t){var n=t.target;Oe.elements.media.play=function(){n.playVideo(),Oe.elements.media.paused=!1},Oe.elements.media.pause=function(){n.pauseVideo(),Oe.elements.media.paused=!0},Oe.elements.media.stop=function(){n.stopVideo(),Oe.elements.media.paused=!0},Oe.elements.media.duration=n.getDuration(),Oe.elements.media.paused=!0,Oe.elements.media.currentTime=0,Oe.elements.media.muted=n.isMuted();var s=n.getPlaybackRate(),a=n.getAvailablePlaybackRates();console.warn(s,a),Ve.title=n.getVideoData().title,Oe.supported.full&&Oe.elements.media.setAttribute("tabindex",-1),Q(),c(Oe.elements.media,"timeupdate"),c(Oe.elements.media,"durationchange"),e.clearInterval(je.buffering),je.buffering=e.setInterval(function(){Oe.elements.media.buffered=n.getVideoLoadedFraction(),(null===Oe.elements.media.lastBuffered||Oe.elements.media.lastBuffered<Oe.elements.media.buffered)&&c(Oe.elements.media,"progress"),Oe.elements.media.lastBuffered=Oe.elements.media.buffered,1===Oe.elements.media.buffered&&(e.clearInterval(je.buffering),c(Oe.elements.media,"canplaythrough"))},200)},onStateChange:function(t){var n=t.target;switch(e.clearInterval(je.playing),t.data){case 0:if(Ve.loop.active){n.stopVideo(),n.playVideo();break}Oe.elements.media.paused=!0,c(Oe.elements.media,"ended");break;case 1:Oe.elements.media.paused=!1,Oe.elements.media.seeking&&c(Oe.elements.media,"seeked"),Oe.elements.media.seeking=!1,c(Oe.elements.media,"play"),c(Oe.elements.media,"playing"),je.playing=e.setInterval(function(){Oe.elements.media.currentTime=n.getCurrentTime(),c(Oe.elements.media,"timeupdate")},100),Oe.elements.media.duration!==n.getDuration()&&(Oe.elements.media.duration=n.getDuration(),c(Oe.elements.media,"durationchange"));var s=n.getAvailableQualityLevels(),a=n.getPlaybackQuality();S(s,a);break;case 2:Oe.elements.media.paused=!0,c(Oe.elements.media,"pause")}c(Oe.elements.container,"statechange",!1,{code:t.data})}}})}function X(t){Oe.embed=new e.Vimeo.Player(Oe.elements.media,{id:t,loop:Ve.loop.active,autoplay:Ve.autoplay,byline:!1,portrait:!1,title:!1}),Oe.elements.media.play=function(){Oe.embed.play(),Oe.elements.media.paused=!1},Oe.elements.media.pause=function(){Oe.embed.pause(),Oe.elements.media.paused=!0},Oe.elements.media.stop=function(){Oe.embed.stop(),Oe.elements.media.paused=!0},Oe.elements.media.paused=!0,Oe.elements.media.currentTime=0,Q(),Oe.embed.getCurrentTime().then(function(e){Oe.elements.media.currentTime=e,c(Oe.elements.media,"timeupdate")}),Oe.embed.getDuration().then(function(e){Oe.elements.media.duration=e,c(Oe.elements.media,"durationchange")}),Oe.embed.getTextTracks().then(function(e){P(e),Ve.captions.active&&Oe.embed.enableTextTrack(Ve.captions.language.toLowerCase())}),Oe.embed.on("cuechange",function(e){var t=null;e.cues.length&&(t=r.stripHTML(e.cues[0].text)),q(t)}),Oe.embed.on("loaded",function(){r.is.htmlElement(Oe.embed.element)&&Oe.supported.full&&Oe.embed.element.setAttribute("tabindex",-1)}),Oe.embed.on("play",function(){Oe.elements.media.paused=!1,c(Oe.elements.media,"play"),c(Oe.elements.media,"playing")}),Oe.embed.on("pause",function(){Oe.elements.media.paused=!0,c(Oe.elements.media,"pause")}),Oe.embed.on("timeupdate",function(e){Oe.elements.media.seeking=!1,Oe.elements.media.currentTime=e.seconds,c(Oe.elements.media,"timeupdate")}),Oe.embed.on("progress",function(e){Oe.elements.media.buffered=e.percent,c(Oe.elements.media,"progress"),1===parseInt(e.percent)&&c(Oe.elements.media,"canplaythrough")}),Oe.embed.on("seeked",function(){Oe.elements.media.seeking=!1,c(Oe.elements.media,"seeked"),c(Oe.elements.media,"play")}),Oe.embed.on("ended",function(){Oe.elements.media.paused=!0,c(Oe.elements.media,"ended")})}function z(){Oe.embed=e.SC.Widget(this),Oe.embed.bind(e.SC.Widget.Events.READY,function(){Oe.elements.media.play=function(){Oe.embed.play(),Oe.elements.media.paused=!1},Oe.elements.media.pause=function(){Oe.embed.pause(),Oe.elements.media.paused=!0},Oe.elements.media.stop=function(){Oe.embed.seekTo(0),Oe.embed.pause(),Oe.elements.media.paused=!0},Oe.elements.media.paused=!0,Oe.elements.media.currentTime=0,Oe.embed.getDuration(function(e){Oe.elements.media.duration=e/1e3,Q()}),Oe.embed.getPosition(function(e){Oe.elements.media.currentTime=e,c(Oe.elements.media,"timeupdate")}),Oe.embed.bind(e.SC.Widget.Events.PLAY,function(){Oe.elements.media.paused=!1,c(Oe.elements.media,"play"),c(Oe.elements.media,"playing")}),Oe.embed.bind(e.SC.Widget.Events.PAUSE,function(){Oe.elements.media.paused=!0,c(Oe.elements.media,"pause")}),Oe.embed.bind(e.SC.Widget.Events.PLAY_PROGRESS,function(e){Oe.elements.media.seeking=!1,Oe.elements.media.currentTime=e.currentPosition/1e3,c(Oe.elements.media,"timeupdate")}),Oe.embed.bind(e.SC.Widget.Events.LOAD_PROGRESS,function(e){Oe.elements.media.buffered=e.loadProgress,c(Oe.elements.media,"progress"),1===parseInt(e.loadProgress)&&c(Oe.elements.media,"canplaythrough")}),Oe.embed.bind(e.SC.Widget.Events.FINISH,function(){Oe.elements.media.paused=!0,c(Oe.elements.media,"ended")})})}function $(){"play"in Oe.elements.media&&Oe.elements.media.play()}function G(){"pause"in Oe.elements.media&&Oe.elements.media.pause()}function K(e){return r.is.boolean(e)||(e=Oe.elements.media.paused),e?$():G(),e}function Z(e){r.inArray(["start","end","all","none","toggle"],e)||(e="toggle");var n=Number(Oe.elements.media.currentTime);switch(e){case"start":Ve.loop.end&&Ve.loop.end<=n&&(Ve.loop.end=null),Ve.loop.start=n,Ve.loop.indicator.start=Oe.elements.display.played.value;break;case"end":if(Ve.loop.start>=n)return;Ve.loop.end=n,Ve.loop.indicator.end=Oe.elements.display.played.value;break;case"all":Ve.loop.start=0,Ve.loop.end=Oe.elements.media.duration-2,Ve.loop.indicator.start=0,Ve.loop.indicator.end=100;break;case"toggle":Ve.loop.active?(Ve.loop.start=0,Ve.loop.end=null):(Ve.loop.start=0,Ve.loop.end=Oe.elements.media.duration-2);break;default:Ve.loop.start=0,Ve.loop.end=null}Ve.loop.active=r.is.number(Ve.loop.start)&&r.is.number(Ve.loop.end);var s=(he(Ve.loop.start,p('[data-plyr-loop="start"]')),null);r.is.number(Ve.loop.end)&&(s=he(Ve.loop.end,t.querySelector('[data-loop__value="loopout"]'))),Ve.loop.active}function ee(e){return r.is.event(e)?e=parseFloat(e.target.value):r.is.number(e)||(e=parseFloat(Oe.storage.speed||Ve.speed.selected)),e<.1&&(e=.1),e>2&&(e=2),r.is.array(Ve.speed.options)?(Ve.speed.selected=e,Oe.elements.media.playbackRate=e,void W({speed:e})):void Re("Invalid speeds format")}function te(){return Ve.speed.selected.toFixed(1).toString().replace(".0","")+"×"}function ne(e){r.is.number(e)||(e=Ve.seekTime),ae(Oe.elements.media.currentTime-e)}function se(e){r.is.number(e)||(e=Ve.seekTime),ae(Oe.elements.media.currentTime+e)}function ae(e){var t=0,n=Oe.elements.media.paused,s=le();r.is.number(e)?t=e:r.is.event(e)&&r.inArray(["input","change"],e.type)&&(t=e.target.value/e.target.max*s),t<0?t=0:t>s&&(t=s),Ee(t);try{Oe.elements.media.currentTime=t.toFixed(4)}catch(e){}if(r.inArray(l.embed,Oe.type)){switch(Oe.type){case"youtube":Oe.embed.seekTo(t);break;case"vimeo":Oe.embed.setCurrentTime(t.toFixed(0));break;case"soundcloud":Oe.embed.seekTo(1e3*t)}n&&G(),c(Oe.elements.media,"timeupdate"),Oe.elements.media.seeking=!0,c(Oe.elements.media,"seeking")}De("Seeking to "+Oe.elements.media.currentTime+" seconds")}function le(){var e=parseInt(Ve.duration),t=0;return null===Oe.elements.media.duration||isNaN(Oe.elements.media.duration)||(t=Oe.elements.media.duration),isNaN(e)?t:e}function re(){r.toggleClass(Oe.elements.container,Ve.classes.playing,!Oe.elements.media.paused),r.toggleClass(Oe.elements.container,Ve.classes.stopped,Oe.elements.media.paused),we(Oe.elements.media.paused)}function ie(){s={x:e.pageXOffset||0,y:e.pageYOffset||0}}function oe(){e.scrollTo(s.x,s.y)}function ue(e){var n=o.fullscreen;if(n){if(!e||e.type!==i.eventType)return i.isFullScreen(Oe.elements.container)?i.cancelFullScreen():(ie(),i.requestFullScreen(Oe.elements.container)),void(Oe.fullscreen.active=i.isFullScreen(Oe.elements.container));Oe.fullscreen.active=i.isFullScreen(Oe.elements.container)}else Oe.fullscreen.active=!Oe.fullscreen.active,t.body.style.overflow=Oe.fullscreen.active?"hidden":"";r.toggleClass(Oe.elements.container,Ve.classes.fullscreen.active,Oe.fullscreen.active),f(Oe.fullscreen.active),Oe.elements.buttons&&Oe.elements.buttons.fullscreen&&r.toggleState(Oe.elements.buttons.fullscreen,Oe.fullscreen.active),c(Oe.elements.container,Oe.fullscreen.active?"enterfullscreen":"exitfullscreen",!0),!Oe.fullscreen.active&&n&&oe()}function ce(n){var s=Oe.elements.settings.menu.parentNode,a=n.target,l=t.getElementById(a.getAttribute("aria-controls")),i="false"===a.getAttribute("aria-expanded");if(r.is.htmlElement(l)){var o,u,c,d="tabpanel"===l.getAttribute("role");if(d){var p=s.querySelector('[role="tabpanel"][aria-hidden="false"]');c=p.parentNode,[].forEach.call(s.querySelectorAll('[aria-controls="'+p.getAttribute("id")+'"]'),function(e){e.setAttribute("aria-expanded",!1)}),c.style.width=p.scrollWidth+"px",c.style.height=p.scrollHeight+"px",p.setAttribute("aria-hidden",!0),p.setAttribute("tabindex",-1);var m=l.cloneNode(!0);m.style.position="absolute",m.style.opacity=0,m.setAttribute("aria-hidden",!1),c.appendChild(m),o=m.scrollWidth,u=m.scrollHeight,r.removeElement(m)}l.setAttribute("aria-hidden",!i),a.setAttribute("aria-expanded",i),l.removeAttribute("tabindex"),d&&(c.style.width=o+"px",c.style.height=u+"px",e.setTimeout(function(){c.style.width="",c.style.height=""},300))}}function de(e){if(r.is.boolean(e)||(e=!Oe.elements.media.muted),r.toggleState(Oe.elements.buttons.mute,e),Oe.elements.media.muted=e,0===Oe.elements.media.volume&&pe(Ve.volume),r.inArray(l.embed,Oe.type)){switch(Oe.type){case"youtube":Oe.embed[Oe.elements.media.muted?"mute":"unMute"]();break;case"vimeo":case"soundcloud":Oe.embed.setVolume(Oe.elements.media.muted?0:parseFloat(Ve.volume/10))}c(Oe.elements.media,"volumechange")}}function pe(e){var t=10,n=0;if(r.is.event(e)&&(e=e.target.value),r.is.undefined(e)&&(e=Oe.storage.volume),(null===e||isNaN(e))&&(e=Ve.volume),e>t&&(e=t),e<n&&(e=n),Oe.elements.media.volume=parseFloat(e/t),Oe.elements.display.volume&&(Oe.elements.display.volume.value=e),r.inArray(l.embed,Oe.type)){switch(Oe.type){case"youtube":Oe.embed.setVolume(100*Oe.elements.media.volume);break;case"vimeo":case"soundcloud":Oe.embed.setVolume(Oe.elements.media.volume)}c(Oe.elements.media,"volumechange")}0===e?Oe.elements.media.muted=!0:Oe.elements.media.muted&&e>0&&de()}function me(e){var t=Oe.elements.media.muted?0:10*Oe.elements.media.volume;r.is.number(e)||(e=1),pe(t+e)}function fe(e){var t=Oe.elements.media.muted?0:10*Oe.elements.media.volume;r.is.number(e)||(e=1),pe(t-e)}function ye(){var e=Oe.elements.media.muted?0:10*Oe.elements.media.volume;Oe.supported.full&&(Oe.elements.inputs.volume&&(Oe.elements.inputs.volume.value=e),Oe.elements.display.volume&&(Oe.elements.display.volume.value=e)),W({volume:e}),r.toggleClass(Oe.elements.container,Ve.classes.muted,0===e),Oe.supported.full&&Oe.elements.buttons.mute&&r.toggleState(Oe.elements.buttons.mute,0===e)}function ge(e){var t="waiting"===e.type;clearTimeout(je.loading),je.loading=setTimeout(function(){r.toggleClass(Oe.elements.container,Ve.classes.loading,t),we(t)},t?250:0)}function be(e){if(Oe.supported.full){var t=Oe.elements.display.played,n=0,s=le();if(e)switch(e.type){case"timeupdate":case"seeking":if(Oe.elements.controls.pressed)return;n=r.getPercentage(Oe.elements.media.currentTime,s),"timeupdate"===e.type&&Oe.elements.inputs.seek&&(Oe.elements.inputs.seek.value=n);break;case"playing":case"progress":t=Oe.elements.display.buffer,n=function(){var e=Oe.elements.media.buffered;return e&&e.length?r.getPercentage(e.end(0),s):r.is.number(e)?100*e:0}()}r.is.number(Ve.loop.start)&&r.is.number(Ve.loop.end)&&Oe.elements.media.currentTime>=Ve.loop.end&&ae(Ve.loop.start),ve(t,n)}}function ve(e,t){if(Oe.supported.full){if(r.is.undefined(t)&&(t=0),r.is.undefined(e)){if(!r.is.htmlElement(Oe.elements.display.buffer))return;e=Oe.elements.display.buffer}if(r.is.htmlElement(e)){e.value=t;var n=e.getElementsByTagName("span")[0];r.is.htmlElement(n)&&(n.childNodes[0].nodeValue=t)}}}function he(e,t){if(t){isNaN(e)&&(e=0);var n=parseInt(e%60),s=parseInt(e/60%60),a=parseInt(e/60/60%60),l=parseInt(le()/60/60%60)>0;n=("0"+n).slice(-2),s=("0"+s).slice(-2);var r=(l?a+":":"")+s+":"+n;return t.textContent=r,r}}function ke(){if(Oe.supported.full){var e=le()||0;!Oe.elements.display.duration&&Ve.displayDuration&&Oe.elements.media.paused&&he(e,Oe.elements.display.currentTime),Oe.elements.display.duration&&he(e,Oe.elements.display.duration),Ae()}}function Ce(e){he(Oe.elements.media.currentTime,Oe.elements.display.currentTime),e&&"timeupdate"===e.type&&Oe.elements.media.seeking||be(e)}function Ee(e){r.is.number(e)||(e=0);var t=le(),n=r.getPercentage(e,t);Oe.elements.progress&&Oe.elements.display.played&&(Oe.elements.display.played.value=n),Oe.elements.buttons&&Oe.elements.inputs.seek&&(Oe.elements.inputs.seek.value=n)}function Ae(e){var t=le();if(Ve.tooltips.seek&&r.is.htmlElement(Oe.elements.inputs.seek)&&r.is.htmlElement(Oe.elements.display.seekTooltip)&&0!==t){var n=Oe.elements.inputs.seek.getBoundingClientRect(),s=0,a=Ve.classes.tooltip+"--visible";if(r.is.event(e))s=100/n.width*(e.pageX-n.left);else{if(!r.hasClass(Oe.elements.display.seekTooltip,a))return;s=Oe.elements.display.seekTooltip.style.left.replace("%",""); +}s<0?s=0:s>100&&(s=100),he(t/100*s,Oe.elements.display.seekTooltip),Oe.elements.display.seekTooltip.style.left=s+"%",r.is.event(e)&&r.inArray(["mouseenter","mouseleave"],e.type)&&r.toggleClass(Oe.elements.display.seekTooltip,a,"mouseenter"===e.type)}}function we(t){if(Ve.hideControls&&"audio"!==Oe.type){var n=0,s=!1,a=t,l=r.hasClass(Oe.elements.container,Ve.classes.loading);if(r.is.boolean(t)||(t&&t.type?(s="enterfullscreen"===t.type,a=r.inArray(["mousemove","touchstart","mouseenter","focus"],t.type),r.inArray(["mousemove","touchmove"],t.type)&&(n=2e3),"focus"===t.type&&(n=3e3)):a=r.hasClass(Oe.elements.container,Ve.classes.hideControls)),e.clearTimeout(je.hover),a||Oe.elements.media.paused||l){if(r.toggleClass(Oe.elements.container,Ve.classes.hideControls,!1),Oe.elements.media.paused||l)return;o.touch&&(n=3e3)}a&&Oe.elements.media.paused||(je.hover=e.setTimeout(function(){(!Oe.elements.controls.pressed&&!Oe.elements.controls.hover||s)&&r.toggleClass(Oe.elements.container,Ve.classes.hideControls,!0)},n))}}function Se(e){if(!r.is.undefined(e))return void Te(e);var t;switch(Oe.type){case"youtube":t=Oe.embed.getVideoUrl();break;case"vimeo":Oe.embed.getVideoUrl.then(function(e){t=e});break;case"soundcloud":Oe.embed.getCurrentSound(function(e){t=e.permalink_url});break;default:t=Oe.elements.media.currentSrc}return t||""}function Te(e){function t(){if(Oe.embed=null,m("media"),m("captions"),m("wrapper"),Oe.elements.container&&Oe.elements.container.removeAttribute("class"),"type"in e&&(Oe.type=e.type,"video"===Oe.type)){var t=e.sources[0];"type"in t&&r.inArray(l.embed,t.type)&&(Oe.type=t.type)}switch(Oe.supported=r.checkSupport(Oe.type,Ve.inline),Oe.type){case"video":Oe.elements.media=r.createElement("video");break;case"audio":Oe.elements.media=r.createElement("audio");break;case"youtube":case"vimeo":case"soundcloud":Oe.elements.media=r.createElement("div"),Oe.embedId=e.sources[0].src}r.prependChild(Oe.elements.container,Oe.elements.media),r.is.boolean(e.autoplay)&&(Ve.autoplay=e.autoplay),r.inArray(l.html5,Oe.type)&&(Ve.crossorigin&&Oe.elements.media.setAttribute("crossorigin",""),Ve.autoplay&&Oe.elements.media.setAttribute("autoplay",""),"poster"in e&&Oe.elements.media.setAttribute("poster",e.poster),Ve.loop.active&&Oe.elements.media.setAttribute("loop",""),Ve.inline&&Oe.elements.media.setAttribute("playsinline","")),r.toggleClass(Oe.elements.container,Ve.classes.fullscreen.active,Oe.fullscreen.active),r.toggleClass(Oe.elements.container,Ve.classes.captions.active,Oe.captions.enabled),D(),r.inArray(l.html5,Oe.type)&&y("source",e.sources),Y(),r.inArray(l.html5,Oe.type)&&("tracks"in e&&y("track",e.tracks),Oe.elements.media.load()),(r.inArray(l.html5,Oe.type)||r.inArray(l.embed,Oe.type)&&!Oe.supported.full)&&(Ne(),Le()),Ve.title=e.title,B()}return r.is.object(e)&&"sources"in e&&e.sources.length?(r.toggleClass(Oe.elements.container,Ve.classes.ready,!1),G(),Ee(),ve(),Pe(),void _e(t,!1)):void Re("Invalid source format")}function xe(e){"video"===Oe.type&&Oe.elements.media.setAttribute("poster",e)}function Fe(){function n(){var e=K(),t=Oe.elements.buttons[e?"play":"pause"],n=Oe.elements.buttons[e?"pause":"play"];if(n){var s=r.hasClass(t,Ve.classes.tabFocus);setTimeout(function(){r.is.htmlElement(n)&&n.focus(),s&&(r.toggleClass(t,Ve.classes.tabFocus,!1),r.toggleClass(n,Ve.classes.tabFocus,!0))},100)}}function s(e){return e.keyCode?e.keyCode:e.which}function a(e){r.toggleClass(d("."+Ve.classes.tabFocus),Ve.classes.tabFocus,!1),Oe.elements.container.contains(e)&&r.toggleClass(e,Ve.classes.tabFocus,!0)}function l(e){function t(){var e=Oe.elements.media.duration;r.is.number(e)&&ae(e/10*(a-48))}var a=s(e),l="keydown"===e.type,i=l&&a===c;if(r.is.number(a))if(l){var u=[48,49,50,51,52,53,54,56,57,32,75,38,40,77,39,37,70,67,73,76,79],d=[38,40];if(r.inArray(d,a)){var p=r.getFocusElement();if(r.is.htmlElement(p)&&"radio"===r.getFocusElement().type)return}switch(r.inArray(u,a)&&(e.preventDefault(),e.stopPropagation()),a){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:i||t();break;case 32:case 75:i||n();break;case 38:me();break;case 40:fe();break;case 77:i||de();break;case 39:se();break;case 37:ne();break;case 70:ue();break;case 67:i||j();break;case 73:Z("start");break;case 76:Z();break;case 79:Z("end")}!o.fullscreen&&Oe.fullscreen.active&&27===a&&ue(),c=a}else c=null}var u=Oe.browser.isIE?"change":"input";if(Ve.keyboardShortcuts.focused){var c=null;Ve.keyboardShortcuts.global&&r.on(e,"keydown keyup",function(e){var t=s(e),n=r.getFocusElement(),a=[48,49,50,51,52,53,54,56,57,75,77,70,67,73,76,79];!r.inArray(a,t)||r.is.htmlElement(n)&&r.matches(n,Ve.selectors.editable)||l(e)},!1),r.on(Oe.elements.container,"keydown keyup",l,!1)}r.on(e,"keyup",function(e){var t=s(e),n=r.getFocusElement();9===t&&a(n)}),r.on(t.body,"click",function(){r.toggleClass(p("."+Ve.classes.tabFocus),Ve.classes.tabFocus,!1)});for(var m in Oe.elements.buttons){var f=Oe.elements.buttons[m];r.on(f,"blur",function(){r.toggleClass(f,"tab-focus",!1)})}var y=function(e,t,n){r.is.function(t)&&t.call(this,e),r.is.function(n)&&n.call(this,e)};r.proxy(Oe.elements.buttons.play,"click",Ve.listeners.play,n),r.proxy(Oe.elements.buttons.playLarge,"click",Ve.listeners.play,n),r.proxy(Oe.elements.buttons.pause,"click",Ve.listeners.pause,n),r.proxy(Oe.elements.buttons.restart,"click",Ve.listeners.restart,ae),r.proxy(Oe.elements.buttons.rewind,"click",Ve.listeners.rewind,ne),r.proxy(Oe.elements.buttons.forward,"click",Ve.listeners.forward,se),r.proxy(Oe.elements.buttons.mute,"click",Ve.listeners.mute,de),r.proxy(Oe.elements.buttons.captions,"click",Ve.listeners.captions,j),r.proxy(Oe.elements.buttons.fullscreen,"click",Ve.listeners.fullscreen,ue),r.proxy(Oe.elements.buttons.pip,"click",Ve.listeners.pip,function(e){o.pip&&Oe.elements.media.webkitSetPresentationMode("picture-in-picture"===Oe.elements.media.webkitPresentationMode?"inline":"picture-in-picture")}),r.proxy(Oe.elements.buttons.airplay,"click",Ve.listeners.airplay,function(e){o.airplay&&Oe.elements.media.webkitShowPlaybackTargetPicker()}),r.on(Oe.elements.settings.menu,"click",ce),r.on(t.body,"click",function(e){var t=Oe.elements.settings.menu,n=t.querySelector("form");"true"===n.getAttribute("aria-hidden")||t.contains(e.target)||n.setAttribute("aria-hidden",!0)}),r.on(Oe.elements.settings.menu,"click",function(e){r.matches(e.target,Ve.selectors.inputs.language)?y.call(this,e,Ve.listeners.language,L):r.matches(e.target,Ve.selectors.inputs.quality)?y.call(this,e,Ve.listeners.quality,function(){Re("Set quality")}):r.matches(e.target,Ve.selectors.inputs.speed)?y.call(this,e,Ve.listeners.speed,ee):r.matches(e.target,Ve.selectors.buttons.loop)&&y.call(this,e,Ve.listeners.loop,function(){var t=e.target.getAttribute("data-loop__value")||e.target.getAttribute("data-loop__type");r.inArray(["start","end","all","none"],t)&&Z(t)})}),r.proxy(Oe.elements.inputs.seek,u,Ve.listeners.seek,ae),r.proxy(Oe.elements.inputs.volume,u,Ve.listeners.volume,pe),r.on(Oe.elements.progress,"mouseenter mouseleave mousemove",Ae),Ve.hideControls&&(r.on(Oe.elements.container,"mouseenter mouseleave mousemove touchstart touchend touchcancel touchmove enterfullscreen",we),r.on(Oe.elements.controls,"mouseenter mouseleave",function(e){Oe.elements.controls.hover="mouseenter"===e.type}),r.on(Oe.elements.controls,"mousedown mouseup touchstart touchend touchcancel",function(e){Oe.elements.controls.pressed=r.inArray(["mousedown","touchstart"],e.type)}),r.on(Oe.elements.controls,"focus blur",we,!0,!0)),r.proxy(Oe.elements.inputs.volume,"wheel",Ve.listeners.volume,function(e){var t=e.webkitDirectionInvertedFromDevice,n=.2,s=0;(e.deltaY<0||e.deltaX>0)&&(t?(fe(n),s=-1):(me(n),s=1)),(e.deltaY>0||e.deltaX<0)&&(t?(me(n),s=1):(fe(n),s=-1)),(1===s&&Oe.elements.media.volume<1||s===-1&&Oe.elements.media.volume>0)&&e.preventDefault()},!1),o.fullscreen&&r.on(t,i.eventType,ue)}function Ie(){if(r.on(Oe.elements.media,"timeupdate seeking",Ce),r.on(Oe.elements.media,"durationchange loadedmetadata",ke),r.on(Oe.elements.media,"ended",function(){"video"===Oe.type&&Ve.showPosterOnEnd&&("video"===Oe.type&&q(),ae(),Oe.elements.media.load())}),r.on(Oe.elements.media,"progress playing",be),r.on(Oe.elements.media,"volumechange",ye),r.on(Oe.elements.media,"play pause ended",re),r.on(Oe.elements.media,"waiting canplay seeked",ge),Ve.clickToPlay&&"audio"!==Oe.type){var e=p("."+Ve.classes.videoWrapper);if(!e)return;e.style.cursor="pointer",r.on(e,"click",function(){Ve.hideControls&&o.touch&&!Oe.elements.media.paused||(Oe.elements.media.paused?$():Oe.elements.media.ended?(ae(),$()):G())})}Ve.disableContextMenu&&r.on(Oe.elements.media,"contextmenu",function(e){e.preventDefault()},!1),r.on(Oe.elements.media,Ve.events.concat(["keyup","keydown"]).join(" "),function(e){c(Oe.elements.container,e.type,!0)})}function Pe(){if(r.inArray(l.html5,Oe.type)){for(var e=Oe.elements.media.querySelectorAll("source"),t=0;t<e.length;t++)r.removeElement(e[t]);Oe.elements.media.setAttribute("src","https://cdn.selz.com/plyr/blank.mp4"),Oe.elements.media.load(),De("Cancelled network requests")}}function _e(n,s){function a(){r.is.boolean(s)||(s=!0),r.is.function(n)&&n.call(Oe.original),s&&(Oe.elements.container.parentNode.replaceChild(Oe.original,Oe.elements.container),t.body.style.overflow="",c(Oe.original,"destroyed",!0))}switch(Oe.type){case"youtube":e.clearInterval(je.buffering),e.clearInterval(je.playing),Oe.embed.destroy(),a();break;case"vimeo":Oe.embed.unload().then(a),e.setTimeout(a,200);break;case"video":case"audio":R(!0),a()}}function Ne(){return Oe.supported.full?(r.is.htmlElement(Oe.elements.controls)||(M(),Fe()),void(r.is.htmlElement(Oe.elements.controls)&&(Ie(),R(),I(),P(),pe(),ye(),ee(),Z(),Ce(),re()))):(Re("Basic support only",Oe.type),m("controls"),m("buttons.play"),void R(!0))}function Le(){c(Oe.elements.container,"ready",!0),Ve.autoplay&&$()}function qe(e){if(!r.is.htmlElement(e))return Be("Setup failed. No suitable element passed."),!1;if(!Ve.enabled)return!1;if(!r.checkSupport().basic)return!1;if(e.plyr)return!1;var t=e.tagName.toLowerCase();switch(t){case"div":if(Oe.type=e.getAttribute("data-type"),Oe.embedId=e.getAttribute("data-video-id"),r.is.empty(Oe.type)||r.is.empty(Oe.embedId))return!1;e.removeAttribute("data-type"),e.removeAttribute("data-video-id");break;case"iframe":break;case"video":case"audio":Oe.type=t,Ve.crossorigin=null!==e.getAttribute("crossorigin"),Ve.autoplay=Ve.autoplay||null!==e.getAttribute("autoplay"),Ve.inline=null!==e.getAttribute("playsinline"),Ve.loop.active=Ve.loop||null!==e.getAttribute("loop");break;default:return!1}if(Oe.browser=r.getBrowser(),H(),Oe.supported=r.checkSupport(Oe.type,Ve.inline),!Oe.supported.basic)return!1;if(Oe.elements.container=r.wrap(e,r.createElement("div")),Oe.original=e.cloneNode(!0),Oe.elements.container.setAttribute("tabindex",0),D(),De(Oe.browser.name+" "+Oe.browser.version),Y(),Ve.debug){var n=Ve.events.concat(["setup","statechange","enterfullscreen","exitfullscreen","captionsenabled","captionsdisabled"]);r.on(Oe.elements.container,n.join(" "),function(e){De(["event:",e.type].join(" ").trim())})}return(r.inArray(l.html5,Oe.type)||r.inArray(l.embed,Oe.type)&&!Oe.supported.full)&&(Ne(),Le(),B()),!0}var Oe=this,je={},Me={};r.is.string(n)&&(n=t.querySelectorAll(n)),(e.jQuery&&n instanceof jQuery||r.is.nodeList(n)||r.is.array(n))&&(n=n[0]);var Ve=r.extend({},a,u,function(){try{return JSON.parse(n.getAttribute("data-plyr"))}catch(e){}}());Oe.elements={container:null,buttons:{},display:{},progress:{},inputs:{},settings:{menu:null,panes:{},tabs:{}},media:n,captions:null},Oe.captions={enabled:!1,captions:[],tracks:[],currentTrack:null},Oe.fullscreen={active:!1};var De=function(){},Re=function(){},Be=function(){};return Ve.debug&&"console"in e&&(De=e.console.log,Re=e.console.warn,Be=e.console.error),De("Config",Ve),De("Support",o),Me={getOriginal:function(){return Oe.original},getContainer:function(){return Oe.elements.container},getEmbed:function(){return Oe.embed},getMedia:function(){return Oe.elements.media},getType:function(){return Oe.type},getDuration:le,getCurrentTime:function(){return Oe.elements.media.currentTime},getVolume:function(){return Oe.elements.media.volume},isMuted:function(){return Oe.elements.media.muted},isReady:function(){return r.hasClass(Oe.elements.container,Ve.classes.ready)},isLoading:function(){return r.hasClass(Oe.elements.container,Ve.classes.loading)},isPaused:function(){return Oe.elements.media.paused},isLooping:function(){return Ve.loop.active},on:function(e,t){return r.on(Oe.elements.container,e,t),this},play:$,pause:G,loop:Z,stop:function(){G(),ae()},restart:ae,rewind:ne,forward:se,seek:ae,source:Se,poster:xe,setVolume:pe,setSpeed:ee,togglePlay:K,toggleMute:de,toggleCaptions:j,toggleFullscreen:ue,toggleControls:we,setLanguage:L,isFullscreen:Oe.fullscreen.active,support:function(e){return o.mime(Oe,e)},destroy:_e},qe(Oe.elements.media)?Me:null}var s={x:0,y:0},a={enabled:!0,title:"",debug:!1,autoplay:!1,seekTime:10,volume:10,duration:null,displayDuration:!0,loadSprite:!0,iconPrefix:"plyr",iconUrl:"https://cdn.plyr.io/2.0.10/plyr.svg",clickToPlay:!0,hideControls:!0,showPosterOnEnd:!1,disableContextMenu:!0,quality:{default:"auto",selected:"auto"},loop:{active:!1,start:0,end:null,indicator:{start:0,end:0}},speed:{selected:1,options:[.25,.5,.75,1,1.25,1.5,2]},keyboardShortcuts:{focused:!0,global:!1},tooltips:{controls:!1,seek:!0},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"]',forward:'[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",played:".plyr__progress--played",loop:".plyr__progress--loop",volume:".plyr__volume--display"},progress:".plyr__progress",captions:".plyr__captions",menu:{quality:".js-plyr__menu__list--quality"}},classes:{setup:"plyr--setup",ready:"plyr--ready",videoWrapper:"plyr__video-wrapper",embedWrapper:"plyr__video-embed",control:"plyr__control",type:"plyr--{0}",stopped:"plyr--stopped",playing:"plyr--playing",muted:"plyr--muted",loading:"plyr--loading",hover:"plyr--hover",tooltip:"plyr__tooltip",hidden:"plyr__sr-only",hideControls:"plyr--hide-controls",isIos:"plyr--is-ios",isTouch:"plyr--is-touch",menu:{value:"plyr__menu__value",badge:"plyr__badge"},captions:{enabled:"plyr--captions-enabled",active:"plyr--captions-active"},fullscreen:{enabled:"plyr--fullscreen-enabled",active:"plyr--fullscreen-active"},pip:{enabled:"plyr--pip-enabled",active:"plyr--pip-active"},airplay:{enabled:"plyr--airplay-enabled",active:"plyr--airplay-active"},tabFocus:"tab-focus"},captions:{active:!1,language:e.navigator.language.split("-")[0]},fullscreen:{enabled:!0,fallback:!0,allowAudio:!1},storage:{enabled:!0,key:"plyr"},controls:["play-large","play","progress","current-time","mute","volume","captions","settings","pip","airplay","fullscreen"],i18n:{restart:"Restart",rewind:"Rewind {seektime} secs",play:"Play",pause:"Pause",forward:"Forward {seektime} secs",seek:"Seek",played:"Played",buffered:"Buffered",currentTime:"Current time",duration:"Duration",volume:"Volume",toggleMute:"Toggle Mute",toggleCaptions:"Toggle Captions",toggleFullscreen:"Toggle Fullscreen",frameTitle:"Player for {title}",captions:"Captions",settings:"Settings",speed:"Speed",quality:"Quality",loop:"Loop",start:"Start",end:"End",all:"All",reset:"Reset",none:"None"},urls:{vimeo:{api:"https://player.vimeo.com/api/player.js"},youtube:{api:"https://www.youtube.com/iframe_api"},soundcloud:{api:"https://w.soundcloud.com/player/api.js"}},listeners:{seek:null,play:null,pause:null,restart:null,rewind:null,forward: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"],logPrefix:""},l={embed:["youtube","vimeo","soundcloud"],html5:["video","audio"]},r={is:{object:function(e){return null!==e&&"object"==typeof e&&e.constructor===Object},array:function(e){return null!==e&&Array.isArray(e)},number:function(e){return null!==e&&("number"==typeof e&&!isNaN(e-0)||"object"==typeof e&&e.constructor===Number)},string:function(e){return null!==e&&("string"==typeof e||"object"==typeof e&&e.constructor===String)},boolean:function(e){return null!==e&&"boolean"==typeof e},nodeList:function(e){return null!==e&&e instanceof NodeList},htmlElement:function(e){return null!==e&&e instanceof HTMLElement},function:function(e){return null!==e&&"function"==typeof e},event:function(e){return null!==e&&e instanceof Event},cue:function(t){return null!==t&&(t instanceof e.TextTrackCue||t instanceof e.VTTCue)},track:function(t){return null!==t&&t instanceof e.TextTrack},undefined:function(e){return null!==e&&"undefined"==typeof e},empty:function(e){return null===e||this.undefined(e)||(this.string(e)||this.array(e)||this.nodeList(e))&&0===e.length||this.object(e)&&0===Object.keys(e).length}},getBrowser:function(){var e,t,n,s=navigator.userAgent,a=navigator.appName,l=""+parseFloat(navigator.appVersion),r=parseInt(navigator.appVersion,10),i=!1,o=!1,u=!1,c=!1;return navigator.appVersion.indexOf("Windows NT")!==-1&&navigator.appVersion.indexOf("rv:11")!==-1?(i=!0,a="IE",l="11"):(t=s.indexOf("MSIE"))!==-1?(i=!0,a="IE",l=s.substring(t+5)):(t=s.indexOf("Chrome"))!==-1?(u=!0,a="Chrome",l=s.substring(t+7)):(t=s.indexOf("Safari"))!==-1?(c=!0,a="Safari",l=s.substring(t+7),(t=s.indexOf("Version"))!==-1&&(l=s.substring(t+8))):(t=s.indexOf("Firefox"))!==-1?(o=!0,a="Firefox",l=s.substring(t+8)):(e=s.lastIndexOf(" ")+1)<(t=s.lastIndexOf("/"))&&(a=s.substring(e,t),l=s.substring(t+1),a.toLowerCase()===a.toUpperCase()&&(a=navigator.appName)),(n=l.indexOf(";"))!==-1&&(l=l.substring(0,n)),(n=l.indexOf(" "))!==-1&&(l=l.substring(0,n)),r=parseInt(""+l,10),isNaN(r)&&(l=""+parseFloat(navigator.appVersion),r=parseInt(navigator.appVersion,10)),{name:a,version:r,isIE:i,isOldIE:i&&r<=9,isFirefox:o,isChrome:u,isSafari:c,isIPhone:/(iPhone|iPod)/gi.test(navigator.platform),isIos:/(iPad|iPhone|iPod)/gi.test(navigator.platform)}},checkSupport:function(e,t){var n=!1,s=!1,a=r.getBrowser(),l=a.isIPhone&&t&&o.inline;switch(e){case"video":n=o.video,s=n&&!a.isOldIE&&(!a.isIPhone||l);break;case"audio":n=o.audio,s=n&&!a.isOldIE;break;case"youtube":n=o.video,s=n&&!a.isOldIE&&(!a.isIPhone||l);break;case"vimeo":case"soundcloud":n=!0,s=!a.isOldIE&&!a.isIos;break;default:n=o.audio&&o.video,s=n&&!a.isOldIE}return{basic:n,full:s}},injectScript:function(e){if(!t.querySelectorAll('script[src="'+e+'"]').length){var n=t.createElement("script");n.src=e;var s=t.getElementsByTagName("script")[0];s.parentNode.insertBefore(n,s)}},inFrame:function(){try{return e.self!==e.top}catch(e){return!0}},inArray:function(e,t){return r.is.array(e)&&e.indexOf(t)!==-1},replaceAll:function(e,t,n){return e.replace(new RegExp(t.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g,"\\$1"),"g"),n)},wrap:function(e,t){e.length||(e=[e]);for(var n=e.length-1;n>=0;n--){var s=n>0?t.cloneNode(!0):t,a=e[n],l=a.parentNode,r=a.nextSibling;return s.appendChild(a),r?l.insertBefore(s,r):l.appendChild(s),s}},removeElement:function(e){r.is.htmlElement(e)&&r.is.htmlElement(e.parentNode)&&e.parentNode.removeChild(e)},prependChild:function(e,t){e.insertBefore(t,e.firstChild)},insertAfter:function(e,t){t.parentNode.insertBefore(e,t.nextSibling)},createElement:function(e,n,s){var a=t.createElement(e);return r.is.object(n)&&r.setAttributes(a,n),r.is.string(s)&&(a.textContent=s),a},insertElement:function(e,t,n,s){var a=r.createElement(e,n,s);r.prependChild(t,a)},emptyElement:function(e){for(var t=e.childNodes.length;t--;)e.removeChild(e.lastChild)},setAttributes:function(e,t){for(var n in t)e.setAttribute(n,t[n])},getAttributesFromSelector:function(e,t){if(!r.is.string(e)||r.is.empty(e))return{};var n={};return e.split(",").forEach(function(e){e=e.trim();var s=e.charAt(0);switch(s){case".":var a=e.replace(".","");r.is.object(t)&&r.is.string(t.class)&&(t.class+=" "+a),n.class=a;break;case"#":n.id=e.replace("#","");break;case"[":e=e.replace(/[\[\]]/g,"");var l=e.split("="),i=l[0],o=l.length>1?l[1].replace(/[\"\']/g,""):"";n[i]=o}}),n},toggleClass:function(e,t,n){if(e)if(e.classList)e.classList[n?"add":"remove"](t);else{var s=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=s+(n?" "+t:"")}},hasClass:function(e,t){return!!e&&(e.classList?e.classList.contains(t):new RegExp("(\\s|^)"+t+"(\\s|$)").test(e.className))},matches:function(e,n){var s=Element.prototype,a=s.matches||s.webkitMatchesSelector||s.mozMatchesSelector||s.msMatchesSelector||function(e){return[].indexOf.call(t.querySelectorAll(e),this)!==-1};return a.call(e,n)},getFocusElement:function(){var e=t.activeElement;return e=e&&e!==t.body?t.querySelector(":focus"):null},proxy:function(e,t,n,s,a,l){r.on(e,t,function(t){n&&n.apply(e,[t]),s.apply(e,[t])},a,l)},toggleListener:function(e,t,n,s,a,l){if(t=t.split(" "),r.is.boolean(l)||(l=!1),r.is.boolean(a)||(a=!0),e instanceof NodeList){var i=1===arguments.length?[arguments[0]]:Array.apply(null,arguments);return i.shift(),void[].forEach.call(e,function(e){e instanceof Node&&r.toggleListener.apply(null,[e].concat(i))})}var u=l;o.passiveListeners&&(u={passive:a,capture:l}),t.forEach(function(t){e[s?"addEventListener":"removeEventListener"](t,n,u)})},on:function(e,t,n,s,a){r.is.undefined(e)||r.toggleListener(e,t,n,!0,s,a)},off:function(e,t,n,s,a){r.is.undefined(e)||r.toggleListener(e,t,n,!1,s,a)},event:function(n,s,a,l){if(n&&s){r.is.boolean(a)||(a=!1);var i;r.is.function(e.CustomEvent)?i=e.CustomEvent:(i=function(e,n){n=n||{bubbles:!1,cancelable:!1,detail:void 0};var s=t.createEvent("CustomEvent");return s.initCustomEvent(e,n.bubbles,n.cancelable,n.detail),s},i.prototype=e.Event.prototype);var o=new i(s,{bubbles:a,detail:l});n.dispatchEvent(o)}},toggleState:function(e,t){if(e)return t=r.is.boolean(t)?t:!e.getAttribute("aria-pressed"),e.setAttribute("aria-pressed",t),t},getPercentage:function(e,t){return 0===e||0===t||isNaN(e)||isNaN(t)?0:(e/t*100).toFixed(2)},extend:function(){var e=arguments;if(e.length){if(1===e.length)return e[0];var t=Array.prototype.shift.call(e);r.is.object(t)||(t={});for(var n=e.length,s=0;s<n;s++){var a=e[s];r.is.object(a)||(a={});for(var l in a)a[l]&&a[l].constructor&&a[l].constructor===Object?(t[l]=t[l]||{},r.extend(t[l],a[l])):t[l]=a[l]}return t}},parseYouTubeId:function(e){var t=/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;return e.match(t)?RegExp.$2:e},stripHTML:function(e){var n=t.createDocumentFragment(),s=t.createElement("div");return n.appendChild(s),s.innerHTML=e,n.firstChild.innerText},loadSprite:function(n,s){function a(e,n){e.innerHTML=n,t.body.insertBefore(e,t.body.childNodes[0])}if("string"==typeof n){var l="cache-",r="string"==typeof s,i=!1;if(!r||!t.querySelectorAll("#"+s).length){var u=t.createElement("div");if(u.setAttribute("hidden",""),r&&u.setAttribute("id",s),o.storage){var c=e.localStorage.getItem(l+s);if(i=null!==c){var d=JSON.parse(c);a(u,d.content)}}var p=new XMLHttpRequest;if(!("withCredentials"in p))return;p.open("GET",n,!0),p.onload=function(){o.storage&&e.localStorage.setItem(l+s,JSON.stringify({content:p.responseText})),a(u,p.responseText)},p.send()}}}},i=function(){var e=function(){var e=!1;return r.is.function(t.cancelFullScreen)?e="":["webkit","o","moz","ms","khtml"].some(function(n){return r.is.function(t[n+"CancelFullScreen"])?(e=n,!0):r.is.function(t.msExitFullscreen)&&t.msFullscreenEnabled?(e="ms",!0):void 0}),e}();return{prefix:e,eventType:"ms"===e?"MSFullscreenChange":e+"fullscreenchange",isFullScreen:function(n){if(!o.fullscreen)return!1;switch(r.is.undefined(n)&&(n=t.body),this.prefix){case"":return t.fullscreenElement===n;case"moz":return t.mozFullScreenElement===n;default:return t[e+"FullscreenElement"]===n}},requestFullScreen:function(n){return!!o.fullscreen&&(r.is.htmlElement(n)||(n=t.body),""===e?n.requestFullScreen():n[e+("ms"===e?"RequestFullscreen":"RequestFullScreen")]())},cancelFullScreen:function(){return!!o.fullscreen&&(""===e?t.cancelFullScreen():t[e+("ms"===e?"ExitFullscreen":"CancelFullScreen")]())},element:function(){return o.fullscreen?""===e?t.fullscreenElement:t[e+"FullscreenElement"]:null}}}(),o={audio:"canPlayType"in t.createElement("audio"),video:"canPlayType"in t.createElement("video"),fullscreen:i.prefix!==!1,storage:function(){if(!("localStorage"in e))return!1;var t="___test";try{return e.localStorage.setItem(t,t),e.localStorage.removeItem(t),!0}catch(e){return!1}return!1}(),pip:function(){var e=r.getBrowser();return!e.isIPhone&&r.is.function(r.createElement("video").webkitSetPresentationMode)}(),airplay:r.is.function(e.WebKitPlaybackTargetAvailabilityEvent),inline:"playsInline"in t.createElement("video"),mime:function(e,t){var n=e.media;try{if(!r.is.function(n.canPlayType))return!1;if("video"===e.type)switch(t){case"video/webm":return n.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/no/,"");case"video/mp4":return n.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/,"");case"video/ogg":return n.canPlayType('video/ogg; codecs="theora"').replace(/no/,"")}else if("audio"===e.type)switch(t){case"audio/mpeg":return n.canPlayType("audio/mpeg;").replace(/no/,"");case"audio/ogg":return n.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/,"");case"audio/wav":return n.canPlayType('audio/wav; codecs="1"').replace(/no/,"")}}catch(e){return!1}return!1},textTracks:"textTracks"in t.createElement("video"),passiveListeners:function(){var t=!1;try{var n=Object.defineProperty({},"passive",{get:function(){t=!0}});e.addEventListener("test",null,n)}catch(e){}return t}(),touch:"ontouchstart"in t.documentElement};return n});
\ No newline at end of file @@ -1,21 +1,26 @@ ### Todo #### To build -[x] Get list of subtitles/captions available (HTML5) +[x] Get list of subtitles/captions available (HTML5, Vimeo) [x] Add preferred quality option into config [ ] Update quality options on YouTube play (can't get up front?!) [ ] Update speed options on YouTube load -[ ] Get quality options for HTML5 somehow (multi source?) -[ ] Finish and test PiP (need Sierra VM) -[ ] Finish and test AirPlay (need Sierra VM) -[ ] Download button - grab first <source> or src attribute (or maybe use currentSrc?) for HTML5 and links for embedded players +[ ] Finish and test PiP (need MacOS Sierra) +[ ] Finish and test AirPlay (need MacOS Sierra) [ ] Controls hide/show events [ ] Test custom controls still works +[ ] Tidy up small UI for iOS inline +[ ] Finish new loop setup and UI +[ ] Toggle settings menu + +#### Later +[ ] Get quality options for HTML5 somehow (multi source?) +[ ] Download button - grab first <source> or src attribute (or maybe use currentSrc?) for HTML5 and links for embedded players #### Bugs [ ] Fix audio setup bug when calling `.setup()` again [ ] Fix events on unsupported devices (iOS, old IE) -[ ] Fix YouTube rights blocking (origin perhaps?) +[x] Fix YouTube rights blocking (origin perhaps?) # Notes - No quality HTML5 support (yet) @@ -25,11 +30,13 @@ - No PiP or AirPlay for Vimeo/YouTube - Settings won't be supported for custom controls (coming soon, need to work on templating) - Added `playsinline` support for iOS 10 +- Embed setup now accepts an <iframe> as the target element for true progressive enhancement #### Breaking changes - New config options for loop - Selectors changes (new `input` and `display` object) - DOCUMENT - Custom HTML option now `controls` which accepts a string (HTML), a function (your own template engine) or array (use built in controls) +- .setup() is removed in favour of a constructor ## Added - Seek i8n label @@ -784,14 +784,9 @@ These events also bubble up the DOM. The event target will be the container elem </thead> <tbody> <tr> - <td><code>setup</code></td> - <td></td> - <td>When an initial setup has completed</td> - </tr> - <tr> <td><code>ready</code></td> <td></td> - <td>Triggered when the instance is ready for API use and external APIs are ready (in the case of YouTube and Vimeo).</td> + <td>Triggered when the instance is ready for API calls.</td> </tr> <tr> <td><code>canplay</code></td> @@ -1057,9 +1052,6 @@ If a User Agent is disabled but supports `<video>` and `<audio>` natively, it wi Any unsupported browsers will display links to download the media if the correct html is used. -### Checking for support -There's an API method for checking support. You can call `plyr.supported()` and optionally pass a type to it, e.g. `plyr.supported("video")`. It will return an object with two keys; `basic` meaning there's basic support for that media type (or both if no type is passed) and `full` meaning there's full support for plyr. - ## Issues If you find anything weird with Plyr, please let us know using the GitHub issues tracker. diff --git a/src/js/plyr.js b/src/js/plyr.js index 63c1aa9c..c41d564b 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1,11 +1,9 @@ // ========================================================================== // Plyr -// plyr.js v2.0.10 +// plyr.js v3.0.0 // https://github.com/selz/plyr // License: The MIT License (MIT) // ========================================================================== -// Credits: http://paypal.github.io/accessible-html5-video-player/ -// ========================================================================== (function(root, factory) { 'use strict'; @@ -21,10 +19,11 @@ }); } else { // Browser globals (root is window) - root.plyr = factory(root, document); + root.Plyr = factory(root, document); } }(typeof window !== 'undefined' ? window : this, function(window, document) { 'use strict'; + /* global jQuery */ // Globals var scroll = { @@ -88,8 +87,6 @@ // Selectors // Change these to match your template if using custom HTML selectors: { - html5: 'video, audio', - embed: '[data-type]', editable: 'input, textarea, select, [contenteditable]', container: '.plyr', controls: { @@ -271,8 +268,8 @@ }, // Events to watch on HTML5 media elements and bubble + // https://developer.mozilla.org/en/docs/Web/Guide/Events/Media_events events: [ - 'ready', 'ended', 'progress', 'stalled', @@ -303,50 +300,51 @@ html5: ['video', 'audio'] }; - // Check variable types - var is = { - object: function(input) { - return input !== null && typeof(input) === 'object' && input.constructor === Object; - }, - array: function(input) { - return input !== null && Array.isArray(input); - }, - number: function(input) { - return input !== null && (typeof(input) === 'number' && !isNaN(input - 0) || (typeof input === 'object' && input.constructor === Number)); - }, - string: function(input) { - return input !== null && (typeof input === 'string' || (typeof input === 'object' && input.constructor === String)); - }, - boolean: function(input) { - return input !== null && typeof input === 'boolean'; - }, - nodeList: function(input) { - return input !== null && input instanceof NodeList; - }, - htmlElement: function(input) { - return input !== null && input instanceof HTMLElement; - }, - function: function(input) { - return input !== null && typeof input === 'function'; - }, - event: function(input) { - return input !== null && input instanceof Event; - }, - cue: function(input) { - return input !== null && (input instanceof window.TextTrackCue || input instanceof window.VTTCue); - }, - track: function(input) { - return input !== null && input instanceof window.TextTrack; - }, - undefined: function(input) { - return input !== null && typeof input === 'undefined'; + // Utilities outside of Plyr scope + var utils = { + // Check variable types + is: { + object: function(input) { + return input !== null && typeof(input) === 'object' && input.constructor === Object; + }, + array: function(input) { + return input !== null && Array.isArray(input); + }, + number: function(input) { + return input !== null && (typeof(input) === 'number' && !isNaN(input - 0) || (typeof input === 'object' && input.constructor === Number)); + }, + string: function(input) { + return input !== null && (typeof input === 'string' || (typeof input === 'object' && input.constructor === String)); + }, + boolean: function(input) { + return input !== null && typeof input === 'boolean'; + }, + nodeList: function(input) { + return input !== null && input instanceof NodeList; + }, + htmlElement: function(input) { + return input !== null && input instanceof HTMLElement; + }, + function: function(input) { + return input !== null && typeof input === 'function'; + }, + event: function(input) { + return input !== null && input instanceof Event; + }, + cue: function(input) { + return input !== null && (input instanceof window.TextTrackCue || input instanceof window.VTTCue); + }, + track: function(input) { + return input !== null && input instanceof window.TextTrack; + }, + undefined: function(input) { + return input !== null && typeof input === 'undefined'; + }, + empty: function(input) { + return input === null || this.undefined(input) || ((this.string(input) || this.array(input) || this.nodeList(input)) && input.length === 0) || (this.object(input) && Object.keys(input).length === 0); + } }, - empty: function(input) { - return input === null || this.undefined(input) || ((this.string(input) || this.array(input) || this.nodeList(input)) && input.length === 0) || (this.object(input) && Object.keys(input).length === 0); - } - }; - var utils = { // Credits: http://paypal.github.io/accessible-html5-video-player/ // Unfortunately, due to mixed support, UA sniffing is required getBrowser: function() { @@ -430,6 +428,47 @@ }; }, + // Check for support + // Basic functionality vs full UI + checkSupport: function(type, inline) { + var basic = false; + var full = false; + var browser = utils.getBrowser(); + var playsInline = (browser.isIPhone && inline && support.inline); + + switch (type) { + case 'video': + basic = support.video; + full = basic && !browser.isOldIE && (!browser.isIPhone || playsInline); + break; + + case 'audio': + basic = support.audio; + full = basic && !browser.isOldIE; + break; + + case 'youtube': + basic = support.video; + full = basic && !browser.isOldIE && (!browser.isIPhone || playsInline); + break; + + case 'vimeo': + case 'soundcloud': + basic = true; + full = (!browser.isOldIE && !browser.isIos); + break; + + default: + basic = (support.audio && support.video); + full = (basic && !browser.isOldIE); + } + + return { + basic: basic, + full: full + }; + }, + // Inject a script injectScript: function(url) { // Check script is not already referenced @@ -455,7 +494,7 @@ // Element exists in an array inArray: function(haystack, needle) { - return is.array(haystack) && haystack.indexOf(needle) !== -1; + return utils.is.array(haystack) && haystack.indexOf(needle) !== -1; }, // Replace all @@ -499,8 +538,8 @@ // Remove an element removeElement: function(element) { - if (!is.htmlElement(element) || - !is.htmlElement(element.parentNode)) { + if (!utils.is.htmlElement(element) || + !utils.is.htmlElement(element.parentNode)) { return; } @@ -523,12 +562,12 @@ var element = document.createElement(type); // Set all passed attributes - if (is.object(attributes)) { + if (utils.is.object(attributes)) { utils.setAttributes(element, attributes); } // Add text node - if (is.string(text)) { + if (utils.is.string(text)) { element.textContent = text; } @@ -567,7 +606,7 @@ // '#test' to { id: 'test' } // '[data-test="test"]' to { 'data-test': 'test' } - if (!is.string(selector) || is.empty(selector)) { + if (!utils.is.string(selector) || utils.is.empty(selector)) { return {}; } @@ -586,7 +625,7 @@ var className = selector.replace('.', ''); // Add to existing classname - if (is.object(existingAttributes) && is.string(existingAttributes.class)) { + if (utils.is.object(existingAttributes) && utils.is.string(existingAttributes.class)) { existingAttributes.class += ' ' + className; } @@ -651,8 +690,8 @@ prototype.webkitMatchesSelector || prototype.mozMatchesSelector || prototype.msMatchesSelector || - function(s) { - return [].indexOf.call(document.querySelectorAll(s), this) !== -1; + function(selector) { + return [].indexOf.call(document.querySelectorAll(selector), this) !== -1; }; return matches.call(element, selector); @@ -687,13 +726,13 @@ // Whether the listener is a capturing listener or not // Default to false - if (!is.boolean(capture)) { + if (!utils.is.boolean(capture)) { capture = false; } // Whether the listener can be passive (i.e. default never prevented) // Default to true - if (!is.boolean(passive)) { + if (!utils.is.boolean(passive)) { passive = true; } @@ -736,14 +775,14 @@ // Bind event handler on: function(element, events, callback, passive, capture) { - if (!is.undefined(element)) { + if (!utils.is.undefined(element)) { utils.toggleListener(element, events, callback, true, passive, capture); } }, // Unbind event handler off: function(element, events, callback, passive, capture) { - if (!is.undefined(element)) { + if (!utils.is.undefined(element)) { utils.toggleListener(element, events, callback, false, passive, capture); } }, @@ -756,10 +795,30 @@ } // Default bubbles to false - if (!is.boolean(bubbles)) { + if (!utils.is.boolean(bubbles)) { bubbles = false; } + // Create CustomEvent constructor + var CustomEvent; + if (utils.is.function(window.CustomEvent)) { + CustomEvent = window.CustomEvent; + } else { + // Polyfill CustomEvent + // https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill + CustomEvent = function(event, params) { + params = params || { + bubbles: false, + cancelable: false, + detail: undefined + }; + var custom = document.createEvent('CustomEvent'); + custom.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); + return custom; + }; + CustomEvent.prototype = window.Event.prototype; + } + // Create and dispatch the event var event = new CustomEvent(type, { bubbles: bubbles, @@ -779,7 +838,7 @@ } // Get state - state = (is.boolean(state) ? state : !target.getAttribute('aria-pressed')); + state = (utils.is.boolean(state) ? state : !target.getAttribute('aria-pressed')); // Set the attribute on target target.setAttribute('aria-pressed', state); @@ -814,7 +873,7 @@ // First object is the destination var destination = Array.prototype.shift.call(objects); - if (!is.object(destination)) { + if (!utils.is.object(destination)) { destination = {}; } @@ -824,7 +883,7 @@ for (var i = 0; i < length; i++) { var source = objects[i]; - if (!is.object(source)) { + if (!utils.is.object(source)) { source = {}; } @@ -854,6 +913,70 @@ fragment.appendChild(element); element.innerHTML = source; return fragment.firstChild.innerText; + }, + + // Load an SVG sprite + loadSprite: function(url, id) { + if (typeof url !== 'string') { + return; + } + + var prefix = 'cache-'; + var hasId = typeof id === 'string'; + var isCached = false; + + function updateSprite(container, data) { + // Inject content + container.innerHTML = data; + + // Inject the SVG to the body + document.body.insertBefore(container, document.body.childNodes[0]); + } + + // Only load once + if (!hasId || !document.querySelectorAll('#' + id).length) { + // Create container + var container = document.createElement('div'); + container.setAttribute('hidden', ''); + + if (hasId) { + container.setAttribute('id', id); + } + + // Check in cache + if (support.storage) { + var cached = window.localStorage.getItem(prefix + id); + isCached = cached !== null; + + if (isCached) { + var data = JSON.parse(cached); + updateSprite(container, data.content); + } + } + + // ReSharper disable once InconsistentNaming + var xhr = new XMLHttpRequest(); + + // XHR for Chrome/Firefox/Opera/Safari + if ('withCredentials' in xhr) { + xhr.open('GET', url, true); + } else { + return; + } + + // Once loaded, inject to container and body + xhr.onload = function() { + if (support.storage) { + window.localStorage.setItem(prefix + id, JSON.stringify({ + content: xhr.responseText + })); + } + + updateSprite(container, xhr.responseText); + }; + + xhr.send(); + } } }; @@ -863,15 +986,15 @@ var prefix = (function() { var value = false; - if (is.function(document.cancelFullScreen)) { + if (utils.is.function(document.cancelFullScreen)) { value = ''; } else { // Check for fullscreen support by vendor prefix ['webkit', 'o', 'moz', 'ms', 'khtml'].some(function(prefix) { - if (is.function(document[prefix + 'CancelFullScreen'])) { + if (utils.is.function(document[prefix + 'CancelFullScreen'])) { value = prefix; return true; - } else if (is.function(document.msExitFullscreen) && document.msFullscreenEnabled) { + } else if (utils.is.function(document.msExitFullscreen) && document.msFullscreenEnabled) { // Special case for MS (when isn't it?) value = 'ms'; return true; @@ -893,7 +1016,7 @@ if (!support.fullscreen) { return false; } - if (is.undefined(element)) { + if (utils.is.undefined(element)) { element = document.body; } switch (this.prefix) { @@ -909,7 +1032,7 @@ if (!support.fullscreen) { return false; } - if (!is.htmlElement(element)) { + if (!utils.is.htmlElement(element)) { element = document.body; } return (prefix === '') ? element.requestFullScreen() : element[prefix + (prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')](); @@ -929,7 +1052,7 @@ }; })(); - // Check for support + // Check for feature support var support = { // Basic support audio: 'canPlayType' in document.createElement('audio'), @@ -947,18 +1070,11 @@ // Try to use it (it might be disabled, e.g. user is in private/porn mode) // see: https://github.com/Selz/plyr/issues/131 + var test = '___test'; try { - // Add test item - window.localStorage.setItem('___test', 'OK'); - - // Get the test item - var result = window.localStorage.getItem('___test'); - - // Clean up - window.localStorage.removeItem('___test'); - - // Check if value matches - return (result === 'OK'); + window.localStorage.setItem(test, test); + window.localStorage.removeItem(test); + return true; } catch (e) { return false; } @@ -970,12 +1086,12 @@ // Safari only currently pip: (function() { var browser = utils.getBrowser(); - return !browser.isIPhone && is.function(utils.createElement('video').webkitSetPresentationMode); + return !browser.isIPhone && utils.is.function(utils.createElement('video').webkitSetPresentationMode); })(), // Airplay support // Safari only currently - airplay: is.function(window.WebKitPlaybackTargetAvailabilityEvent), + airplay: utils.is.function(window.WebKitPlaybackTargetAvailabilityEvent), // Inline playback support // https://webkit.org/blog/6784/new-video-policies-for-ios/ @@ -989,7 +1105,7 @@ try { // Bail if no checking function - if (!is.function(media.canPlayType)) { + if (!utils.is.function(media.canPlayType)) { return false; } @@ -1048,14 +1164,27 @@ }; // Player instance - function Plyr(media, config) { + function Player(element, options) { var player = this; var timers = {}; - var api; + var api = {}; - player.fullscreen = { - active: false - }; + // String selector passed + if (utils.is.string(element)) { + element = document.querySelectorAll(element); + } + + // jQuery, NodeList or Array passed, use first element + if ((window.jQuery && element instanceof jQuery) || utils.is.nodeList(element) || utils.is.array(element)) { + element = element[0]; + } + + // Config + var config = utils.extend({}, defaults, options, (function() { + try { + return JSON.parse(element.getAttribute('data-plyr')); + } catch (e) {} + })()); // Elements cache player.elements = { @@ -1069,7 +1198,7 @@ panes: {}, tabs: {} }, - media: media, + media: element, captions: null }; @@ -1081,15 +1210,19 @@ currentTrack: null }; - // Set media - var original = media.cloneNode(true); + // Fullscreen + player.fullscreen = { + active: false + }; // Debugging var log = function() {}; var warn = function() {}; + var error = function() {}; if (config.debug && 'console' in window) { log = window.console.log; warn = window.console.warn; + error = window.console.error; } // Log config options and support @@ -1115,9 +1248,10 @@ function removeElement(element) { // Remove reference from player.elements cache - if (is.string(element)) { + if (utils.is.string(element)) { utils.removeElement(player.elements[element]); player.elements[element] = null; + } else { utils.removeElement(element); } @@ -1150,11 +1284,11 @@ // Add elements to HTML5 media (source, tracks, etc) function insertElements(type, attributes) { - if (is.string(attributes)) { + if (utils.is.string(attributes)) { utils.insertElement(type, player.elements.media, { src: attributes }); - } else if (is.array(attributes)) { + } else if (utils.is.array(attributes)) { attributes.forEach(function(attribute) { utils.insertElement(type, player.elements.media, attribute); }); @@ -1230,7 +1364,7 @@ var iconToggled; var labelKey; - if (!is.object(attributes)) { + if (!utils.is.object(attributes)) { attributes = {}; } @@ -1278,7 +1412,7 @@ utils.extend(attributes, utils.getAttributesFromSelector(config.selectors.buttons[type], attributes)); // Add toggle icon if needed - if (is.string(iconToggled)) { + if (utils.is.string(iconToggled)) { button.appendChild(createIcon(iconToggled, { class: 'icon--' + iconToggled })); @@ -1665,7 +1799,7 @@ } } - if (is.array(options) && !is.empty(options)) { + if (utils.is.array(options) && !utils.is.empty(options)) { options.filter(function(quality) { // Remove any unwanted quality levels return !utils.inArray(['tiny', 'small'], quality); @@ -1692,7 +1826,7 @@ label.appendChild(document.createTextNode(getLabel(quality))); var badge = getBadge(quality); - if (is.htmlElement(badge)) { + if (utils.is.htmlElement(badge)) { label.appendChild(badge); } @@ -1739,7 +1873,7 @@ utils.emptyElement(list); // If there's no captions, bail - if (is.empty(player.captions.tracks)) { + if (utils.is.empty(player.captions.tracks)) { return; } @@ -1748,7 +1882,7 @@ return { language: track.language, badge: true, - label: !is.empty(track.label) ? track.label : track.language.toUpperCase() + label: !utils.is.empty(track.label) ? track.label : track.language.toUpperCase() } }); @@ -1799,7 +1933,7 @@ utils.emptyElement(list); // If there's no captions, bail - if (!is.array(options)) { + if (!utils.is.array(options)) { options = config.speed.options; } @@ -1868,19 +2002,19 @@ } // Inject the container - if (!is.htmlElement(player.elements.captions)) { + if (!utils.is.htmlElement(player.elements.captions)) { player.elements.captions = utils.createElement('div', utils.getAttributesFromSelector(config.selectors.captions)); utils.insertAfter(player.elements.captions, player.elements.wrapper); } // Get tracks - player.captions.tracks = is.array(tracks) ? tracks : player.elements.media.textTracks; + player.captions.tracks = utils.is.array(tracks) ? tracks : player.elements.media.textTracks; // Set the class hook - utils.toggleClass(player.elements.container, config.classes.captions.enabled, !is.empty(player.captions.tracks)); + utils.toggleClass(player.elements.container, config.classes.captions.enabled, !utils.is.empty(player.captions.tracks)); // If no caption file exists, hide container for caption text - if (is.empty(player.captions.tracks)) { + if (utils.is.empty(player.captions.tracks)) { return; } @@ -1905,14 +2039,14 @@ }); // If we couldn't get the requested language, we get the first - if (!is.track(player.captions.currentTrack)) { + if (!utils.is.track(player.captions.currentTrack)) { warn('No language found to match ' + language + ' in tracks'); player.captions.currentTrack = player.captions.tracks[0]; } // If it's a caption or subtitle, render it var track = player.captions.currentTrack; - if (is.track(track) && utils.inArray(['captions', 'subtitles'], track.kind)) { + if (utils.is.track(track) && utils.inArray(['captions', 'subtitles'], track.kind)) { utils.on(track, 'cuechange', setActiveCue); // If we change the active track while a cue is already displayed we need to update it @@ -1928,7 +2062,7 @@ // Get current selected caption language function getLanguage() { - if (!support.textTracks || is.empty(player.captions.tracks)) { + if (!support.textTracks || utils.is.empty(player.captions.tracks)) { return 'No Subs'; } @@ -1942,14 +2076,14 @@ // Display active caption if it contains text function setActiveCue(track) { // Get the track from the event if needed - if (is.event(track)) { + if (utils.is.event(track)) { track = track.target; } var active = track.activeCues[0]; // Display a cue, if there is one - if (is.cue(active)) { + if (utils.is.cue(active)) { setCaption(active.getCueAsHTML()); } else { setCaption(); @@ -1959,9 +2093,9 @@ // Select active caption function setLanguage(language) { // Save config - if (is.string(language)) { + if (utils.is.string(language)) { config.captions.language = language.toLowerCase(); - } else if (is.event(language)) { + } else if (utils.is.event(language)) { config.captions.language = language.target.value.toLowerCase(); } @@ -1974,19 +2108,19 @@ // Set the current caption function setCaption(caption) { - if (is.htmlElement(player.elements.captions)) { + if (utils.is.htmlElement(player.elements.captions)) { var content = utils.createElement('span'); // Empty the container utils.emptyElement(player.elements.captions); // Default to empty - if (is.undefined(caption)) { + if (utils.is.undefined(caption)) { caption = ''; } // Set the span content - if (is.string(caption)) { + if (utils.is.string(caption)) { content.textContent = caption.trim(); } else { content.appendChild(caption); @@ -2013,7 +2147,7 @@ var active = player.storage.captions; // Otherwise fall back to the default config - if (!is.boolean(active)) { + if (!utils.is.boolean(active)) { active = config.captions.active; } else { config.captions.active = active; @@ -2033,7 +2167,7 @@ } // If the method is called without parameter, toggle based on current value - if (!is.boolean(show)) { + if (!utils.is.boolean(show)) { show = (player.elements.container.className.indexOf(config.classes.captions.active) === -1); } @@ -2064,7 +2198,7 @@ // Only load external sprite using AJAX if (iconUrl.absolute) { log('AJAX loading absolute SVG sprite' + (player.browser.isIE ? ' (due to IE)' : '')); - loadSprite(iconUrl.url, "sprite-plyr"); + utils.loadSprite(iconUrl.url, "sprite-plyr"); } else { log('Sprite will be used as external resource directly'); } @@ -2083,12 +2217,12 @@ var controls = null; // HTML passed as the option - if (is.string(config.controls)) { + if (utils.is.string(config.controls)) { controls = config.controls; } // A custom function to build controls // The function can return a HTMLElement or String - else if (is.function(config.controls)) { + else if (utils.is.function(config.controls)) { controls = config.controls({ id: player.id, seektime: config.seekTime @@ -2112,24 +2246,24 @@ var target; // Inject to custom location - if (is.string(config.selectors.controls.container)) { + if (utils.is.string(config.selectors.controls.container)) { target = document.querySelector(config.selectors.controls.container); } // Inject into the container by default - if (!is.htmlElement(target)) { + if (!utils.is.htmlElement(target)) { target = player.elements.container } // Inject controls HTML - if (is.htmlElement(controls)) { + if (utils.is.htmlElement(controls)) { target.appendChild(controls); } else { target.insertAdjacentHTML('beforeend', controls); } // Find the elements if need be - if (is.htmlElement(player.elements.controls)) { + if (utils.is.htmlElement(player.elements.controls)) { findElements(); } @@ -2186,7 +2320,7 @@ }; // Seek tooltip - if (is.htmlElement(player.elements.progress)) { + if (utils.is.htmlElement(player.elements.progress)) { player.elements.display.seekTooltip = player.elements.progress.querySelector('.' + config.classes.tooltip); } @@ -2222,7 +2356,7 @@ var label = config.i18n.play; // If there's a media title set, use that for the label - if (is.string(config.title) && !is.empty(config.title)) { + if (utils.is.string(config.title) && !utils.is.empty(config.title)) { label += ', ' + config.title; // Set container label @@ -2231,18 +2365,18 @@ // If there's a play button, set label if (player.supported.full) { - if (is.htmlElement(player.elements.buttons.play)) { + if (utils.is.htmlElement(player.elements.buttons.play)) { player.elements.buttons.play.setAttribute('aria-label', label); } - if (is.htmlElement(player.elements.buttons.playLarge)) { + if (utils.is.htmlElement(player.elements.buttons.playLarge)) { player.elements.buttons.playLarge.setAttribute('aria-label', label); } } // Set iframe title // https://github.com/Selz/plyr/issues/124 - if (is.htmlElement(iframe)) { - var title = is.string(config.title) && !is.empty(config.title) ? config.title : 'video'; + if (utils.is.htmlElement(iframe)) { + var title = utils.is.string(config.title) && !utils.is.empty(config.title) ? config.title : 'video'; iframe.setAttribute('title', config.i18n.frameTitle.replace('{title}', title)); } } @@ -2375,7 +2509,7 @@ player.elements.media.setAttribute('id', id); // Setup API - if (is.object(window.YT)) { + if (utils.is.object(window.YT)) { youTubeReady(mediaId); } else { // Load the API @@ -2401,12 +2535,12 @@ player.elements.media.setAttribute('id', id); // Load the API if not already - if (!is.object(window.Vimeo)) { + if (!utils.is.object(window.Vimeo)) { utils.injectScript(config.urls.vimeo.api); // Wait for fragaloop load var vimeoTimer = window.setInterval(function() { - if (is.object(window.Vimeo)) { + if (utils.is.object(window.Vimeo)) { window.clearInterval(vimeoTimer); vimeoReady(mediaId); } @@ -2714,7 +2848,7 @@ player.embed.on('loaded', function() { // Fix keyboard focus issues // https://github.com/Selz/plyr/issues/317 - if (is.htmlElement(player.embed.element) && player.supported.full) { + if (utils.is.htmlElement(player.embed.element) && player.supported.full) { player.embed.element.setAttribute('tabindex', -1); } }); @@ -2848,7 +2982,7 @@ // Toggle playback function togglePlay(toggle) { // True toggle - if (!is.boolean(toggle)) { + if (!utils.is.boolean(toggle)) { toggle = player.elements.media.paused; } @@ -2912,11 +3046,11 @@ } // Check if can loop - config.loop.active = is.number(config.loop.start) && is.number(config.loop.end); + config.loop.active = utils.is.number(config.loop.start) && utils.is.number(config.loop.end); var start = updateTimeDisplay(config.loop.start, getElement('[data-plyr-loop="start"]')); var end = null; - if (is.number(config.loop.end)) { + if (utils.is.number(config.loop.end)) { // Find the <span> inside button end = updateTimeDisplay(config.loop.end, document.querySelector('[data-loop__value="loopout"]')); } else { @@ -2943,9 +3077,9 @@ // Set playback speed function setSpeed(speed) { // Load speed from storage or default value - if (is.event(speed)) { + if (utils.is.event(speed)) { speed = parseFloat(speed.target.value); - } else if (!is.number(speed)) { + } else if (!utils.is.number(speed)) { speed = parseFloat(player.storage.speed || config.speed.selected); } @@ -2957,7 +3091,7 @@ speed = 2.0; } - if (!is.array(config.speed.options)) { + if (!utils.is.array(config.speed.options)) { warn('Invalid speeds format'); return; } @@ -2983,7 +3117,7 @@ // Rewind function rewind(seekTime) { // Use default if needed - if (!is.number(seekTime)) { + if (!utils.is.number(seekTime)) { seekTime = config.seekTime; } seek(player.elements.media.currentTime - seekTime); @@ -2992,7 +3126,7 @@ // Fast forward function forward(seekTime) { // Use default if needed - if (!is.number(seekTime)) { + if (!utils.is.number(seekTime)) { seekTime = config.seekTime; } seek(player.elements.media.currentTime + seekTime); @@ -3005,9 +3139,9 @@ var paused = player.elements.media.paused; var duration = getDuration(); - if (is.number(input)) { + if (utils.is.number(input)) { targetTime = input; - } else if (is.event(input) && utils.inArray(['input', 'change'], input.type)) { + } else if (utils.is.event(input) && utils.inArray(['input', 'change'], input.type)) { // It's the seek slider // Seek to the selected time targetTime = ((input.target.value / input.target.max) * duration); @@ -3166,7 +3300,7 @@ var show = (toggle.getAttribute('aria-expanded') === 'false'); // Nothing to show, bail - if (!is.htmlElement(target)) { + if (!utils.is.htmlElement(target)) { return; } @@ -3221,7 +3355,7 @@ // Mute function toggleMute(muted) { // If the method is called without parameter, toggle based on current value - if (!is.boolean(muted)) { + if (!utils.is.boolean(muted)) { muted = !player.elements.media.muted; } @@ -3261,12 +3395,12 @@ var min = 0; // If volume is event, get from input - if (is.event(volume)) { + if (utils.is.event(volume)) { volume = volume.target.value; } // Load volume from storage if no value specified - if (is.undefined(volume)) { + if (utils.is.undefined(volume)) { volume = player.storage.volume; } @@ -3321,7 +3455,7 @@ function increaseVolume(step) { var volume = player.elements.media.muted ? 0 : (player.elements.media.volume * 10); - if (!is.number(step)) { + if (!utils.is.number(step)) { step = 1; } @@ -3332,7 +3466,7 @@ function decreaseVolume(step) { var volume = player.elements.media.muted ? 0 : (player.elements.media.volume * 10); - if (!is.number(step)) { + if (!utils.is.number(step)) { step = 1; } @@ -3423,7 +3557,7 @@ if (buffered && buffered.length) { // HTML5 return utils.getPercentage(buffered.end(0), duration); - } else if (is.number(buffered)) { + } else if (utils.is.number(buffered)) { // YouTube returns between 0 and 1 return (buffered * 100); } @@ -3435,7 +3569,7 @@ } } - if (is.number(config.loop.start) && is.number(config.loop.end) && player.elements.media.currentTime >= config.loop.end) { + if (utils.is.number(config.loop.start) && utils.is.number(config.loop.end) && player.elements.media.currentTime >= config.loop.end) { seek(config.loop.start); } @@ -3449,12 +3583,12 @@ } // Default to 0 - if (is.undefined(value)) { + if (utils.is.undefined(value)) { value = 0; } // Default to buffer or bail - if (is.undefined(progress)) { - if (is.htmlElement(player.elements.display.buffer)) { + if (utils.is.undefined(progress)) { + if (utils.is.htmlElement(player.elements.display.buffer)) { progress = player.elements.display.buffer; } else { return; @@ -3462,12 +3596,12 @@ } // Update value and label - if (is.htmlElement(progress)) { + if (utils.is.htmlElement(progress)) { progress.value = value; // Update text label inside var label = progress.getElementsByTagName('span')[0]; - if (is.htmlElement(label)) { + if (utils.is.htmlElement(label)) { label.childNodes[0].nodeValue = value; } } @@ -3546,7 +3680,7 @@ // Update seek range and progress function updateSeekDisplay(time) { // Default to 0 - if (!is.number(time)) { + if (!utils.is.number(time)) { time = 0; } @@ -3569,7 +3703,7 @@ var duration = getDuration(); // Bail if setting not true - if (!config.tooltips.seek || !is.htmlElement(player.elements.inputs.seek) || !is.htmlElement(player.elements.display.seekTooltip) || duration === 0) { + if (!config.tooltips.seek || !utils.is.htmlElement(player.elements.inputs.seek) || !utils.is.htmlElement(player.elements.display.seekTooltip) || duration === 0) { return; } @@ -3579,7 +3713,7 @@ var visible = config.classes.tooltip + '--visible'; // Determine percentage, if already visible - if (is.event(event)) { + if (utils.is.event(event)) { percent = ((100 / clientRect.width) * (event.pageX - clientRect.left)); } else { if (utils.hasClass(player.elements.display.seekTooltip, visible)) { @@ -3604,7 +3738,7 @@ // Show/hide the tooltip // If the event is a moues in/out and percentage is inside bounds - if (is.event(event) && utils.inArray(['mouseenter', 'mouseleave'], event.type)) { + if (utils.is.event(event) && utils.inArray(['mouseenter', 'mouseleave'], event.type)) { utils.toggleClass(player.elements.display.seekTooltip, visible, (event.type === 'mouseenter')); } } @@ -3622,7 +3756,7 @@ var loading = utils.hasClass(player.elements.container, config.classes.loading); // Default to false if no boolean - if (!is.boolean(toggle)) { + if (!utils.is.boolean(toggle)) { if (toggle && toggle.type) { // Is the enter fullscreen event isEnterFullscreen = (toggle.type === 'enterfullscreen'); @@ -3679,7 +3813,7 @@ // Add common function to retrieve media source function source(source) { // If not null or undefined, parse it - if (!is.undefined(source)) { + if (!utils.is.undefined(source)) { updateSource(source); return; } @@ -3714,7 +3848,7 @@ // Update source // Sources are not checked for support so be careful function updateSource(source) { - if (!is.object(source) || !('sources' in source) || !source.sources.length) { + if (!utils.is.object(source) || !('sources' in source) || !source.sources.length) { warn('Invalid source format'); return; } @@ -3768,7 +3902,7 @@ } // Check for support - player.supported = getSupport(player.type, config.inline); + player.supported = utils.checkSupport(player.type, config.inline); // Create new markup switch (player.type) { @@ -3792,7 +3926,7 @@ utils.prependChild(player.elements.container, player.elements.media); // Autoplay the new source? - if (is.boolean(source.autoplay)) { + if (utils.is.boolean(source.autoplay)) { config.autoplay = source.autoplay; } @@ -3883,7 +4017,7 @@ var hadTabFocus = utils.hasClass(trigger, config.classes.tabFocus); setTimeout(function() { - if (is.htmlElement(target)) { + if (utils.is.htmlElement(target)) { target.focus(); } @@ -3919,13 +4053,11 @@ var code = getKeyCode(event); var focused = utils.getFocusElement(); var allowed = [48, 49, 50, 51, 52, 53, 54, 56, 57, 75, 77, 70, 67, 73, 76, 79]; - var count = get().length; - // Only handle global key press if there's only one player - // and the key is in the allowed keys + // Only handle global key press if key is in the allowed keys // and if the focused element is not editable (e.g. text input) // and any that accept key input http://webaim.org/techniques/keyboard/ - if (count === 1 && utils.inArray(allowed, code) && (!is.htmlElement(focused) || !utils.matches(focused, config.selectors.editable))) { + if (utils.inArray(allowed, code) && (!utils.is.htmlElement(focused) || !utils.matches(focused, config.selectors.editable))) { handleKey(event); } }, false); @@ -3942,7 +4074,7 @@ // If the event is bubbled from the media element // Firefox doesn't get the keycode for whatever reason - if (!is.number(code)) { + if (!utils.is.number(code)) { return; } @@ -3952,7 +4084,7 @@ var duration = player.elements.media.duration; // Bail if we have no duration set - if (!is.number(duration)) { + if (!utils.is.number(duration)) { return; } @@ -3970,7 +4102,7 @@ if (utils.inArray(checkFocus, code)) { var focused = utils.getFocusElement(); - if (is.htmlElement(focused) && utils.getFocusElement().type === "radio") { + if (utils.is.htmlElement(focused) && utils.getFocusElement().type === "radio") { return; } } @@ -4093,10 +4225,10 @@ // Trigger custom and default handlers var handlerProxy = function(event, customHandler, defaultHandler) { - if (is.function(customHandler)) { + if (utils.is.function(customHandler)) { customHandler.call(this, event); } - if (is.function(defaultHandler)) { + if (utils.is.function(defaultHandler)) { defaultHandler.call(this, event); } } @@ -4376,11 +4508,6 @@ // Event listeners are removed when elements are removed // http://stackoverflow.com/questions/12528049/if-a-dom-element-is-removed-are-its-listeners-also-removed-from-memory function destroy(callback, restore) { - // Bail if the element is not initialized - if (!player.init) { - return null; - } - // Type specific stuff switch (player.type) { case 'youtube': @@ -4419,13 +4546,13 @@ function cleanUp() { // Default to restore original element - if (!is.boolean(restore)) { + if (!utils.is.boolean(restore)) { restore = true; } // Callback - if (is.function(callback)) { - callback.call(original); + if (utils.is.function(callback)) { + callback.call(player.original); } // Bail if we don't need to restore the original element @@ -4433,94 +4560,15 @@ return; } - // Remove init flag - player.init = false; - // Replace the container with the original element provided - player.elements.container.parentNode.replaceChild(original, player.elements.container); + player.elements.container.parentNode.replaceChild(player.original, player.elements.container); - // unbind escape key + // Reset overflow (incase destroyed while fullscreen) document.body.style.overflow = ''; // Event - trigger(original, 'destroyed', true); - } - } - - // Setup a player - function init() { - // Bail if the element is initialized - if (player.init) { - return null; - } - - // Sniff out the browser - player.browser = utils.getBrowser(); - - // Bail if nothing to setup - if (!is.htmlElement(player.elements.media)) { - return; - } - - // Load saved settings from localStorage - setupStorage(); - - // Set media type based on tag or data attribute - // Supported: video, audio, vimeo, youtube - var tagName = media.tagName.toLowerCase(); - if (tagName === 'div') { - player.type = media.getAttribute('data-type'); - player.embedId = media.getAttribute('data-video-id'); - - // Clean up - media.removeAttribute('data-type'); - media.removeAttribute('data-video-id'); - } else { - player.type = tagName; - config.crossorigin = media.getAttribute('crossorigin') !== null; - config.autoplay = config.autoplay || (media.getAttribute('autoplay') !== null); - config.inline = media.getAttribute('playsinline') !== null; - config.loop.active = config.loop || (media.getAttribute('loop') !== null); - } - - // Check for support - player.supported = getSupport(player.type, config.inline); - - // If no native support, bail - if (!player.supported.basic) { - return; - } - - // Wrap media - player.elements.container = utils.wrap(media, utils.createElement('div')); - - // Allow focus to be captured - player.elements.container.setAttribute('tabindex', 0); - - // Add style hook - toggleStyleHook(); - - // Debug info - log('' + player.browser.name + ' ' + player.browser.version); - - // Setup media - setupMedia(); - - // Setup interface - // If embed but not fully supported, setupInterface (to avoid flash of controls) and call ready now - if (utils.inArray(types.html5, player.type) || (utils.inArray(types.embed, player.type) && !player.supported.full)) { - // Setup UI - setupInterface(); - - // Call ready - ready(); - - // Set title on button and frame - setTitle(); + trigger(player.original, 'destroyed', true); } - - // Successful setup - player.init = true; } // Setup the UI @@ -4543,7 +4591,7 @@ } // Inject custom controls if not present - if (!is.htmlElement(player.elements.controls)) { + if (!utils.is.htmlElement(player.elements.controls)) { // Inject custom controls injectControls(); @@ -4552,7 +4600,7 @@ } // If there's no controls, bail - if (!is.htmlElement(player.elements.controls)) { + if (!utils.is.htmlElement(player.elements.controls)) { return; } @@ -4585,9 +4633,148 @@ checkPlaying(); } + // Everything done + function ready() { + // Set class hook on media element + // utils.toggleClass(player.elements.media, defaults.classes.setup, true); + + // Set container class for ready + // utils.toggleClass(player.elements.container, config.classes.ready, true); + + // Store a refernce to instance + // player.elements.media.plyr = api; + + // Ready event at end of execution stack + trigger(player.elements.container, 'ready', true); + + // Autoplay + if (config.autoplay) { + play(); + } + } + + // Setup a player + function setup(target) { + // We need an element to setup + if (!utils.is.htmlElement(target)) { + error('Setup failed. No suitable element passed.'); + return false; + } + + // Bail if not enabled + if (!config.enabled) { + return false; + } + + // Bail if disabled or no basic support + // You may want to disable certain UAs etc + if (!utils.checkSupport().basic) { + return false; + } + + // Bail if the element is initialized + if (target.plyr) { + return false; + } + + // Set media type based on tag or data attribute + // Supported: video, audio, vimeo, youtube + var type = target.tagName.toLowerCase(); + + // Different setup based on type + switch (type) { + case 'div': + player.type = target.getAttribute('data-type'); + player.embedId = target.getAttribute('data-video-id'); + + if (utils.is.empty(player.type) || utils.is.empty(player.embedId)) { + return false; + } + + // Clean up + target.removeAttribute('data-type'); + target.removeAttribute('data-video-id'); + break; + + case 'iframe': + // Do something with the iframe + break; + + case 'video': + case 'audio': + player.type = type; + config.crossorigin = target.getAttribute('crossorigin') !== null; + config.autoplay = config.autoplay || (target.getAttribute('autoplay') !== null); + config.inline = target.getAttribute('playsinline') !== null; + config.loop.active = config.loop || (target.getAttribute('loop') !== null); + break; + + default: + return false; + } + + // Sniff out the browser + player.browser = utils.getBrowser(); + + // Load saved settings from localStorage + setupStorage(); + + // Check for support + player.supported = utils.checkSupport(player.type, config.inline); + + // If no native support, bail + if (!player.supported.basic) { + return false; + } + + // Wrap media + player.elements.container = utils.wrap(target, utils.createElement('div')); + + // Cache original element state for .destroy() + player.original = target.cloneNode(true); + + // Allow focus to be captured + player.elements.container.setAttribute('tabindex', 0); + + // Add style hook + toggleStyleHook(); + + // Debug info + log(player.browser.name + ' ' + player.browser.version); + + // Setup media + setupMedia(); + + // Listen for events if debugging + if (config.debug) { + var events = config.events.concat(['setup', 'statechange', 'enterfullscreen', 'exitfullscreen', 'captionsenabled', 'captionsdisabled']); + + utils.on(player.elements.container, events.join(' '), function(event) { + log(['event:', event.type].join(' ').trim()); + }); + } + + // Setup interface + // If embed but not fully supported, setupInterface (to avoid flash of controls) and call ready now + if (utils.inArray(types.html5, player.type) || (utils.inArray(types.embed, player.type) && !player.supported.full)) { + // Setup UI + setupInterface(); + + // Call ready + ready(); + + // Set title on button and frame + setTitle(); + } + + // Successful setup + return true; + } + + // Expose prototypes api = { getOriginal: function() { - return original; + return player.original; }, getContainer: function() { return player.elements.container @@ -4648,299 +4835,21 @@ toggleFullscreen: toggleFullscreen, toggleControls: toggleControls, setLanguage: setLanguage, - isFullscreen: function() { - return player.fullscreen.active || false; - }, + isFullscreen: player.fullscreen.active, support: function(mimeType) { return support.mime(player, mimeType); }, destroy: destroy }; - // Everything done - function ready() { - // Set class hook on media element - utils.toggleClass(player.elements.media, defaults.classes.setup, true); - - // Set container class for ready - utils.toggleClass(player.elements.container, config.classes.ready, true); - - // Store a refernce to instance - player.elements.media.plyr = api; - - // Ready event at end of execution stack - window.setTimeout(function() { - trigger(player.elements.media, 'ready'); - }, 0); - - // Autoplay - if (config.autoplay) { - play(); - } - } - // Initialize instance - init(); - - // If init failed, return null - if (!player.init) { + if (!setup(player.elements.media)) { return null; } + // Expose API return api; } - // Load a sprite - function loadSprite(url, id) { - var x = new XMLHttpRequest(); - - // If the id is set and sprite exists, bail - if (is.string(id) && is.htmlElement(document.querySelector('#' + id))) { - return; - } - - // Create placeholder (to prevent loading twice) - var container = utils.createElement('div'); - container.setAttribute('hidden', ''); - if (is.string(id)) { - container.setAttribute('id', id); - } - document.body.insertBefore(container, document.body.childNodes[0]); - - // Check for CORS support - if ('withCredentials' in x) { - x.open('GET', url, true); - } else { - return; - } - - // Inject hidden div with sprite on load - x.onload = function() { - container.innerHTML = x.responseText; - } - - x.send(); - } - - // Check for support - // Basic functionality vs full UI - function getSupport(type, inline) { - var basic = false; - var full = false; - var browser = utils.getBrowser(); - var playsInline = (browser.isIPhone && inline && support.inline); - - switch (type) { - case 'video': - basic = support.video; - full = basic && !browser.isOldIE && (!browser.isIPhone || playsInline); - break; - - case 'audio': - basic = support.audio; - full = basic && !browser.isOldIE; - break; - - case 'youtube': - basic = support.video; - full = basic && !browser.isOldIE && (!browser.isIPhone || playsInline); - break; - - case 'vimeo': - case 'soundcloud': - basic = true; - full = (!browser.isOldIE && !browser.isIos); - break; - - default: - basic = (support.audio && support.video); - full = (basic && !browser.isOldIE); - } - - return { - basic: basic, - full: full - }; - } - - // Setup function - function setup(targets, options) { - // Get the players - var players = []; - var instances = []; - var selector = [defaults.selectors.html5, defaults.selectors.embed].join(','); - - // Select the elements - if (is.string(targets)) { - // String selector passed - targets = document.querySelectorAll(targets); - } else if (is.htmlElement(targets)) { - // Single HTMLElement passed - targets = [targets]; - } else if (!is.nodeList(targets) && !is.array(targets) && !is.string(targets)) { - // No selector passed, possibly options as first argument - // If options are the first argument - if (is.undefined(options) && is.object(targets)) { - options = targets; - } - - // Use default selector - targets = document.querySelectorAll(selector); - } - - // Convert NodeList to array - if (is.nodeList(targets)) { - targets = Array.prototype.slice.call(targets); - } - - // Bail if disabled or no basic support - // You may want to disable certain UAs etc - if (!getSupport().basic || !targets.length) { - return false; - } - - // Add to container list - function add(target, media) { - if (!utils.hasClass(media, defaults.classes.hook)) { - players.push({ - // Always wrap in a <div> for styling - // container: utils.wrap(media, document.createElement('div')), - // Could be a container or the media itself - target: target, - // This should be the <video>, <audio> or <div> (YouTube/Vimeo) - media: media - }); - } - } - - // Check if the targets have multiple media elements - for (var i = 0; i < targets.length; i++) { - var target = targets[i]; - - // Get children - var children = target.querySelectorAll(selector); - - // If there's more than one media element child, wrap them - if (children.length) { - for (var x = 0; x < children.length; x++) { - add(target, children[x]); - } - } else if (utils.matches(target, selector)) { - // Target is media element - add(target, target); - } - } - - // Create a player instance for each element - players.forEach(function(player) { - var element = player.target; - var media = player.media; - var match = false; - - // The target element can also be the media element - if (media === element) { - match = true; - } - - // Setup a player instance and add to the element - // Create instance-specific config - var data = {}; - - // Try parsing data attribute config - try { - data = JSON.parse(element.getAttribute('data-plyr')); - } catch (e) {} - - var config = utils.extend({}, defaults, options, data); - - // Bail if not enabled - if (!config.enabled) { - return null; - } - - // Create new instance - var instance = new Plyr(media, config); - - // Go to next if setup failed - if (!is.object(instance)) { - return; - } - - // Listen for events if debugging - if (config.debug) { - var events = config.events.concat(['setup', 'statechange', 'enterfullscreen', 'exitfullscreen', 'captionsenabled', 'captionsdisabled']); - - utils.on(instance.getContainer(), events.join(' '), function(event) { - window.console.log([config.logPrefix, 'event:', event.type].join(' ').trim()); - }); - } - - // Callback - utils.event(instance.getContainer(), 'setup', true, { - plyr: instance - }); - - // Add to return array even if it's already setup - instances.push(instance); - }); - - return instances; - } - - // Get all instances within a provided container - function get(container) { - if (is.string(container)) { - // Get selector if string passed - container = document.querySelector(container); - } else if (is.undefined(container)) { - // Use body by default to get all on page - container = document.body; - } - - // If we have a HTML element - if (is.htmlElement(container)) { - var elements = container.querySelectorAll('.' + defaults.classes.setup), - instances = []; - - Array.prototype.slice.call(elements).forEach(function(element) { - if (is.object(element.plyr)) { - instances.push(element.plyr); - } - }); - - return instances; - } - - return []; - } - - return { - setup: setup, - supported: getSupport, - loadSprite: loadSprite, - get: get - }; + return Player; })); - -// Custom event polyfill -// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent -(function() { - if (typeof window.CustomEvent === 'function') { - return; - } - - function CustomEvent(event, params) { - params = params || { - bubbles: false, - cancelable: false, - detail: undefined - }; - var evt = document.createEvent('CustomEvent'); - evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); - return evt; - } - - CustomEvent.prototype = window.Event.prototype; - - window.CustomEvent = CustomEvent; -})(); |