/* Minification failed. Returning unminified contents.
(29053,33-34): run-time error JS1014: Invalid character: `
(29053,34-35): run-time error JS1195: Expected expression: &
(29053,51-52): run-time error JS1014: Invalid character: `
(29055,33-34): run-time error JS1014: Invalid character: `
(29055,34-35): run-time error JS1195: Expected expression: ?
(29055,51-52): run-time error JS1014: Invalid character: `
 */
/*! Respond.js v1.4.2: min/max-width media query polyfill
 * Copyright 2014 Scott Jehl
 * Licensed under MIT
 * http://j.mp/respondjs */
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
(function(n){"use strict";n.matchMedia=n.matchMedia||function(n){var u,i=n.documentElement,f=i.firstElementChild||i.firstChild,r=n.createElement("body"),t=n.createElement("div");return t.id="mq-test-1",t.style.cssText="position:absolute;top:-100em",r.style.background="none",r.appendChild(t),function(n){return t.innerHTML='&shy;<style media="'+n+'"> #mq-test-1 { width: 42px; }<\/style>',i.insertBefore(r,f),u=t.offsetWidth===42,i.removeChild(r),{matches:u,media:n}}}(n.document)})(this),function(n){"use strict";function tt(){y(!0)}var t={};n.respond=t;t.update=function(){};var f=[],it=function(){var t=!1;try{t=new n.XMLHttpRequest}catch(i){t=new n.ActiveXObject("Microsoft.XMLHTTP")}return function(){return t}}(),p=function(n,t){var i=it();i&&(i.open("GET",n,!0),i.onreadystatechange=function(){i.readyState===4&&(i.status===200||i.status===304)&&t(i.responseText)},i.readyState!==4)&&i.send(null)},w=function(n){return n.replace(t.regex.minmaxwh,"").match(t.regex.other)};if(t.ajax=p,t.queue=f,t.unsupportedmq=w,t.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,comments:/\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,maxw:/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,minmaxwh:/\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,other:/\([^\)]*\)/g},t.mediaQueriesSupported=n.matchMedia&&n.matchMedia("only all")!==null&&n.matchMedia("only all").matches,!t.mediaQueriesSupported){var i=n.document,r=i.documentElement,e=[],o=[],u=[],c={},b=30,s=i.getElementsByTagName("head")[0]||r,rt=i.getElementsByTagName("base")[0],h=s.getElementsByTagName("link"),l,k,a,v=function(){var f,t=i.createElement("div"),n=i.body,o=r.style.fontSize,e=n&&n.style.fontSize,u=!1;return t.style.cssText="position:absolute;font-size:1em;width:1em",n||(n=u=i.createElement("body"),n.style.background="none"),r.style.fontSize="100%",n.style.fontSize="100%",n.appendChild(t),u&&r.insertBefore(n,r.firstChild),f=t.offsetWidth,u?r.removeChild(n):n.removeChild(t),r.style.fontSize=o,e&&(n.style.fontSize=e),a=parseFloat(f)},y=function(t){var rt="clientWidth",ut=r[rt],ft=i.compatMode==="CSS1Compat"&&ut||i.body[rt]||ut,p={},ct=h[h.length-1],et=(new Date).getTime(),tt,g,nt,f,it;if(t&&l&&et-l<b){n.clearTimeout(k);k=n.setTimeout(y,b);return}l=et;for(tt in e)if(e.hasOwnProperty(tt)){var c=e[tt],w=c.minw,d=c.maxw,ot=w===null,st=d===null,ht="em";!w||(w=parseFloat(w)*(w.indexOf(ht)>-1?a||v():1));!d||(d=parseFloat(d)*(d.indexOf(ht)>-1?a||v():1));c.hasquery&&(ot&&st||!(ot||ft>=w)||!(st||ft<=d))||(p[c.media]||(p[c.media]=[]),p[c.media].push(o[c.rules]))}for(g in u)u.hasOwnProperty(g)&&u[g]&&u[g].parentNode===s&&s.removeChild(u[g]);u.length=0;for(nt in p)p.hasOwnProperty(nt)&&(f=i.createElement("style"),it=p[nt].join("\n"),f.type="text/css",f.media=nt,s.insertBefore(f,ct.nextSibling),f.styleSheet?f.styleSheet.cssText=it:f.appendChild(i.createTextNode(it)),u.push(f))},d=function(n,i,r){var h=n.replace(t.regex.comments,"").replace(t.regex.keyframes,"").match(t.regex.media),c=h&&h.length||0,l,a,f,v,u,p,b,s;for(i=i.substring(0,i.lastIndexOf("/")),l=function(n){return n.replace(t.regex.urls,"$1"+i+"$2$3")},a=!c&&r,i.length&&(i+="/"),a&&(c=1),f=0;f<c;f++)for(a?(v=r,o.push(l(n))):(v=h[f].match(t.regex.findStyles)&&RegExp.$1,o.push(RegExp.$2&&l(RegExp.$2))),p=v.split(","),b=p.length,s=0;s<b;s++)(u=p[s],w(u))||e.push({media:u.split("(")[0].match(t.regex.only)&&RegExp.$2||"all",rules:o.length-1,hasquery:u.indexOf("(")>-1,minw:u.match(t.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:u.match(t.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")});y()},g=function(){if(f.length){var t=f.shift();p(t.href,function(i){d(i,t.href,t.media);c[t.href]=!0;n.setTimeout(function(){g()},0)})}},nt=function(){for(var r=0;r<h.length;r++){var i=h[r],t=i.href,u=i.media,e=i.rel&&i.rel.toLowerCase()==="stylesheet";!t||!e||c[t]||(i.styleSheet&&i.styleSheet.rawCssText?(d(i.styleSheet.rawCssText,t,u),c[t]=!0):(/^([a-zA-Z:]*\/\/)/.test(t)||rt)&&t.replace(RegExp.$1,"").split("/")[0]!==n.location.host||(t.substring(0,2)==="//"&&(t=n.location.protocol+t),f.push({href:t,media:u})))}g()};nt();t.update=nt;t.getEmValue=v;n.addEventListener?n.addEventListener("resize",tt,!1):n.attachEvent&&n.attachEvent("onresize",tt)}}(this);
//# sourceMappingURL=respond.min.js.map
;
/*!
 * VERSION: 1.17.0
 * DATE: 2015-05-27
 * UPDATES AND DOCS AT: http://greensock.com
 *
 * @license Copyright (c) 2008-2015, GreenSock. All rights reserved.
 * This work is subject to the terms at http://greensock.com/standard-license or for
 * Club GreenSock members, the software agreement that was issued with your membership.
 *
 * @author: Jack Doyle, jack@greensock.com
 */

/*!
* LayerSlider is using TweenLite, TimeLineLite, EasePack & CSSPlugin
*/

;eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('!18(t,e){"4I 4J";1b i=t.5r=t.5r||t;1c(!i.3A){1b r,s,n,a,o,l=18(t){1b e,r=t.1t("."),s=i;1d(e=0;r.1f>e;e++)s[r[e]]=s=s[r[e]]||{};1a s},h=l("5p.5o"),u=1e-10,f=18(t){1b e,i=[],r=t.1f;1d(e=0;e!==r;i.24(t[e++]));1a i},p=18(){},19=18(){1b t=az.1A.a1,e=t.2h([]);1a 18(i){1a 1g!=i&&(i 2p 42||"4q"==1k i&&!!i.24&&t.2h(i)===e)}}(),c={},d=18(r,s,n,a){15.59=c[r]?c[r].59:[],c[r]=15,15.5C=1g,15.9D=n;1b o=[];15.6Q=18(h){1d(1b u,f,p,19,m=s.1f,g=m;--m>-1;)(u=c[s[m]]||1j d(s[m],[])).5C?(o[m]=u.5C,g--):h&&u.59.24(15);1c(0===g&&n)1d(f=("5p.5o."+r).1t("."),p=f.4K(),19=l(f.1I("."))[p]=15.5C=n.4i(n,o),a&&(i[p]=19,"18"==1k 3H&&3H.6R?3H((t.8U?t.8U+"/":"")+r.1t(".").4K(),[],18(){1a 19}):r===e&&"37"!=1k 2k&&2k.3n&&(2k.3n=19)),m=0;15.59.1f>m;m++)15.59[m].6Q()},15.6Q(!0)},m=t.3J=18(t,e,i,r){1a 1j d(t,e,i,r)},g=h.8z=18(t,e,i){1a e=e||18(){},m(t,[],18(){1a e},i),e};m.70=i;1b v=[0,0,1,1],x=[],y=g("2A.8A",18(t,e,i,r){15.7b=t,15.7C=i||0,15.7A=r||0,15.7a=e?v.4O(e):v},!0),T=y.8Y={},w=y.8y=18(t,e,i,r){1d(1b s,n,a,o,l=e.1t(","),u=l.1f,f=(i||"5G,6U,5A").1t(",");--u>-1;)1d(n=l[u],s=r?g("2A."+n,1g,!0):h.2A[n]||{},a=f.1f;--a>-1;)o=f[a],T[n+"."+o]=T[o+n]=s[o]=t.2C?t:t[o]||1j t};1d(n=y.1A,n.3T=!1,n.2C=18(t){1c(15.7b)1a 15.7a[0]=t,15.7b.4i(1g,15.7a);1b e=15.7C,i=15.7A,r=1===e?1-t:2===e?t:.5>t?2*t:2*(1-t);1a 1===i?r*=r:2===i?r*=r*r:3===i?r*=r*r*r:4===i&&(r*=r*r*r*r),1===e?1-r:2===e?r:.5>t?r/2:1-r/2},r=["9o","7T","bt","aW","aM,aP"],s=r.1f;--s>-1;)n=r[s]+",ba"+s,w(1j y(1g,1g,1,s),n,"6U",!0),w(1j y(1g,1g,2,s),n,"5G"+(0===s?",aH":"")),w(1j y(1g,1g,3,s),n,"5A");T.bz=h.2A.9o.5G,T.an=h.2A.7T.5A;1b b=g("8q.8p",18(t){15.4n={},15.7R=t||15});n=b.1A,n.9V=18(t,e,i,r,s){s=s||0;1b n,l,h=15.4n[t],u=0;1d(1g==h&&(15.4n[t]=h=[]),l=h.1f;--l>-1;)n=h[l],n.c===e&&n.s===i?h.3c(l,1):0===u&&s>n.2w&&(u=l+1);h.3c(u,0,{c:e,s:i,8Z:r,2w:s}),15!==a||o||a.3g()},n.bm=18(t,e){1b i,r=15.4n[t];1c(r)1d(i=r.1f;--i>-1;)1c(r[i].c===e)1a 2y r.3c(i,1)},n.8v=18(t){1b e,i,r,s=15.4n[t];1c(s)1d(e=s.1f,i=15.7R;--e>-1;)r=s[e],r&&(r.8Z?r.c.2h(r.s||i,{2f:t,2J:i}):r.c.2h(r.s||i))};1b P=t.aJ,O=t.aw,S=84.aN||18(){1a(1j 84).bs()},k=S();1d(r=["6a","bq","9U","o"],s=r.1f;--s>-1&&!P;)P=t[r[s]+"bp"],O=t[r[s]+"bk"]||t[r[s]+"a8"];g("6f",18(t,e){1b i,r,s,n,l,h=15,f=S(),19=e!==!1&&P,c=a5,d=33,m="6h",g=18(t){1b e,a,o=S()-k;o>c&&(f+=o-d),k+=o,h.3q=(k-f)/8l,e=h.3q-l,(!i||e>0||t===!0)&&(h.3C++,l+=e+(e>=n?.aF:n-e),a=!0),t!==!0&&(s=r(g)),a&&h.8v(m)};b.2h(h),h.3q=h.3C=0,h.6h=18(){g(!0)},h.7e=18(t,e){c=t||1/u,d=1i.aD(e,c,0)},h.67=18(){1g!=s&&(19&&O?O(s):ao(s),r=p,s=1g,h===a&&(o=!1))},h.3g=18(){1g!==s?h.67():h.3C>10&&(k=S()-c+5),r=0===i?p:19&&P?P:18(t){1a 6j(t,0|8l*(l-h.3q)+1)},h===a&&(o=!0),g(2)},h.6T=18(t){1a 2n.1f?(i=t,n=1/(i||60),l=15.3q+n,2y h.3g()):i},h.8j=18(t){1a 2n.1f?(h.67(),19=t,2y h.6T(i)):19},h.6T(t),6j(18(){19&&5>h.3C&&h.8j(!1)},aI)}),n=h.6f.1A=1j h.8q.8p,n.2V=h.6f;1b A=g("5N.93",18(t,e){1c(15.1w=e=e||{},15.1D=15.2i=t||0,15.2K=1P(e.4F)||0,15.1C=1,15.2l=e.1X===!0,15.1y=e.1y,15.2F=e.4y===!0,V){o||a.3g();1b i=15.1w.7l?j:V;i.1V(15,i.1p),15.1w.2W&&15.2W(!0)}});a=A.78=1j h.6f,n=A.1A,n.2z=n.1K=n.2u=n.1F=!1,n.1E=n.1p=0,n.1B=-1,n.1h=n.3i=n.3O=n.1r=n.26=1g,n.1F=!1;1b C=18(){o&&S()-k>8E&&a.3g(),6j(C,8E)};C(),n.7P=18(t,e){1a 1g!=t&&15.41(t,e),15.4y(!1).2W(!1)},n.7f=18(t,e){1a 1g!=t&&15.41(t,e),15.2W(!0)},n.aa=18(t,e){1a 1g!=t&&15.41(t,e),15.2W(!1)},n.41=18(t,e){1a 15.2R(1P(t),e!==!1)},n.ah=18(t,e){1a 15.4y(!1).2W(!1).2R(t?-15.2K:0,e!==!1,!0)},n.80=18(t,e){1a 1g!=t&&15.41(t||15.27(),e),15.4y(!0).2W(!1)},n.1G=18(){},n.4H=18(){1a 15.1p=15.1E=0,15.2u=15.1K=!1,15.1B=-1,(15.1K||!15.26)&&15.1H(!0),15},n.5c=18(){1b t,e=15.1r,i=15.1l;1a!e||!15.1K&&!15.1F&&e.5c()&&(t=e.4g())>=i&&i+15.27()/15.1C>t},n.1H=18(t,e){1a o||a.3g(),15.1K=!t,15.2l=15.5c(),e!==!0&&(t&&!15.26?15.1r.1V(15,15.1l-15.2K):!t&&15.26&&15.1r.40(15,!0)),!1},n.2s=18(){1a 15.1H(!1,!1)},n.3R=18(t,e){1a 15.2s(t,e),15},n.3m=18(t){1d(1b e=t?15:15.26;e;)e.2z=!0,e=e.26;1a 15},n.5R=18(t){1d(1b e=t.1f,i=t.4O();--e>-1;)"{5v}"===t[e]&&(i[e]=15);1a i},n.4j=18(t){1b e=15.1w;e[t].4i(e[t+"8h"]||e.5s||15,e[t+"8I"]||x)},n.ab=18(t,e,i,r){1c("bw"===(t||"").1u(0,2)){1b s=15.1w;1c(1===2n.1f)1a s[t];1g==e?4d s[t]:(s[t]=e,s[t+"8I"]=19(i)&&-1!==i.1I("").1m("{5v}")?15.5R(i):i,s[t+"8h"]=r),"4B"===t&&(15.3O=e)}1a 15},n.4F=18(t){1a 2n.1f?(15.1r.2r&&15.8M(15.1l+t-15.2K),15.2K=t,15):15.2K},n.2B=18(t){1a 2n.1f?(15.1D=15.2i=t,15.3m(!0),15.1r.2r&&15.1p>0&&15.1p<15.1D&&0!==t&&15.2R(15.1E*(t/15.1D),!0),15):(15.2z=!1,15.1D)},n.27=18(t){1a 15.2z=!1,2n.1f?15.2B(t):15.2i},n.3q=18(t,e){1a 2n.1f?(15.2z&&15.27(),15.2R(t>15.1D?15.1D:t,e)):15.1p},n.2R=18(t,e,i){1c(o||a.3g(),!2n.1f)1a 15.1E;1c(15.1r){1c(0>t&&!i&&(t+=15.27()),15.1r.2r){15.2z&&15.27();1b r=15.2i,s=15.1r;1c(t>r&&!i&&(t=r),15.1l=(15.1F?15.5g:s.1p)-(15.2F?r-t:t)/15.1C,s.2z||15.3m(!1),s.1r)1d(;s.1r;)s.1r.1p!==(s.1l+s.1E)/s.1C&&s.2R(s.1E,!0),s=s.1r}15.1K&&15.1H(!0,!1),(15.1E!==t||0===15.1D)&&(15.1G(t,e,!1),z.1f&&q())}1a 15},n.bv=n.br=18(t,e){1a 2n.1f?15.2R(15.2B()*t,e):15.1p/15.2B()},n.8M=18(t){1a 2n.1f?(t!==15.1l&&(15.1l=t,15.26&&15.26.4V&&15.26.1V(15,t-15.2K)),15):15.1l},n.aR=18(t){1a 15.1l+(0!=t?15.27():15.2B())/15.1C},n.6M=18(t){1c(!2n.1f)1a 15.1C;1c(t=t||u,15.1r&&15.1r.2r){1b e=15.5g,i=e||0===e?e:15.1r.2R();15.1l=i-(i-15.1l)*15.1C/t}1a 15.1C=t,15.3m(!1)},n.4y=18(t){1a 2n.1f?(t!=15.2F&&(15.2F=t,15.2R(15.1r&&!15.1r.2r?15.27()-15.1E:15.1E,!0)),15):15.2F},n.2W=18(t){1c(!2n.1f)1a 15.1F;1b e,i,r=15.1r;1a t!=15.1F&&r&&(o||t||a.3g(),e=r.4g(),i=e-15.5g,!t&&r.2r&&(15.1l+=i,15.3m(!1)),15.5g=t?e:1g,15.1F=t,15.2l=15.5c(),!t&&0!==i&&15.2u&&15.2B()&&15.1G(r.2r?15.1E:(e-15.1l)/15.1C,!0,!0)),15.1K&&!t&&15.1H(!0,!1),15};1b R=g("5N.95",18(t){A.2h(15,0,t),15.3N=15.2r=!0});n=R.1A=1j A,n.2V=R,n.3R().1K=!1,n.28=n.3i=n.4W=1g,n.4V=!1,n.1V=n.85=18(t,e){1b i,r;1c(t.1l=1P(e||0)+t.2K,t.1F&&15!==t.1r&&(t.5g=t.1l+(15.4g()-t.1l)/t.1C),t.26&&t.26.40(t,!0),t.26=t.1r=15,t.1K&&t.1H(!0,!0),i=15.3i,15.4V)1d(r=t.1l;i&&i.1l>r;)i=i.1n;1a i?(t.1h=i.1h,i.1h=t):(t.1h=15.28,15.28=t),t.1h?t.1h.1n=t:15.3i=t,t.1n=i,15.4W=t,15.1r&&15.3m(!0),15},n.40=18(t,e){1a t.26===15&&(e||t.1H(!1,!0),t.1n?t.1n.1h=t.1h:15.28===t&&(15.28=t.1h),t.1h?t.1h.1n=t.1n:15.3i===t&&(15.3i=t.1n),t.1h=t.1n=t.26=1g,t===15.4W&&(15.4W=15.3i),15.1r&&15.3m(!0)),15},n.1G=18(t,e,i){1b r,s=15.28;1d(15.1E=15.1p=15.1B=t;s;)r=s.1h,(s.2l||t>=s.1l&&!s.1F)&&(s.2F?s.1G((s.2z?s.27():s.2i)-(t-s.1l)*s.1C,e,i):s.1G((t-s.1l)*s.1C,e,i)),s=r},n.4g=18(){1a o||a.3g(),15.1E};1b M=g("3A",18(e,i,r){1c(A.2h(15,i,r),15.1G=M.1A.1G,1g==e)7g"7W 3V a 1g 2J.";15.2J=e="1O"!=1k e?e:M.48(e)||e;1b s,n,a,o=e.aQ||e.1f&&e!==t&&e[0]&&(e[0]===t||e[0].3S&&e[0].1v&&!e.3S),l=15.1w.5e;1c(15.7j=l=1g==l?B[M.7O]:"2E"==1k l?l>>0:B[l],(o||e 2p 42||e.24&&19(e))&&"2E"!=1k e[0])1d(15.2N=a=f(e),15.4a=[],15.3b=[],s=0;a.1f>s;s++)n=a[s],n?"1O"!=1k n?n.1f&&n!==t&&n[0]&&(n[0]===t||n[0].3S&&n[0].1v&&!n.3S)?(a.3c(s--,1),15.2N=a=a.4O(f(n))):(15.3b[s]=W(n,15,!1),1===l&&15.3b[s].1f>1&&G(n,15,1g,1,15.3b[s])):(n=a[s--]=M.48(n),"1O"==1k n&&a.3c(s+1,1)):a.3c(s--,1);1o 15.4a={},15.3b=W(e,15,!1),1===l&&15.3b.1f>1&&G(e,15,1g,1,15.3b);(15.1w.1X||0===i&&0===15.2K&&15.1w.1X!==!1)&&(15.1p=-u,15.1G(-15.2K))},!0),D=18(e){1a e&&e.1f&&e!==t&&e[0]&&(e[0]===t||e[0].3S&&e[0].1v&&!e.3S)},X=18(t,e){1b i,r={};1d(i 1x t)Y[i]||i 1x e&&"2Q"!==i&&"x"!==i&&"y"!==i&&"2D"!==i&&"3j"!==i&&"3M"!==i&&"4w"!==i||!(!N[i]||N[i]&&N[i].aX)||(r[i]=t[i],4d t[i]);t.57=r};n=M.1A=1j A,n.2V=M,n.3R().1K=!1,n.3x=0,n.1s=n.2N=n.3z=n.1Z=1g,n.56=n.3k=!1,M.4M="1.17.0",M.7B=n.2M=1j y(1g,1g,1,1),M.7O="2m",M.78=a,M.7y=9K,M.7e=18(t,e){a.7e(t,e)},M.48=t.$||t.7X||18(e){1b i=t.$||t.7X;1a i?(M.48=i,i(e)):"37"==1k 52?e:52.91?52.91(e):52.af("#"===e.1z(0)?e.1u(1):e)};1b z=[],F={},I=M.5f={9Y:19,9g:D,9Z:z},N=M.am={},E=I.a9={},L=0,Y=I.9C={4e:1,4F:1,5e:1,4E:1,6s:1,at:1,7l:1,5d:1,3o:1,4B:1,aY:1,b5:1,5h:1,b0:1,aZ:1,3Z:1,96:1,aS:1,by:1,bh:1,ac:1,69:1,aC:1,1X:1,5M:1,ar:1,1y:1,2W:1,4y:1,7n:1,2Z:1,5n:1,5s:1},B={3E:0,4A:1,2m:2,aK:3,au:4,av:5,"bo":1,"as":0},j=A.8n=1j R,V=A.ap=1j R,U=30,q=I.9P=18(){1b t,e=z.1f;1d(F={};--e>-1;)t=z[e],t&&t.3k!==!1&&(t.1G(t.3k[0],t.3k[1],!0),t.3k=!1);z.1f=0};V.1l=a.3q,j.1l=a.3C,V.2l=j.2l=!0,6j(q,1),A.8H=M.1G=18(){1b t,e,i;1c(z.1f&&q(),V.1G((a.3q-V.1l)*V.1C,!1,!1),j.1G((a.3C-j.1l)*j.1C,!1,!1),z.1f&&q(),a.3C>=U){U=a.3C+(3l(M.7y,10)||9K);1d(i 1x E){1d(e=E[i].3X,t=e.1f;--t>-1;)e[t].1K&&e.3c(t,1);0===e.1f&&4d E[i]}1c(i=V.28,(!i||i.1F)&&M.7y&&!j.28&&1===a.4n.6h.1f){1d(;i&&i.1F;)i=i.1h;i||a.67()}}},a.9V("6h",A.8H);1b W=18(t,e,i){1b r,s,n=t.6b;1c(E[n||(t.6b=n="t"+L++)]||(E[n]={2J:t,3X:[]}),e&&(r=E[n].3X,r[s=r.1f]=e,i))1d(;--s>-1;)r[s]===e&&r.3c(s,1);1a E[n].3X},Z=18(t,e,i,r){1b s,n,a=t.1w.5n;1a a&&(s=a(t,e,i,r)),a=M.5n,a&&(n=a(t,e,i,r)),s!==!1&&n!==!1},G=18(t,e,i,r,s){1b n,a,o,l;1c(1===r||r>=4){1d(l=s.1f,n=0;l>n;n++)1c((o=s[n])!==e)o.1K||o.2s(1g,t,e)&&(a=!0);1o 1c(5===r)8u;1a a}1b h,f=e.1l+u,p=[],19=0,c=0===e.1D;1d(n=s.1f;--n>-1;)(o=s[n])===e||o.1K||o.1F||(o.1r!==e.1r?(h=h||Q(e,0,c),0===Q(o,h,c)&&(p[19++]=o)):f>=o.1l&&o.1l+o.27()/o.1C>f&&((c||!o.2u)&&2e-10>=f-o.1l||(p[19++]=o)));1d(n=19;--n>-1;)1c(o=p[n],2===r&&o.2s(i,t,e)&&(a=!0),2!==r||!o.1s&&o.2u){1c(2!==r&&!Z(o,e))aV;o.1H(!1,!1)&&(a=!0)}1a a},Q=18(t,e,i){1d(1b r=t.1r,s=r.1C,n=t.1l;r.1r;){1c(n+=r.1l,s*=r.1C,r.1F)1a-1M;r=r.1r}1a n/=s,n>e?n-e:i&&n===e||!t.2u&&2*u>n-e?u:(n+=t.27()/t.1C/s)>e+u?0:n-e-u};n.7o=18(){1b t,e,i,r,s,n=15.1w,a=15.3z,o=15.1D,l=!!n.1X,h=n.4e;1c(n.3o){15.1Z&&(15.1Z.1G(-1,!0),15.1Z.3R()),s={};1d(r 1x n.3o)s[r]=n.3o[r];1c(s.5e=!1,s.1X=!0,s.2Z=l&&n.2Z!==!1,s.3o=s.4F=1g,15.1Z=M.4p(15.2J,0,s),l)1c(15.1p>0)15.1Z=1g;1o 1c(0!==o)1a}1o 1c(n.5d&&0!==o)1c(15.1Z)15.1Z.1G(-1,!0),15.1Z.3R(),15.1Z=1g;1o{0!==15.1p&&(l=!1),i={};1d(r 1x n)Y[r]&&"7n"!==r||(i[r]=n[r]);1c(i.5e=0,i.1y="82",i.2Z=l&&n.2Z!==!1,i.1X=l,15.1Z=M.4p(15.2J,0,i),l){1c(0===15.1p)1a}1o 15.1Z.7o(),15.1Z.1H(!1),15.1w.1X&&(15.1Z=1g)}1c(15.2M=h=h?h 2p y?h:"18"==1k h?1j y(h,n.69):T[h]||M.7B:M.7B,n.69 2p 42&&h.3y&&(15.2M=h.3y.4i(h,n.69)),15.7i=15.2M.7C,15.8r=15.2M.7A,15.1s=1g,15.2N)1d(t=15.2N.1f;--t>-1;)15.5m(15.2N[t],15.4a[t]={},15.3b[t],a?a[t]:1g)&&(e=!0);1o e=15.5m(15.2J,15.4a,15.3b,a);1c(e&&M.64("5S",15),a&&(15.1s||"18"!=1k 15.2J&&15.1H(!1,!1)),n.5d)1d(i=15.1s;i;)i.s+=i.c,i.c=-i.c,i=i.1h;15.3O=n.4B,15.2u=!0},n.5m=18(e,i,r,s){1b n,a,o,l,h,u;1c(1g==e)1a!1;F[e.6b]&&q(),15.1w.57||e.1v&&e!==t&&e.3S&&N.57&&15.1w.7n!==!1&&X(15.1w,e);1d(n 1x 15.1w){1c(u=15.1w[n],Y[n])u&&(u 2p 42||u.24&&19(u))&&-1!==u.1I("").1m("{5v}")&&(15.1w[n]=u=15.5R(u,15));1o 1c(N[n]&&(l=1j N[n]).72(e,15.1w[n],15)){1d(15.1s=h={1h:15.1s,t:l,p:"1Y",s:0,c:1,f:!0,n:n,5u:!0,2w:l.74},a=l.2P.1f;--a>-1;)i[l.2P[a]]=15.1s;(l.74||l.5S)&&(o=!0),(l.7x||l.9i)&&(15.56=!0)}1o 15.1s=i[n]=h={1h:15.1s,t:e,p:n,f:"18"==1k e[n],n:n,5u:!1,2w:0},h.s=h.f?e[n.1m("4Q")||"18"!=1k e["8P"+n.1u(3)]?n:"8P"+n.1u(3)]():1q(e[n]),h.c="1O"==1k u&&"="===u.1z(1)?3l(u.1z(0)+"1",10)*1P(u.1u(2)):1P(u)-h.s||0;h&&h.1h&&(h.1h.1n=h)}1a s&&15.2s(s,e)?15.5m(e,i,r,s):15.7j>1&&15.1s&&r.1f>1&&G(e,15,i,15.7j,r)?(15.2s(i,e),15.5m(e,i,r,s)):(15.1s&&(15.1w.2Z!==!1&&15.1D||15.1w.2Z&&!15.1D)&&(F[e.6b]=!0),o)},n.1G=18(t,e,i){1b r,s,n,a,o=15.1p,l=15.1D,h=15.1B;1c(t>=l)15.1E=15.1p=l,15.3x=15.2M.3T?15.2M.2C(1):1,15.2F||(r=!0,s="4E",i=i||15.1r.3N),0===l&&(15.2u||!15.1w.2Z||i)&&(15.1l===15.1r.1D&&(t=0),(0===t||0>h||h===u&&"5B"!==15.1y)&&h!==t&&(i=!0,h>u&&(s="3Z")),15.1B=a=!e||t||h===t?t:u);1o 1c(1e-7>t)15.1E=15.1p=0,15.3x=15.2M.3T?15.2M.2C(0):0,(0!==o||0===l&&h>0)&&(s="3Z",r=15.2F),0>t&&(15.2l=!1,0===l&&(15.2u||!15.1w.2Z||i)&&(h>=0&&(h!==u||"5B"!==15.1y)&&(i=!0),15.1B=a=!e||t||h===t?t:u)),15.2u||(i=!0);1o 1c(15.1E=15.1p=t,15.7i){1b f=t/l,p=15.7i,19=15.8r;(1===p||3===p&&f>=.5)&&(f=1-f),3===p&&(f*=2),1===19?f*=f:2===19?f*=f*f:3===19?f*=f*f*f:4===19&&(f*=f*f*f*f),15.3x=1===p?1-f:2===p?f:.5>t/l?f/2:1-f/2}1o 15.3x=15.2M.2C(t/l);1c(15.1p!==o||i){1c(!15.2u){1c(15.7o(),!15.2u||15.1K)1a;1c(!i&&15.1s&&(15.1w.2Z!==!1&&15.1D||15.1w.2Z&&!15.1D))1a 15.1p=15.1E=o,15.1B=h,z.24(15),2y(15.3k=[t,e]);15.1p&&!r?15.3x=15.2M.2C(15.1p/l):r&&15.2M.3T&&(15.3x=15.2M.2C(0===15.1p?0:1))}1d(15.3k!==!1&&(15.3k=!1),15.2l||!15.1F&&15.1p!==o&&t>=0&&(15.2l=!0),0===o&&(15.1Z&&(t>=0?15.1Z.1G(t,e,i):s||(s="bA")),15.1w.5h&&(0!==15.1p||0===l)&&(e||15.4j("5h"))),n=15.1s;n;)n.f?n.t[n.p](n.c*15.3x+n.s):n.t[n.p]=n.c*15.3x+n.s,n=n.1h;15.3O&&(0>t&&15.1Z&&t!==-1e-4&&15.1Z.1G(t,e,i),e||(15.1p!==o||r)&&15.4j("4B")),s&&(!15.1K||i)&&(0>t&&15.1Z&&!15.3O&&t!==-1e-4&&15.1Z.1G(t,e,i),r&&(15.1r.3N&&15.1H(!1,!1),15.2l=!1),!e&&15.1w[s]&&15.4j(s),0===l&&15.1B===u&&a!==u&&(15.1B=0))}},n.2s=18(t,e,i){1c("4A"===t&&(t=1g),1g==t&&(1g==e||e===15.2J))1a 15.3k=!1,15.1H(!1,!1);e="1O"!=1k e?e||15.2N||15.2J:M.48(e)||e;1b r,s,n,a,o,l,h,u,f,p=i&&15.1p&&i.1l===15.1l&&15.1r===i.1r;1c((19(e)||D(e))&&"2E"!=1k e[0])1d(r=e.1f;--r>-1;)15.2s(t,e[r],i)&&(l=!0);1o{1c(15.2N){1d(r=15.2N.1f;--r>-1;)1c(e===15.2N[r]){o=15.4a[r]||{},15.3z=15.3z||[],s=15.3z[r]=t?15.3z[r]||{}:"4A";8u}}1o{1c(e!==15.2J)1a!1;o=15.4a,s=15.3z=t?15.3z||{}:"4A"}1c(o){1c(h=t||o,u=t!==s&&"4A"!==s&&t!==o&&("4q"!=1k t||!t.aA),i&&(M.5n||15.1w.5n)){1d(n 1x h)o[n]&&(f||(f=[]),f.24(n));1c((f||!t)&&!Z(15,i,e,f))1a!1}1d(n 1x h)(a=o[n])&&(p&&(a.f?a.t[a.p](a.s):a.t[a.p]=a.s,l=!0),a.5u&&a.t.2s(h)&&(l=!0),a.5u&&0!==a.t.2P.1f||(a.1n?a.1n.1h=a.1h:a===15.1s&&(15.1s=a.1h),a.1h&&(a.1h.1n=a.1n),a.1h=a.1n=1g),4d o[n]),u&&(s[n]=1);!15.1s&&15.2u&&15.1H(!1,!1)}}1a l},n.4H=18(){1a 15.56&&M.64("7x",15),15.1s=15.3z=15.1Z=15.3O=1g,15.56=15.2l=15.3k=!1,15.4a=15.2N?{}:[],A.1A.4H.2h(15),15.1w.1X&&(15.1p=-u,15.1G(-15.2K)),15},n.1H=18(t,e){1c(o||a.3g(),t&&15.1K){1b i,r=15.2N;1c(r)1d(i=r.1f;--i>-1;)15.3b[i]=W(r[i],15,!0);1o 15.3b=W(15.2J,15,!0)}1a A.1A.1H.2h(15,t,e),15.56&&15.1s?M.64(t?"9i":"7x",15):!1},M.4p=18(t,e,i){1a 1j M(t,e,i)},M.6q=18(t,e,i){1a i.5d=!0,i.1X=0!=i.1X,1j M(t,e,i)},M.5Z=18(t,e,i,r){1a r.3o=i,r.1X=0!=r.1X&&0!=i.1X,1j M(t,e,r)},M.4v=18(t,e,i,r,s){1a 1j M(e,0,{4F:t,4E:e,6s:i,5s:r,3Z:e,96:i,1X:!1,2Z:!1,7l:s,5e:0})},M.4Q=18(t,e){1a 1j M(t,0,e)},M.4C=18(t,e){1c(1g==t)1a[];t="1O"!=1k t?t:M.48(t)||t;1b i,r,s,n;1c((19(t)||D(t))&&"2E"!=1k t[0]){1d(i=t.1f,r=[];--i>-1;)r=r.4O(M.4C(t[i],e));1d(i=r.1f;--i>-1;)1d(n=r[i],s=i;--s>-1;)n===r[s]&&r.3c(i,1)}1o 1d(r=W(t).4O(),i=r.1f;--i>-1;)(r[i].1K||e&&!r[i].5c())&&r.3c(i,1);1a r},M.aj=M.aq=18(t,e,i){"4q"==1k e&&(i=e,e=!1);1d(1b r=M.4C(t,e),s=r.1f;--s>-1;)r[s].2s(i,t)};1b $=g("5q.8O",18(t,e){15.2P=(t||"").1t(","),15.5t=15.2P[0],15.74=e||0,15.a3=$.1A},!0);1c(n=$.1A,$.4M="1.10.1",$.49=2,n.1s=1g,n.a6=18(t,e,i,r,s,n){1b a,o;1a 1g!=r&&(a="2E"==1k r||"="!==r.1z(1)?1P(r)-1P(i):3l(r.1z(0)+"1",10)*1P(r.1u(2)))?(15.1s=o={1h:15.1s,t:t,p:e,s:i,c:a,f:"18"==1k t[e],n:s||e,r:n},o.1h&&(o.1h.1n=o),o):2y 0},n.1Y=18(t){1d(1b e,i=15.1s,r=1e-6;i;)e=i.c*t+i.s,i.r?e=1i.3P(e):r>e&&e>-r&&(e=0),i.f?i.t[i.p](e):i.t[i.p]=e,i=i.1h},n.2s=18(t){1b e,i=15.2P,r=15.1s;1c(1g!=t[15.5t])15.2P=[];1o 1d(e=i.1f;--e>-1;)1g!=t[i[e]]&&i.3c(e,1);1d(;r;)1g!=t[r.n]&&(r.1h&&(r.1h.1n=r.1n),r.1n?(r.1n.1h=r.1h,r.1n=1g):15.1s===r&&(15.1s=r.1h)),r=r.1h;1a!1},n.9G=18(t,e){1d(1b i=15.1s;i;)(t[15.5t]||1g!=i.n&&t[i.n.1t(15.5t+"19").1I("")])&&(i.r=e),i=i.1h},M.64=18(t,e){1b i,r,s,n,a,o=e.1s;1c("5S"===t){1d(;o;){1d(a=o.1h,r=s;r&&r.2w>o.2w;)r=r.1h;(o.1n=r?r.1n:n)?o.1n.1h=o:s=o,(o.1h=r)?r.1n=o:n=o,o=a}o=e.1s=s}1d(;o;)o.5u&&"18"==1k o.t[t]&&o.t[t]()&&(i=!0),o=o.1h;1a i},$.6O=18(t){1d(1b e=t.1f;--e>-1;)t[e].49===$.49&&(N[(1j t[e]).5t]=t[e]);1a!0},m.2L=18(t){1c(!(t&&t.9J&&t.9H&&t.49))7g"ay 2L a4.";1b e,i=t.9J,r=t.6n||0,s=t.al,n={9H:"72",4Q:"1Y",3R:"2s",3P:"9G",aE:"5S"},a=g("5q."+i.1z(0).5Q()+i.1u(1)+"9Q",18(){$.2h(15,i,r),15.2P=s||[]},t.3G===!0),o=a.1A=1j $(i);o.2V=a,a.49=t.49;1d(e 1x n)"18"==1k t[e]&&(o[n[e]]=t[e]);1a a.4M=t.4M,$.6O([a]),a},r=t.3t){1d(s=0;r.1f>s;s++)r[s]();1d(n 1x c)c[n].9D||t.7d.7Q("bl aL bj bf: 5p.5o."+n)}o=!1}}("37"!=1k 2k&&2k.3n&&"37"!=1k 3G?3G:15||43,"3A");1b 1J="37"!=1k 2k&&2k.3n&&"37"!=1k 3G?3G:15||43;(1J.3t||(1J.3t=[])).24(18(){"4I 4J";1J.3J("8s",["5N.93","5N.95","3A"],18(t,e,i){1b r=18(t){e.2h(15,t),15.2U={},15.3N=15.1w.3N===!0,15.2r=15.1w.2r===!0,15.4V=!0,15.3O=15.1w.4B;1b i,r,s=15.1w;1d(r 1x s)i=s[r],l(i)&&-1!==i.1I("").1m("{5v}")&&(s[r]=15.5R(i));l(s.3X)&&15.1V(s.3X,0,s.b8,s.b1)},s=1e-10,n=i.5f,a=r.5f={},o=n.9g,l=n.9Y,h=n.9Z,u=n.9P,f=[],p=1J.3J.70,19=18(t){1b e,i={};1d(e 1x t)i[e]=t[e];1a i},c=a.aO=18(t,e,i,r){1b n,a=t.1r,o=a.1E,l=t.1l,h=0>t.1B||0===t.1B&&a.2F,u=h?0:s,p=h?s:0;1c(e||!15.58){1d(a.7f(l),n=t.1n;n&&n.1l===l;)n.1B=p,n=n.1n;1d(n=t.1h;n&&n.1l===l;)n.1B=u,n=n.1h;e&&e.4i(r||a.1w.5s||a,i||f),(15.58||!a.1F)&&a.41(o)}},d=18(t){1b e,i=[],r=t.1f;1d(e=0;e!==r;i.24(t[e++]));1a i},m=r.1A=1j e;1a r.4M="1.17.0",m.2V=r,m.3R().1K=m.58=!1,m.4p=18(t,e,r,s){1b n=r.5M&&p.7h||i;1a e?15.1V(1j n(t,e,r),s):15.4Q(t,r,s)},m.6q=18(t,e,r,s){1a 15.1V((r.5M&&p.7h||i).6q(t,e,r),s)},m.5Z=18(t,e,r,s,n){1b a=s.5M&&p.7h||i;1a e?15.1V(a.5Z(t,e,r,s),n):15.4Q(t,s,n)},m.6G=18(t,e,s,n,a,l,h,u){1b f,p=1j r({4E:l,6s:h,5s:u,2r:15.2r});1d("1O"==1k t&&(t=i.48(t)||t),t=t||[],o(t)&&(t=d(t)),n=n||0,0>n&&(t=d(t),t.80(),n*=-1),f=0;t.1f>f;f++)s.3o&&(s.3o=19(s.3o)),p.4p(t[f],e,19(s),f*n);1a 15.1V(p,a)},m.ax=18(t,e,i,r,s,n,a,o){1a i.1X=0!=i.1X,i.5d=!0,15.6G(t,e,i,r,s,n,a,o)},m.aB=18(t,e,i,r,s,n,a,o,l){1a r.3o=i,r.1X=0!=r.1X&&0!=i.1X,15.6G(t,e,r,s,n,a,o,l)},m.2h=18(t,e,r,s){1a 15.1V(i.4v(0,t,e,r),s)},m.4Q=18(t,e,r){1a r=15.3F(r,0,!0),1g==e.1X&&(e.1X=r===15.1p&&!15.1F),15.1V(1j i(t,0,e),r)},r.a0=18(t,e){t=t||{},1g==t.2r&&(t.2r=!0);1b s,n,a=1j r(t),o=a.1r;1d(1g==e&&(e=!0),o.40(a,!0),a.1l=0,a.1B=a.1p=a.1E=o.1p,s=o.28;s;)n=s.1h,e&&s 2p i&&s.2J===s.1w.4E||a.1V(s,s.1l-s.2K),s=n;1a o.1V(a,0),a},m.1V=18(s,n,a,o){1b h,u,f,p,19,c;1c("2E"!=1k n&&(n=15.3F(n,0,!0,s)),!(s 2p t)){1c(s 2p 42||s&&s.24&&l(s)){1d(a=a||"a2",o=o||0,h=n,u=s.1f,f=0;u>f;f++)l(p=s[f])&&(p=1j r({3X:p})),15.1V(p,h),"1O"!=1k p&&"18"!=1k p&&("ak"===a?h=p.1l+p.27()/p.1C:"ag"===a&&(p.1l-=p.4F())),h+=o;1a 15.3m(!0)}1c("1O"==1k s)1a 15.87(s,n);1c("18"!=1k s)7g"7W 1V "+s+" bi bd 26; bc bg 9h a 3V, 26, 18, bx 1O.";s=i.4v(0,s)}1c(e.1A.1V.2h(15,s,n),(15.1K||15.1p===15.1D)&&!15.1F&&15.1D<15.2B())1d(19=15,c=19.4g()>s.1l;19.1r;)c&&19.1r.2r?19.2R(19.1E,!0):19.1K&&19.1H(!0,!1),19=19.1r;1a 15},m.61=18(e){1c(e 2p t)1a 15.40(e,!1);1c(e 2p 42||e&&e.24&&l(e)){1d(1b i=e.1f;--i>-1;)15.61(e[i]);1a 15}1a"1O"==1k e?15.8g(e):15.3R(1g,e)},m.40=18(t,i){e.1A.40.2h(15,t,i);1b r=15.3i;1a r?15.1p>r.1l+r.2i/r.1C&&(15.1p=15.2B(),15.1E=15.2i):15.1p=15.1E=15.1D=15.2i=0,15},m.bb=18(t,e){1a 15.1V(t,15.3F(1g,e,!0,t))},m.85=m.aU=18(t,e,i,r){1a 15.1V(t,e||0,i,r)},m.b6=18(t,e,i,r){1a 15.1V(t,15.3F(1g,e,!0,t),i,r)},m.87=18(t,e){1a 15.2U[t]=15.3F(e),15},m.b3=18(t,e,r,s){1b n=i.4v(0,c,["{5v}",e,r,s],15);1a n.1y="5B",15.1V(n,t)},m.8g=18(t){1a 4d 15.2U[t],15},m.b2=18(t){1a 1g!=15.2U[t]?15.2U[t]:-1},m.3F=18(e,i,r,s){1b n;1c(s 2p t&&s.26===15)15.61(s);1o 1c(s&&(s 2p 42||s.24&&l(s)))1d(n=s.1f;--n>-1;)s[n]2p t&&s[n].26===15&&15.61(s[n]);1c("1O"==1k i)1a 15.3F(i,r&&"2E"==1k e&&1g==15.2U[i]?e-15.2B():0,r);1c(i=i||0,"1O"!=1k e||!76(e)&&1g==15.2U[e])1g==e&&(e=15.2B());1o{1c(n=e.1m("="),-1===n)1a 1g==15.2U[e]?r?15.2U[e]=15.2B()+i:i:15.2U[e]+i;i=3l(e.1z(n-1)+"1",10)*1P(e.1u(n+1)),e=n>1?15.3F(e.1u(0,n-1),0,r):15.2B()}1a 1P(e)+i},m.41=18(t,e){1a 15.2R("2E"==1k t?t:15.3F(t),e!==!1)},m.b4=18(){1a 15.2W(!0)},m.b9=18(t,e){1a 15.7P(t,e)},m.b7=18(t,e){1a 15.7f(t,e)},m.1G=18(t,e,i){15.1K&&15.1H(!0,!1);1b r,n,a,o,l,f=15.2z?15.27():15.2i,p=15.1p,19=15.1l,c=15.1C,d=15.1F;1c(t>=f)15.1E=15.1p=f,15.2F||15.7c()||(n=!0,o="4E",l=!!15.1r.3N,0===15.1D&&(0===t||0>15.1B||15.1B===s)&&15.1B!==t&&15.28&&(l=!0,15.1B>s&&(o="3Z"))),15.1B=15.1D||!e||t||15.1B===t?t:s,t=f+1e-4;1o 1c(1e-7>t)1c(15.1E=15.1p=0,(0!==p||0===15.1D&&15.1B!==s&&(15.1B>0||0>t&&15.1B>=0))&&(o="3Z",n=15.2F),0>t)15.2l=!1,15.1r.3N&&15.2F?(l=n=!0,o="3Z"):15.1B>=0&&15.28&&(l=!0),15.1B=t;1o{1c(15.1B=15.1D||!e||t||15.1B===t?t:s,0===t&&n)1d(r=15.28;r&&0===r.1l;)r.1D||(n=!1),r=r.1h;t=0,15.2u||(l=!0)}1o 15.1E=15.1p=15.1B=t;1c(15.1p!==p&&15.28||i||l){1c(15.2u||(15.2u=!0),15.2l||!15.1F&&15.1p!==p&&t>0&&(15.2l=!0),0===p&&15.1w.5h&&0!==15.1p&&(e||15.4j("5h")),15.1p>=p)1d(r=15.28;r&&(a=r.1h,!15.1F||d);)(r.2l||r.1l<=15.1p&&!r.1F&&!r.1K)&&(r.2F?r.1G((r.2z?r.27():r.2i)-(t-r.1l)*r.1C,e,i):r.1G((t-r.1l)*r.1C,e,i)),r=a;1o 1d(r=15.3i;r&&(a=r.1n,!15.1F||d);)(r.2l||p>=r.1l&&!r.1F&&!r.1K)&&(r.2F?r.1G((r.2z?r.27():r.2i)-(t-r.1l)*r.1C,e,i):r.1G((t-r.1l)*r.1C,e,i)),r=a;15.3O&&(e||(h.1f&&u(),15.4j("4B"))),o&&(15.1K||(19===15.1l||c!==15.1C)&&(0===15.1p||f>=15.27())&&(n&&(h.1f&&u(),15.1r.3N&&15.1H(!1,!1),15.2l=!1),!e&&15.1w[o]&&15.4j(o)))}},m.7c=18(){1d(1b t=15.28;t;){1c(t.1F||t 2p r&&t.7c())1a!0;t=t.1h}1a!1},m.5X=18(t,e,r,s){s=s||-5K;1d(1b n=[],a=15.28,o=0;a;)s>a.1l||(a 2p i?e!==!1&&(n[o++]=a):(r!==!1&&(n[o++]=a),t!==!1&&(n=n.4O(a.5X(!0,e,r)),o=n.1f))),a=a.1h;1a n},m.4C=18(t,e){1b r,s,n=15.1K,a=[],o=0;1d(n&&15.1H(!0,!0),r=i.4C(t),s=r.1f;--s>-1;)(r[s].26===15||e&&15.8J(r[s]))&&(a[o++]=r[s]);1a n&&15.1H(!1,!0),a},m.aT=18(){1a 15.4W},m.8J=18(t){1d(1b e=t.26;e;){1c(e===15)1a!0;e=e.26}1a!1},m.8T=18(t,e,i){i=i||0;1d(1b r,s=15.28,n=15.2U;s;)s.1l>=i&&(s.1l+=t),s=s.1h;1c(e)1d(r 1x n)n[r]>=i&&(n[r]+=t);1a 15.3m(!0)},m.2s=18(t,e){1c(!t&&!e)1a 15.1H(!1,!1);1d(1b i=e?15.4C(e):15.5X(!0,!0,!1),r=i.1f,s=!1;--r>-1;)i[r].2s(t,e)&&(s=!0);1a s},m.bu=18(t){1b e=15.5X(!1,!0,!0),i=e.1f;1d(15.1p=15.1E=0;--i>-1;)e[i].1H(!1,!1);1a t!==!1&&(15.2U={}),15.3m(!0)},m.4H=18(){1d(1b e=15.28;e;)e.4H(),e=e.1h;1a t.1A.4H.2h(15)},m.1H=18(t,i){1c(t===15.1K)1d(1b r=15.28;r;)r.1H(t,!0),r=r.1h;1a e.1A.1H.2h(15,t,i)},m.2R=18(){15.58=!0;1b e=t.1A.2R.4i(15,2n);1a 15.58=!1,e},m.2B=18(t){1a 2n.1f?(0!==15.2B()&&0!==t&&15.6M(15.1D/t),15):(15.2z&&15.27(),15.1D)},m.27=18(t){1c(!2n.1f){1c(15.2z){1d(1b e,i,r=0,s=15.3i,n=ad;s;)e=s.1n,s.2z&&s.27(),s.1l>n&&15.4V&&!s.1F?15.1V(s,s.1l-s.2K):n=s.1l,0>s.1l&&!s.1F&&(r-=s.1l,15.1r.2r&&(15.1l+=s.1l/15.1C),15.8T(-s.1l,!1,-5K),n=0),i=s.1l+s.2i/s.1C,i>r&&(r=i),s=e;15.1D=15.2i=r,15.2z=!1}1a 15.2i}1a 0!==15.27()&&0!==t&&15.6M(15.2i/t),15},m.2W=18(e){1c(!e)1d(1b i=15.28,r=15.1p;i;)i.1l===r&&"5B"===i.1y&&(i.1B=0),i=i.1h;1a t.1A.2W.4i(15,2n)},m.ai=18(){1d(1b e=15.1r;e.1r;)e=e.1r;1a e===t.8n},m.4g=18(){1a 15.1F?15.1E:(15.1r.4g()-15.1l)*15.1C},r},!0)}),1J.3J&&1J.3t.4K()(),18(t){"4I 4J";1b e=18(){1a(1J.5r||1J)[t]};"18"==1k 3H&&3H.6R?3H(["3A"],e):"37"!=1k 2k&&2k.3n&&(8i("./3A.6V"),2k.3n=e())}("8s");1b 1J="37"!=1k 2k&&2k.3n&&"37"!=1k 3G?3G:15||43;(1J.3t||(1J.3t=[])).24(18(){"4I 4J";1J.3J("2A.8x",["2A.8A"],18(t){1b e,i,r,s=1J.5r||1J,n=s.5p.5o,a=2*1i.4S,o=1i.4S/2,l=n.8z,h=18(e,i){1b r=l("2A."+e,18(){},!0),s=r.1A=1j t;1a s.2V=r,s.2C=i,r},u=t.8y||18(){},f=18(t,e,i,r){1b s=l("2A."+t,{6U:1j e,5G:1j i,5A:1j r},!0);1a u(s,t),s},p=18(t,e,i){15.t=t,15.v=e,i&&(15.5E=i,i.5D=15,15.c=i.v-e,15.8k=i.t-t)},19=18(e,i){1b r=l("2A."+e,18(t){15.23=t||0===t?t:1.aG,15.2o=1.a7*15.23},!0),s=r.1A=1j t;1a s.2V=r,s.2C=i,s.3y=18(t){1a 1j r(t)},r},c=f("8x",19("bn",18(t){1a(t-=1)*t*((15.23+1)*t+15.23)+1}),19("bC",18(t){1a t*t*((15.23+1)*t-15.23)}),19("ek",18(t){1a 1>(t*=2)?.5*t*t*((15.2o+1)*t-15.2o):.5*((t-=2)*t*((15.2o+1)*t+15.2o)+2)})),d=l("2A.6P",18(t,e,i){e=e||0===e?e:.7,1g==t?t=.7:t>1&&(t=1),15.8w=1!==t?e:0,15.23=(1-t)/2,15.2o=t,15.3K=15.23+15.2o,15.3T=i===!0},!0),m=d.1A=1j t;1a m.2V=d,m.2C=18(t){1b e=t+(.5-t)*15.8w;1a 15.23>t?15.3T?1-(t=1-t/15.23)*t:e-(t=1-t/15.23)*t*t*t*e:t>15.3K?15.3T?1-(t=(t-15.3K)/15.23)*t:e+(t-e)*(t=(t-15.3K)/15.23)*t*t*t:15.3T?1:e},d.4e=1j d(.7,.7),m.3y=d.3y=18(t,e,i){1a 1j d(t,e,i)},e=l("2A.8W",18(t){t=t||1,15.23=1/t,15.2o=t+1},!0),m=e.1A=1j t,m.2V=e,m.2C=18(t){1a 0>t?t=0:t>=1&&(t=.dX),(15.2o*t>>0)*15.23},m.3y=e.3y=18(t){1a 1j e(t)},i=l("2A.8X",18(e){e=e||{};1d(1b i,r,s,n,a,o,l=e.dp||"3E",h=[],u=0,f=0|(e.do||20),19=f,c=e.dz!==!1,d=e.dA===!0,m=e.8C 2p t?e.8C:1g,g="2E"==1k e.8B?.4*e.8B:.4;--19>-1;)i=c?1i.8t():1/f*19,r=m?m.2C(i):i,"3E"===l?s=g:"dE"===l?(n=1-i,s=n*n*g):"1x"===l?s=i*i*g:.5>i?(n=2*i,s=.5*n*n*g):(n=2*(1-i),s=.5*n*n*g),c?r+=1i.8t()*s-.5*s:19%2?r+=.5*s:r-=.5*s,d&&(r>1?r=1:0>r&&(r=0)),h[u++]={x:i,y:r};1d(h.dF(18(t,e){1a t.x-e.x}),o=1j p(1,1,1g),19=f;--19>-1;)a=h[19],o=1j p(a.x,a.y,o);15.1n=1j p(0,0,0!==o.t?o:o.5E)},!0),m=i.1A=1j t,m.2V=i,m.2C=18(t){1b e=15.1n;1c(t>e.t){1d(;e.5E&&t>=e.t;)e=e.5E;e=e.5D}1o 1d(;e.5D&&e.t>=t;)e=e.5D;1a 15.1n=e,e.v+(t-e.t)/e.8k*e.c},m.3y=18(t){1a 1j i(t)},i.4e=1j i,f("dG",h("dH",18(t){1a 1/2.75>t?7.2X*t*t:2/2.75>t?7.2X*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.2X*(t-=2.25/2.75)*t+.6W:7.2X*(t-=2.6Y/2.75)*t+.6X}),h("dI",18(t){1a 1/2.75>(t=1-t)?1-7.2X*t*t:2/2.75>t?1-(7.2X*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1-(7.2X*(t-=2.25/2.75)*t+.6W):1-(7.2X*(t-=2.6Y/2.75)*t+.6X)}),h("dJ",18(t){1b e=.5>t;1a t=e?1-2*t:2*t-1,t=1/2.75>t?7.2X*t*t:2/2.75>t?7.2X*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.2X*(t-=2.25/2.75)*t+.6W:7.2X*(t-=2.6Y/2.75)*t+.6X,e?.5*(1-t):.5*t+.5})),f("dB",h("dC",18(t){1a 1i.3f(1-(t-=1)*t)}),h("dD",18(t){1a-(1i.3f(1-t*t)-1)}),h("dK",18(t){1a 1>(t*=2)?-.5*(1i.3f(1-t*t)-1):.5*(1i.3f(1-(t-=2)*t)+1)})),r=18(e,i,r){1b s=l("2A."+e,18(t,e){15.23=t>=1?t:1,15.2o=(e||r)/(1>t?t:1),15.3K=15.2o/a*(1i.dL(1/15.23)||0),15.2o=a/15.2o},!0),n=s.1A=1j t;1a n.2V=s,n.2C=i,n.3y=18(t,e){1a 1j s(t,e)},s},f("dT",r("dU",18(t){1a 15.23*1i.3L(2,-10*t)*1i.2t((t-15.3K)*15.2o)+1},.3),r("dV",18(t){1a-(15.23*1i.3L(2,10*(t-=1))*1i.2t((t-15.3K)*15.2o))},.3),r("dW",18(t){1a 1>(t*=2)?-.5*15.23*1i.3L(2,10*(t-=1))*1i.2t((t-15.3K)*15.2o):.5*15.23*1i.3L(2,-10*(t-=1))*1i.2t((t-15.3K)*15.2o)+1},.45)),f("dS",h("dR",18(t){1a 1-1i.3L(2,-10*t)}),h("dN",18(t){1a 1i.3L(2,10*(t-1))-.6w}),h("dM",18(t){1a 1>(t*=2)?.5*1i.3L(2,10*(t-1)):.5*(2-1i.3L(2,-10*(t-1)))})),f("dO",h("dP",18(t){1a 1i.2t(t*o)}),h("dQ",18(t){1a-1i.2S(t*o)+1}),h("dy",18(t){1a-.5*(1i.2S(1i.4S*t)-1)})),l("2A.dx",{dg:18(e){1a t.8Y[e]}},!0),u(s.6P,"6P","4e,"),u(i,"8X","4e,"),u(e,"8W","4e,"),c},!0)}),1J.3J&&1J.3t.4K()();1b 1J="37"!=1k 2k&&2k.3n&&"37"!=1k 3G?3G:15||43;(1J.3t||(1J.3t=[])).24(18(){"4I 4J";1J.3J("5q.9L",["5q.8O","3A"],18(t,e){1b i,r,s,n,a=18(){t.2h(15,"57"),15.2P.1f=0,15.1Y=a.1A.1Y},o=1J.3J.70,l={},h=a.1A=1j t("57");h.2V=a,a.4M="1.17.0",a.49=2,a.6H=0,a.8G="di",a.9b=!0,h="2j",a.79={4T:h,8e:h,8d:h,51:h,2D:h,3j:h,dj:h,7q:h,7H:h,3a:h,df:""};1b u,f,p,19,c,d,m=/(?:\\d|\\-\\d|\\.\\d|\\-\\.\\d)+/g,g=/(?:\\d|\\-\\d|\\.\\d|\\-\\.\\d|\\+=\\d|\\-=\\d|\\+=.\\d|\\-=\\.\\d)+/g,v=/(?:\\+=|\\-=|\\-|\\b)[\\d\\-\\.]+[a-dd-d9-9]*(?:%|\\b)/3Q,x=/(?![+-]?\\d*\\.?\\d+|[+-]|e[+-]\\d+)[^0-9]/g,y=/(?:\\d|\\-|\\+|=|#|\\.)*/g,T=/2a *= *([^)]*)/i,w=/2a:([^;]*)/i,b=/3U\\(2a *=.+?\\)/i,P=/^(6e|6r)/,O=/([A-Z])/g,S=/-([a-z])/3Q,k=/(^(?:8F\\(\\"|8F\\())|(?:(\\"\\))$|\\)$)/3Q,A=18(t,e){1a e.5Q()},C=/(?:6K|86|8f)/i,R=/(9t|9s|9r|9q)=[\\d\\-\\.e]+/3Q,M=/9A\\:6z\\.6B\\.6A\\(.+?\\)/i,D=/,(?=[^\\)]*(?:\\(|$))/3Q,X=1i.4S/3D,z=3D/1i.4S,F={},I=52,N=18(t){1a I.5I?I.5I("9m://9l.9k.9d/d8/da",t):I.db(t)},E=N("dc"),L=N("dk"),Y=a.5f={dl:l},B=dt.du,j=18(){1b t=B.1m("94"),e=N("a");1a p=-1!==B.1m("dv")&&-1===B.1m("dw")&&(-1===t||1P(B.1u(t+8,1))>3),c=p&&6>1P(B.1u(B.1m("ds/")+8,1)),19=-1!==B.1m("dr"),(/dn ([0-9]{1,}[\\.0-9]{0,})/.7S(B)||/dm\\/.*dY:([0-9]{1,}[\\.0-9]{0,})/.7S(B))&&(d=1q(4D.$1)),e?(e.1v.3B="4T:dq;2a:.55;",/^0.55/.35(e.1v.2a)):!1}(),V=18(t){1a T.35("1O"==1k t?t:(t.3e?t.3e.2x:t.1v.2x)||"")?1q(4D.$1)/1M:1},U=18(t){43.7d&&7d.7Q(t)},q="",W="",Z=18(t,e){e=e||E;1b i,r,s=e.1v;1c(2y 0!==s[t])1a t;1d(t=t.1z(0).5Q()+t.1u(1),i=["O","ev","6a","eu","ej"],r=5;--r>-1&&2y 0===s[i[r]+t];);1a r>=0?(W=3===r?"6a":i[r],q="-"+W.6i()+"-",W+t):1g},G=I.7N?I.7N.e5:18(){},Q=a.e3=18(t,e,i,r,s){1b n;1a j||"2a"!==e?(!r&&t.1v[e]?n=t.1v[e]:(i=i||G(t))?n=i[e]||i.4o(e)||i.4o(e.1N(O,"-$1").6i()):t.3e&&(n=t.3e[e]),1g==s||n&&"3E"!==n&&"2m"!==n&&"2m 2m"!==n?n:s):V(t)},$=Y.e1=18(t,i,r,s,n){1c("2j"===s||!s)1a r;1c("2m"===s||!r)1a 0;1b o,l,h,u=C.35(i),f=t,p=E.1v,19=0>r;1c(19&&(r=-r),"%"===s&&-1!==i.1m("4w"))o=r/1M*(u?t.ef:t.eb);1o{1c(p.3B="4w:0 6k 83;4z:"+Q(t,"4z")+";ei-3j:0;","%"!==s&&f.65)p[u?"92":"6C"]=r+s;1o{1c(f=t.5J||I.7D,l=f.71,h=e.78.3C,l&&u&&l.3q===h)1a l.2D*r/1M;p[u?"2D":"3j"]=r+s}f.65(E),o=1q(E[u?"4X":"4Y"]),f.7F(E),u&&"%"===s&&a.ea!==!1&&(l=f.71=f.71||{},l.3q=h,l.2D=1M*(o/r)),0!==o||n||(o=$(t,i,r,s,!0))}1a 19?-o:o},H=Y.e9=18(t,e,i){1c("7J"!==Q(t,"4z",i))1a 0;1b r="51"===e?"6K":"8a",s=Q(t,"7H"+r,i);1a t["ec"+r]-($(t,e,1q(s),s.1N(y,""))||0)},K=18(t,e){1b i,r,s,n={};1c(e=e||G(t,1g))1c(i=e.1f)1d(;--i>-1;)s=e[i],(-1===s.1m("-2Q")||6v===s)&&(n[s.1N(S,A)]=e.4o(s));1o 1d(i 1x e)(-1===i.1m("9j")||be===i)&&(n[i]=e[i]);1o 1c(e=t.3e||t.1v)1d(i 1x e)"1O"==1k i&&2y 0===n[i]&&(n[i.1N(S,A)]=e[i]);1a j||(n.2a=V(t)),r=4N(t,e,!1),n.1W=r.1W,n.21=r.21,n.2q=r.2q,n.2G=r.2G,n.x=r.x,n.y=r.y,34&&(n.z=r.z,n.22=r.22,n.29=r.29,n.36=r.36),n.88&&4d n.88,n},J=18(t,e,i,r,s){1b n,a,o,l={},h=t.1v;1d(a 1x i)"3B"!==a&&"1f"!==a&&76(a)&&(e[a]!==(n=i[a])||s&&s[a])&&-1===a.1m("ed")&&("2E"==1k n||"1O"==1k n)&&(l[a]="2m"!==n||"51"!==a&&"4T"!==a?""!==n&&"2m"!==n&&"3E"!==n||"1O"!=1k e[a]||""===e[a].1N(x,"")?n:0:H(t,a),2y 0!==h[a]&&(o=1j 62(h,a,h[a],o)));1c(r)1d(a 1x r)"3M"!==a&&(l[a]=r[a]);1a{5O:l,4R:o}},8b={2D:["6K","86"],3j:["8a","eh"]},ee=["9p","9f","9X","98"],8R=18(t,e,i){1b r=1q("2D"===e?t.4X:t.4Y),s=8b[e],n=s.1f;1d(i=i||G(t,1g);--n>-1;)r-=1q(Q(t,"7q"+s[n],i,!0))||0,r-=1q(Q(t,"4w"+s[n]+"8f",i,!0))||0;1a r},4r=18(t,e){(1g==t||""===t||"2m"===t||"2m 2m"===t)&&(t="0 0");1b i=t.1t(" "),r=-1!==t.1m("51")?"0%":-1!==t.1m("8e")?"1M%":i[0],s=-1!==t.1m("4T")?"0%":-1!==t.1m("8d")?"1M%":i[1];1a 1g==s?s="77"===r?"50%":"0":"77"===s&&(s="50%"),("77"===r||76(1q(r))&&-1===(r+"").1m("="))&&(r="50%"),t=r+" "+s+(i.1f>2?" "+i[2]:""),e&&(e.9u=-1!==r.1m("%"),e.9v=-1!==s.1m("%"),e.eg="="===r.1z(1),e.e8="="===s.1z(1),e.63=1q(r.1N(x,"")),e.6y=1q(s.1N(x,"")),e.v=t),e||t},6u=18(t,e){1a"1O"==1k t&&"="===t.1z(1)?3l(t.1z(0)+"1",10)*1q(t.1u(2)):1q(t)-1q(e)},2H=18(t,e){1a 1g==t?e:"1O"==1k t&&"="===t.1z(1)?3l(t.1z(0)+"1",10)*1q(t.1u(2))+e:1q(t)},ae=18(t,e,i,r){1b s,n,a,o,l,h=1e-6;1a 1g==t?o=e:"2E"==1k t?o=t:(s=6m,n=t.1t("19"),l="="===t.1z(1),a=(l?3l(t.1z(0)+"1",10)*1q(n[0].1u(2)):1q(n[0]))*(-1===t.1m("e7")?1:z)-(l?0:e),n.1f&&(r&&(r[i]=e+a),-1!==t.1m("e0")&&(a%=s,a!==a%(s/2)&&(a=0>a?a+s:a-s)),-1!==t.1m("dZ")&&0>a?a=(a+5K*s)%s-(0|a/s)*s:-1!==t.1m("e2")&&a>0&&(a=(a-5K*s)%s-(0|a/s)*s)),o=e+a),h>o&&o>-h&&(o=0),o},44={e6:[0,1R,1R],e4:[0,1R,0],el:[5Y,5Y,5Y],9W:[0,0,0],et:[2Y,0,0],ew:[0,2Y,2Y],er:[0,0,1R],es:[0,0,2Y],en:[1R,1R,1R],eo:[1R,0,1R],eq:[2Y,2Y,0],ep:[1R,1R,0],dh:[1R,d6,0],c6:[2Y,2Y,2Y],c7:[2Y,0,2Y],c8:[0,2Y,0],83:[1R,0,0],c9:[1R,5Y,c5],c4:[0,1R,1R],4L:[1R,1R,1R,0]},5H=18(t,e,i){1a t=0>t?t+1:t>1?t-1:t,0|1R*(1>6*t?e+6*(i-e)*t:.5>t?i:2>3*t?e+6*(i-e)*(2/3-t):e)+.5},6d=a.c0=18(t){1b e,i,r,s,n,a;1a t&&""!==t?"2E"==1k t?[t>>16,1R&t>>8,1R&t]:(","===t.1z(t.1f-1)&&(t=t.1u(0,t.1f-1)),44[t]?44[t]:"#"===t.1z(0)?(4===t.1f&&(e=t.1z(1),i=t.1z(2),r=t.1z(3),t="#"+e+e+i+i+r+r),t=3l(t.1u(1),16),[t>>16,1R&t>>8,1R&t]):"6r"===t.1u(0,3)?(t=t.2O(m),s=1P(t[0])%6m/6m,n=1P(t[1])/1M,a=1P(t[2])/1M,i=.5>=a?a*(n+1):a+n-a*n,e=2*a-i,t.1f>3&&(t[3]=1P(t[3])),t[0]=5H(s+1/3,e,i),t[1]=5H(s,e,i),t[2]=5H(s-1/3,e,i),t):(t=t.2O(m)||44.4L,t[0]=1P(t[0]),t[1]=1P(t[1]),t[2]=1P(t[2]),t.1f>3&&(t[3]=1P(t[3])),t)):44.9W},3W="(?:\\\\b(?:(?:6e|6Z|6r|c1)\\\\(.+?\\\\))|\\\\B#.+?\\\\b";1d(h 1x 44)3W+="|"+h+"\\\\b";3W=4D(3W+")","3Q");1b 7k=18(t,e,i,r){1c(1g==t)1a 18(t){1a t};1b s,n=e?(t.2O(3W)||[""])[0]:"",a=t.1t(n).1I("").2O(v)||[],o=t.1u(0,t.1m(a[0])),l=")"===t.1z(t.1f-1)?")":"",h=-1!==t.1m(" ")?" ":",",u=a.1f,f=u>0?a[0].1N(m,""):"";1a u?s=e?18(t){1b e,p,19,c;1c("2E"==1k t)t+=f;1o 1c(r&&D.35(t)){1d(c=t.1N(D,"|").1t("|"),19=0;c.1f>19;19++)c[19]=s(c[19]);1a c.1I(",")}1c(e=(t.2O(3W)||[n])[0],p=t.1t(e).1I("").2O(v)||[],19=p.1f,u>19--)1d(;u>++19;)p[19]=i?p[0|(19-1)/2]:a[19];1a o+p.1I(h)+h+e+l+(-1!==t.1m("7I")?" 7I":"")}:18(t){1b e,n,p;1c("2E"==1k t)t+=f;1o 1c(r&&D.35(t)){1d(n=t.1N(D,"|").1t("|"),p=0;n.1f>p;p++)n[p]=s(n[p]);1a n.1I(",")}1c(e=t.2O(v)||[],p=e.1f,u>p--)1d(;u>++p;)e[p]=i?e[0|(p-1)/2]:a[p];1a o+e.1I(h)+l}:18(t){1a t}},68=18(t){1a t=t.1t(","),18(e,i,r,s,n,a,o){1b l,h=(i+"").1t(" ");1d(o={},l=0;4>l;l++)o[t[l]]=h[l]=h[l]||h[(l-1)/2>>0];1a s.31(e,o,n,a)}},62=(Y.c2=18(t){15.2L.1Y(t);1d(1b e,i,r,s,n=15.1y,a=n.9T,o=n.4R,l=1e-6;o;)e=a[o.v],o.r?e=1i.3P(e):l>e&&e>-l&&(e=0),o.t[o.p]=e,o=o.1h;1c(n.9S&&(n.9S.1W=a.1W),1===t)1d(o=n.4R;o;){1c(i=o.t,i.2f){1c(1===i.2f){1d(s=i.1U+i.s+i.4h,r=1;i.l>r;r++)s+=i["3r"+r]+i["38"+(r+1)];i.e=s}}1o i.e=i.s+i.1U;o=o.1h}},18(t,e,i,r,s){15.t=t,15.p=e,15.v=i,15.r=s,r&&(r.1n=15,15.1h=r)}),ce=(Y.c3=18(t,e,i,r,s,n){1b a,o,l,h,u,f=r,p={},19={},c=i.3I,d=F;1d(i.3I=1g,F=e,r=u=i.31(t,e,r,s),F=d,n&&(i.3I=c,f&&(f.1n=1g,f.1n&&(f.1n.1h=1g)));r&&r!==f;){1c(1>=r.2f&&(o=r.p,19[o]=r.s+r.c,p[o]=r.s,n||(h=1j 62(r,"s",o,h,r.r),r.c=0),1===r.2f))1d(a=r.l;--a>0;)l="3r"+a,o=r.p+"19"+l,19[o]=r.1y[l],p[o]=r[l],n||(h=1j 62(r,l,o,h,r.5P[l]));r=r.1h}1a{9T:p,ca:19,4R:h,cb:u}},Y.cj=18(t,e,r,s,a,o,l,h,u,f,p){15.t=t,15.p=e,15.s=r,15.c=s,15.n=l||e,t 2p ce||n.24(15.n),15.r=h,15.2f=o||0,u&&(15.2w=u,i=!0),15.b=2y 0===f?r:f,15.e=2y 0===p?r+s:p,a&&(15.1h=a,a.1n=15)}),de=18(t,e,i,r,s,n){1b a=1j ce(t,e,i,r-i,s,-1,n);1a a.b=i,a.e=a.1U=r,a},5l=a.4u=18(t,e,i,r,s,n,a,o,l,h){i=i||n||"",a=1j ce(t,e,0,0,a,h?2:1,1g,!1,o,i,r),r+="";1b f,p,19,c,d,v,x,y,T,w,b,O,S=i.1t(", ").1I(",").1t(" "),k=r.1t(", ").1I(",").1t(" "),A=S.1f,C=u!==!1;1d((-1!==r.1m(",")||-1!==i.1m(","))&&(S=S.1I(" ").1N(D,", ").1t(" "),k=k.1I(" ").1N(D,", ").1t(" "),A=S.1f),A!==k.1f&&(S=(n||"").1t(" "),A=S.1f),a.2L=l,a.1Y=h,f=0;A>f;f++)1c(c=S[f],d=k[f],y=1q(c),y||0===y)a.4f("",y,6u(d,y),d.1N(g,""),C&&-1!==d.1m("2j"),!0);1o 1c(s&&("#"===c.1z(0)||44[c]||P.35(c)))O=","===d.1z(d.1f-1)?"),":")",c=6d(c),d=6d(d),T=c.1f+d.1f>6,T&&!j&&0===d[3]?(a["38"+a.l]+=a.l?" 4L":"4L",a.e=a.e.1t(k[f]).1I("4L")):(j||(T=!1),a.4f(T?"6Z(":"6e(",c[0],d[0]-c[0],",",!0,!0).4f("",c[1],d[1]-c[1],",",!0).4f("",c[2],d[2]-c[2],T?",":O,!0),T&&(c=4>c.1f?1:c[3],a.4f("",c,(4>d.1f?1:d[3])-c,O,!1)));1o 1c(v=c.2O(m)){1c(x=d.2O(g),!x||x.1f!==v.1f)1a a;1d(19=0,p=0;v.1f>p;p++)b=v[p],w=c.1m(b,19),a.4f(c.1u(19,w-19),1P(b),6u(x[p],b),"",C&&"2j"===c.1u(w+b.1f,2),0===p),19=w+b.1f;a["38"+a.l]+=c.1u(19)}1o a["38"+a.l]+=a.l?" "+c:c;1c(-1!==r.1m("=")&&a.1y){1d(O=a.1U+a.1y.s,f=1;a.l>f;f++)O+=a["38"+f]+a.1y["3r"+f];a.e=O+a["38"+f]}1a a.l||(a.2f=-1,a.1U=a.e),a.46||a},2b=9;1d(h=ce.1A,h.l=h.2w=0;--2b>0;)h["3r"+2b]=0,h["38"+2b]="";h.1U="",h.1h=h.1n=h.46=h.1y=h.2L=h.1Y=h.5P=1g,h.4f=18(t,e,i,r,s,n){1b a=15,o=a.l;1a a["38"+o]+=n&&o?" "+t:t||"",i||0===o||a.2L?(a.l++,a.2f=a.1Y?2:1,a["38"+a.l]=r||"",o>0?(a.1y["3r"+o]=e+i,a.5P["3r"+o]=s,a["3r"+o]=e,a.2L||(a.46=1j ce(a,"3r"+o,e,i,a.46||a,0,a.n,s,a.2w),a.46.1U=0),a):(a.1y={s:e+i},a.5P={},a.s=e,a.c=i,a.r=s,a)):(a["38"+o]+=e+(r||""),a)};1b 6o=18(t,e){e=e||{},15.p=e.39?Z(t)||t:t,l[t]=l[15.p]=15,15.3d=e.5w||7k(e.2I,e.4G,e.ck,e.4m),e.2g&&(15.31=e.2g),15.9e=e.4G,15.4m=e.4m,15.5z=e.5z,15.4t=e.2I,15.2w=e.6n||0},1Q=Y.cl=18(t,e,i){"4q"!=1k e&&(e={2g:i});1b r,s,n=t.1t(","),a=e.2I;1d(i=i||[a],r=0;n.1f>r;r++)e.39=0===r&&e.39,e.2I=i[r]||a,s=1j 6o(n[r],e)},89=18(t){1c(!l[t]){1b e=t.1z(0).5Q()+t.1u(1)+"9Q";1Q(t,{2g:18(t,i,r,s,n,a,h){1b u=o.5p.5o.5q[e];1a u?(u.ci(),l[r].31(t,i,r,s,n,a,h)):(U("ch: "+e+" 6V bB 9h cc."),n)}})}};h=6o.1A,h.4u=18(t,e,i,r,s,n){1b a,o,l,h,u,f,p=15.5z;1c(15.4m&&(D.35(i)||D.35(e)?(o=e.1N(D,"|").1t("|"),l=i.1N(D,"|").1t("|")):p&&(o=[e],l=[i])),l){1d(h=l.1f>o.1f?l.1f:o.1f,a=0;h>a;a++)e=o[a]=o[a]||15.4t,i=l[a]=l[a]||15.4t,p&&(u=e.1m(p),f=i.1m(p),u!==f&&(-1===f?o[a]=o[a].1t(p).1I(""):-1===u&&(o[a]+=" "+p)));e=o.1I(", "),i=l.1I(", ")}1a 5l(t,15.p,e,i,15.9e,15.4t,r,15.2w,s,n)},h.31=18(t,e,i,r,n,a){1a 15.4u(t.1v,15.3d(Q(t,15.p,s,!1,15.4t)),15.3d(e),n,a)},a.cd=18(t,e,i){1Q(t,{2g:18(t,r,s,n,a,o){1b l=1j ce(t,s,0,0,a,2,s,!1,i);1a l.2L=o,l.1Y=e(t,r,n.3u,s),l},6n:i})},a.9F=p||19;1b 3p,7u="2q,2G,36,x,y,z,21,2T,1W,22,29,3a,1T,1S".1t(","),be=Z("2Q"),6v=q+"2Q",4P=Z("5x"),34=1g!==Z("3a"),5a=Y.9j=18(){15.3a=1q(a.6H)||0,15.47=a.9n!==!1&&34?a.9n||"2m":!1},9a=43.cf,6F=18(t,e,i){1b r,s=I.5I("9m://9l.9k.9d/cg/2v",t),n=/([a-z])([A-Z])/g;1d(r 1x i)s.bZ(1g,r.1N(n,"$1-$2").6i(),i[r]);1a e.65(s),s},6E=I.bY,9E=18(){1b t,e,i,r=d||/94/i.35(B)&&!43.bI;1a I.5I&&!r&&(t=6F("2v",6E),e=6F("7G",t,{2D:1M,3j:50,x:1M}),i=e.9M().2D,e.1v[4P]="50% 50%",e.1v[be]="2q(0.5)",r=i===e.9M().2D&&!(19&&34),6E.7F(t)),r}(),7z=18(t,e,i,r,s){1b n,o,l,h,u,f,p,19,c,d,m,g,v,x,y=t.3w,T=6D(t,!0);y&&(v=y.2d,x=y.2c),(!r||2>(n=r.1t(" ")).1f)&&(p=t.4s(),e=4r(e).1t(" "),n=[(-1!==e[0].1m("%")?1q(e[0])/1M*p.2D:1q(e[0]))+p.x,(-1!==e[1].1m("%")?1q(e[1])/1M*p.3j:1q(e[1]))+p.y]),i.2d=h=1q(n[0]),i.2c=u=1q(n[1]),r&&T!==5L&&(f=T[0],p=T[1],19=T[2],c=T[3],d=T[4],m=T[5],g=f*c-p*19,o=h*(c/g)+u*(-19/g)+(19*m-c*d)/g,l=h*(-p/g)+u*(f/g)-(f*m-p*d)/g,h=i.2d=n[0]=o,u=i.2c=n[1]=l),y&&(s||s!==!1&&a.9b!==!1?(o=h-v,l=u-x,y.3h+=o*T[0]+l*T[2]-o,y.3s+=o*T[1]+l*T[3]-l):y.3h=y.3s=0),t.4b("1y-2v-6p",n.1I(" "))},6I=18(t){1a!!(9a&&"18"==1k t.4s&&t.99&&(!t.5J||t.5J.4s&&t.5J.99))},5L=[1,0,0,1,0,0],6D=18(t,e){1b i,r,s,n,a,o=t.3w||1j 5a,l=5V;1c(be?r=Q(t,6v,1g,!0):t.3e&&(r=t.3e.2x.2O(R),r=r&&4===r.1f?[r[0].1u(4),1P(r[2].1u(4)),1P(r[1].1u(4)),r[3].1u(4),o.x||0,o.y||0].1I(","):""),i=!r||"3E"===r||"3v(1, 0, 0, 1, 0, 0)"===r,(o.2v||t.4s&&6I(t))&&(i&&-1!==(t.1v[be]+"").1m("3v")&&(r=t.1v[be],i=0),s=t.4U("2Q"),i&&s&&(-1!==s.1m("3v")?(r=s,i=0):-1!==s.1m("5b")&&(r="3v(1,0,0,1,"+s.2O(/(?:\\-|\\b)[\\d\\-\\.e]+\\b/3Q).1I(",")+")",i=0))),i)1a 5L;1d(s=(r||"").2O(/(?:\\-|\\b)[\\d\\-\\.e]+\\b/3Q)||[],2b=s.1f;--2b>-1;)n=1P(s[2b]),s[2b]=(a=n-(n|=0))?(0|a*l+(0>a?-.5:.5))/l+n:n;1a e&&s.1f>6?[s[0],s[1],s[4],s[5],s[12],s[13]]:s},4N=Y.bJ=18(t,i,r,n){1c(t.3w&&r&&!n)1a t.3w;1b o,l,h,u,f,p,19=r?t.3w||1j 5a:1j 5a,c=0>19.2q,d=2e-5,m=5V,g=34?1q(Q(t,4P,i,!1,"0 0 0").1t(" ")[2])||19.32||0:0,v=1q(a.6H)||0;1c(19.2v=!(!t.4s||!6I(t)),19.2v&&(7z(t,Q(t,4P,s,!1,"50% 50%")+"",19,t.4U("1y-2v-6p")),3p=a.9F||9E),o=6D(t),o!==5L){1c(16===o.1f){1b x,y,T,w,b,P=o[0],O=o[1],S=o[2],k=o[3],A=o[4],C=o[5],R=o[6],M=o[7],D=o[8],X=o[9],F=o[10],I=o[12],N=o[13],E=o[14],L=o[11],Y=1i.5k(R,F);19.32&&(E=-19.32,I=D*E-o[12],N=X*E-o[13],E=F*E+19.32-o[14]),19.22=Y*z,Y&&(w=1i.2S(-Y),b=1i.2t(-Y),x=A*w+D*b,y=C*w+X*b,T=R*w+F*b,D=A*-b+D*w,X=C*-b+X*w,F=R*-b+F*w,L=M*-b+L*w,A=x,C=y,R=T),Y=1i.5k(D,F),19.29=Y*z,Y&&(w=1i.2S(-Y),b=1i.2t(-Y),x=P*w-D*b,y=O*w-X*b,T=S*w-F*b,X=O*b+X*w,F=S*b+F*w,L=k*b+L*w,P=x,O=y,S=T),Y=1i.5k(O,P),19.1W=Y*z,Y&&(w=1i.2S(-Y),b=1i.2t(-Y),P=P*w+A*b,y=O*w+C*b,C=O*-b+C*w,R=S*-b+R*w,O=y),19.22&&1i.5T(19.22)+1i.5T(19.1W)>bK.9&&(19.22=19.1W=0,19.29+=3D),19.2q=(0|1i.3f(P*P+O*O)*m+.5)/m,19.2G=(0|1i.3f(C*C+X*X)*m+.5)/m,19.36=(0|1i.3f(R*R+F*F)*m+.5)/m,19.21=0,19.3a=L?1/(0>L?-L:L):0,19.x=I,19.y=N,19.z=E,19.2v&&(19.x-=19.2d-(19.2d*P-19.2c*A),19.y-=19.2c-(19.2c*O-19.2d*C))}1o 1c(!(34&&!n&&o.1f&&19.x===o[4]&&19.y===o[5]&&(19.22||19.29)||2y 0!==19.x&&"3E"===Q(t,"6S",i))){1b B=o.1f>=6,j=B?o[0]:1,V=o[1]||0,U=o[2]||0,q=B?o[3]:1;19.x=o[4]||0,19.y=o[5]||0,h=1i.3f(j*j+V*V),u=1i.3f(q*q+U*U),f=j||V?1i.5k(V,j)*z:19.1W||0,p=U||q?1i.5k(U,q)*z+f:19.21||0,1i.5T(p)>90&&bL>1i.5T(p)&&(c?(h*=-1,p+=0>=f?3D:-3D,f+=0>=f?3D:-3D):(u*=-1,p+=0>=p?3D:-3D)),19.2q=h,19.2G=u,19.1W=f,19.21=p,34&&(19.22=19.29=19.z=0,19.3a=v,19.36=1),19.2v&&(19.x-=19.2d-(19.2d*j+19.2c*U),19.y-=19.2c-(19.2d*V+19.2c*q))}19.32=g;1d(l 1x 19)d>19[l]&&19[l]>-d&&(19[l]=0)}1a r&&(t.3w=19,19.2v&&(3p&&t.1v[be]?e.4v(.6w,18(){4Z(t.1v,be)}):!3p&&t.4U("2Q")&&e.4v(.6w,18(){t.5i("2Q")}))),19},8K=18(t){1b e,i,r=15.1y,s=-r.1W*X,n=s+r.21*X,a=5V,o=(0|1i.2S(s)*r.2q*a)/a,l=(0|1i.2t(s)*r.2q*a)/a,h=(0|1i.2t(n)*-r.2G*a)/a,u=(0|1i.2S(n)*r.2G*a)/a,f=15.t.1v,p=15.t.3e;1c(p){i=l,l=-h,h=-i,e=p.2x,f.2x="";1b 19,c,m=15.t.4X,g=15.t.4Y,v="7J"!==p.4z,x="9A:6z.6B.6A(9t="+o+", 9s="+l+", 9r="+h+", 9q="+u,w=r.x+m*r.1T/1M,b=r.y+g*r.1S/1M;1c(1g!=r.63&&(19=(r.9u?.5W*m*r.63:r.63)-m/2,c=(r.9v?.5W*g*r.6y:r.6y)-g/2,w+=19-(19*o+c*l),b+=c-(19*h+c*u)),v?(19=m/2,c=g/2,x+=", 9y="+(19-(19*o+c*l)+w)+", 9x="+(c-(19*h+c*u)+b)+")"):x+=", bH=\'2m bG\')",f.2x=-1!==e.1m("6z.6B.6A(")?e.1N(M,x):x+" "+e,(0===t||1===t)&&1===o&&0===l&&0===h&&1===u&&(v&&-1===x.1m("9y=0, 9x=0")||T.35(e)&&1M!==1q(4D.$1)||-1===e.1m("d7("&&e.1m("bD"))&&f.5i("2x")),!v){1b P,O,S,k=8>d?1:-1;1d(19=r.5U||0,c=r.66||0,r.5U=1i.3P((m-((0>o?-o:o)*m+(0>l?-l:l)*g))/2+w),r.66=1i.3P((g-((0>u?-u:u)*g+(0>h?-h:h)*m))/2+b),2b=0;4>2b;2b++)O=ee[2b],P=p[O],i=-1!==P.1m("2j")?1q(P):$(15.t,O,1q(P),P.1N(y,""))||0,S=i!==r[O]?2>2b?-r.5U:-r.66:2>2b?19-r.5U:c-r.66,f[O]=(r[O]=1i.3P(i-S*(0===2b||2===2b?1:k)))+"2j"}}},8N=Y.bE=Y.bF=18(t){1b e,i,r,s,n,a,o,l,h,u,f,p,c,d,m,g,v,x,y,T,w,b,P,O=15.1y,S=15.t.1v,k=O.1W,A=O.22,C=O.29,R=O.2q,M=O.2G,D=O.36,z=O.x,F=O.y,I=O.z,N=O.2v,E=O.3a,L=O.47;1c(!((1!==t&&0!==t||"2m"!==L||15.3V.1E!==15.3V.2i&&15.3V.1E)&&L||I||E||C||A)||3p&&N||!34)1a 2y(k||O.21||N?(k*=X,b=O.21*X,P=5V,e=1i.2S(k)*R,s=1i.2t(k)*R,i=1i.2t(k-b)*-M,n=1i.2S(k-b)*M,b&&"9z"===O.4x&&(v=1i.9B(b),v=1i.3f(1+v*v),i*=v,n*=v,O.2T&&(e*=v,s*=v)),N&&(z+=O.2d-(O.2d*e+O.2c*i)+O.3h,F+=O.2c-(O.2d*s+O.2c*n)+O.3s,3p&&(O.1T||O.1S)&&(d=15.t.4s(),z+=.5W*O.1T*d.2D,F+=.5W*O.1S*d.3j),d=1e-6,d>z&&z>-d&&(z=0),d>F&&F>-d&&(F=0)),y=(0|e*P)/P+","+(0|s*P)/P+","+(0|i*P)/P+","+(0|n*P)/P+","+z+","+F+")",N&&3p?15.t.4b("2Q","3v("+y):S[be]=(O.1T||O.1S?"5b("+O.1T+"%,"+O.1S+"%) 3v(":"3v(")+y):S[be]=(O.1T||O.1S?"5b("+O.1T+"%,"+O.1S+"%) 3v(":"3v(")+R+",0,0,"+M+","+z+","+F+")");1c(19&&(d=1e-4,d>R&&R>-d&&(R=D=2e-5),d>M&&M>-d&&(M=D=2e-5),!E||O.z||O.22||O.29||(E=0)),k||O.21)k*=X,m=e=1i.2S(k),g=s=1i.2t(k),O.21&&(k-=O.21*X,m=1i.2S(k),g=1i.2t(k),"9z"===O.4x&&(v=1i.9B(O.21*X),v=1i.3f(1+v*v),m*=v,g*=v,O.2T&&(e*=v,s*=v))),i=-g,n=m;1o{1c(!(C||A||1!==D||E||N))1a 2y(S[be]=(O.1T||O.1S?"5b("+O.1T+"%,"+O.1S+"%) 9I(":"9I(")+z+"2j,"+F+"2j,"+I+"2j)"+(1!==R||1!==M?" 5j("+R+","+M+")":""));e=n=1,i=s=0}h=1,r=a=o=l=u=f=0,p=E?-1/E:0,c=O.32,d=1e-6,T=",",w="0",k=C*X,k&&(m=1i.2S(k),g=1i.2t(k),o=-g,u=p*-g,r=e*g,a=s*g,h=m,p*=m,e*=m,s*=m),k=A*X,k&&(m=1i.2S(k),g=1i.2t(k),v=i*m+r*g,x=n*m+a*g,l=h*g,f=p*g,r=i*-g+r*m,a=n*-g+a*m,h*=m,p*=m,i=v,n=x),1!==D&&(r*=D,a*=D,h*=D,p*=D),1!==M&&(i*=M,n*=M,l*=M,f*=M),1!==R&&(e*=R,s*=R,o*=R,u*=R),(c||N)&&(c&&(z+=r*-c,F+=a*-c,I+=h*-c+c),N&&(z+=O.2d-(O.2d*e+O.2c*i)+O.3h,F+=O.2c-(O.2d*s+O.2c*n)+O.3s),d>z&&z>-d&&(z=w),d>F&&F>-d&&(F=w),d>I&&I>-d&&(I=0)),y=O.1T||O.1S?"5b("+O.1T+"%,"+O.1S+"%) 97(":"97(",y+=(d>e&&e>-d?w:e)+T+(d>s&&s>-d?w:s)+T+(d>o&&o>-d?w:o),y+=T+(d>u&&u>-d?w:u)+T+(d>i&&i>-d?w:i)+T+(d>n&&n>-d?w:n),A||C?(y+=T+(d>l&&l>-d?w:l)+T+(d>f&&f>-d?w:f)+T+(d>r&&r>-d?w:r),y+=T+(d>a&&a>-d?w:a)+T+(d>h&&h>-d?w:h)+T+(d>p&&p>-d?w:p)+T):y+=",0,0,0,0,1,0,",y+=z+T+F+T+I+T+(E?1+-I/E:1)+")",S[be]=y};h=5a.1A,h.x=h.y=h.z=h.21=h.2T=h.1W=h.22=h.29=h.32=h.1T=h.1S=h.3h=h.3s=0,h.2q=h.2G=h.36=1,1Q("2Q,5j,2q,2G,36,x,y,z,1W,22,29,7s,21,2T,7t,7v,7m,bM,5x,7w,7Y,7V,9R,47,4x,1T,1S,8S",{2g:18(t,e,i,r,n,o,l){1c(r.73===l)1a n;r.73=l;1b h,u,f,p,19,c,d,m,g,v=t.3w,x=r.3I=4N(t,s,!0,l.9R),y=t.1v,T=1e-6,w=7u.1f,b=l,P={},O="5x";1c("1O"==1k b.2Q&&be)f=E.1v,f[be]=b.2Q,f.6S="bN",f.4z="7J",I.7D.65(E),h=4N(E,1g,!1),I.7D.7F(E),1g!=b.1T&&(h.1T=2H(b.1T,x.1T)),1g!=b.1S&&(h.1S=2H(b.1S,x.1S));1o 1c("4q"==1k b){1c(h={2q:2H(1g!=b.2q?b.2q:b.5j,x.2q),2G:2H(1g!=b.2G?b.2G:b.5j,x.2G),36:2H(b.36,x.36),x:2H(b.x,x.x),y:2H(b.y,x.y),z:2H(b.z,x.z),1T:2H(b.1T,x.1T),1S:2H(b.1S,x.1S),3a:2H(b.7Y,x.3a)},d=b.7V,1g!=d)1c("4q"==1k d)1d(f 1x d)b[f]=d[f];1o b.1W=d;"1O"==1k b.x&&-1!==b.x.1m("%")&&(h.x=0,h.1T=2H(b.x,x.1T)),"1O"==1k b.y&&-1!==b.y.1m("%")&&(h.y=0,h.1S=2H(b.y,x.1S)),h.1W=ae("1W"1x b?b.1W:"7t"1x b?b.7t+"7p":"7s"1x b?b.7s:x.1W,x.1W,"1W",P),34&&(h.22=ae("22"1x b?b.22:"7v"1x b?b.7v+"7p":x.22||0,x.22,"22",P),h.29=ae("29"1x b?b.29:"7m"1x b?b.7m+"7p":x.29||0,x.29,"29",P)),h.21=1g==b.21?x.21:ae(b.21,x.21),h.2T=1g==b.2T?x.2T:ae(b.2T,x.2T),(u=h.2T-x.2T)&&(h.21+=u,h.1W+=u)}1d(34&&1g!=b.47&&(x.47=b.47,c=!0),x.4x=b.4x||x.4x||a.8G,19=x.47||x.z||x.22||x.29||h.z||h.22||h.29||h.3a,19||1g==b.5j||(h.36=1);--w>-1;)i=7u[w],p=h[i]-x[i],(p>T||-T>p||1g!=b[i]||1g!=F[i])&&(c=!0,n=1j ce(x,i,x[i],p,n),i 1x P&&(n.e=P[i]),n.1U=0,n.2L=o,r.2P.24(n.n));1a p=b.5x,x.2v&&(p||b.7w)&&(m=x.3h,g=x.3s,7z(t,4r(p),h,b.7w,b.8S),n=de(x,"2d",(v?x:h).2d,h.2d,n,O),n=de(x,"2c",(v?x:h).2c,h.2c,n,O),(m!==x.3h||g!==x.3s)&&(n=de(x,"3h",v?m:x.3h,x.3h,n,O),n=de(x,"3s",v?g:x.3s,x.3s,n,O)),p=3p?1g:"1L 1L"),(p||34&&19&&x.32)&&(be?(c=!0,i=4P,p=(p||Q(t,i,s,!1,"50% 50%"))+"",n=1j ce(y,i,0,0,n,-1,O),n.b=y[i],n.2L=o,34?(f=x.32,p=p.1t(" "),x.32=(p.1f>2&&(0===f||"1L"!==p[2])?1q(p[2]):f)||0,n.1U=n.e=p[0]+" "+(p[1]||"50%")+" 1L",n=1j ce(x,"32",0,0,n,-1,n.n),n.b=f,n.1U=n.e=x.32):n.1U=n.e=p):4r(p+"",x)),c&&(r.4k=x.2v&&3p||!19&&3!==15.4k?2:3),n},39:!0}),1Q("bU",{2I:"1L 1L 1L 1L #9w",39:!0,4G:!0,4m:!0,5z:"7I"}),1Q("bV",{2I:"1L",2g:18(t,e,i,n,a){e=15.3d(e);1b o,l,h,u,f,p,19,c,d,m,g,v,x,y,T,w,b=["bW","bX","bT","bS"],P=t.1v;1d(d=1q(t.4X),m=1q(t.4Y),o=e.1t(" "),l=0;b.1f>l;l++)15.p.1m("4w")&&(b[l]=Z(b[l])),f=u=Q(t,b[l],s,!1,"1L"),-1!==f.1m(" ")&&(u=f.1t(" "),f=u[0],u=u[1]),p=h=o[l],19=1q(f),v=f.1u((19+"").1f),x="="===p.1z(1),x?(c=3l(p.1z(0)+"1",10),p=p.1u(2),c*=1q(p),g=p.1u((c+"").1f-(0>c?1:0))||""):(c=1q(p),g=p.1u((c+"").1f)),""===g&&(g=r[i]||v),g!==v&&(y=$(t,"8o",19,v),T=$(t,"bO",19,v),"%"===g?(f=1M*(y/d)+"%",u=1M*(T/m)+"%"):"em"===g?(w=$(t,"8o",1,"em"),f=y/w+"em",u=T/w+"em"):(f=y+"2j",u=T+"2j"),x&&(p=1q(f)+c+g,h=1q(u)+c+g)),a=5l(P,b[l],f+" "+u,p+" "+h,!1,"1L",a);1a a},39:!0,5w:7k("1L 1L 1L 1L",!1,!0)}),1Q("bP",{2I:"0 0",2g:18(t,e,i,r,n,a){1b o,l,h,u,f,p,19="bQ-4z",c=s||G(t,1g),m=15.3d((c?d?c.4o(19+"-x")+" "+c.4o(19+"-y"):c.4o(19):t.3e.bR+" "+t.3e.cm)||"0 0"),g=15.3d(e);1c(-1!==m.1m("%")!=(-1!==g.1m("%"))&&(p=Q(t,"cn").1N(k,""),p&&"3E"!==p)){1d(o=m.1t(" "),l=g.1t(" "),L.4b("cR",p),h=2;--h>-1;)m=o[h],u=-1!==m.1m("%"),u!==(-1!==l[h].1m("%"))&&(f=0===h?t.4X-L.2D:t.4Y-L.3j,o[h]=u?1q(m)/1M*f+"2j":1M*(1q(m)/f)+"%");m=o.1I(" ")}1a 15.4u(t.1v,m,g,n,a)},5w:4r}),1Q("cS",{2I:"0 0",5w:4r}),1Q("3a",{2I:"1L",39:!0}),1Q("cT",{2I:"50% 50%",39:!0}),1Q("cU",{39:!0}),1Q("cQ",{39:!0}),1Q("cP",{39:!0}),1Q("7H",{2g:68("9X,9f,98,9p")}),1Q("7q",{2g:68("cL,cM,cN,cO")}),1Q("cV",{2I:"7G(1L,1L,1L,1L)",2g:18(t,e,i,r,n,a){1b o,l,h;1a 9>d?(l=t.3e,h=8>d?" ":",",o="7G("+l.cW+h+l.d3+h+l.d4+h+l.d5+")",e=15.3d(e).1t(",").1I(h)):(o=15.3d(Q(t,15.p,s,!1,15.4t)),e=15.3d(e)),15.4u(t.1v,o,e,n,a)}}),1Q("d2",{2I:"1L 1L 1L #9w",4G:!0,4m:!0}),1Q("7M,8D",{2g:18(t,e,i,r,s){1a s}}),1Q("4w",{2I:"1L 6k #6x",2g:18(t,e,i,r,n,a){1a 15.4u(t.1v,15.3d(Q(t,"6C",s,!1,"1L")+" "+Q(t,"d1",s,!1,"6k")+" "+Q(t,"cX",s,!1,"#6x")),15.3d(e),n,a)},4G:!0,5w:18(t){1b e=t.1t(" ");1a e[0]+" "+(e[1]||"6k")+" "+(t.2O(3W)||["#6x"])[0]}}),1Q("cY",{2g:68("6C,cZ,d0,92")}),1Q("cK,6J,9c",{2g:18(t,e,i,r,s){1b n=t.1v,a="6J"1x n?"6J":"9c";1a 1j ce(n,a,0,0,s,-1,i,!1,0,n[a],e)}});1b 9O=18(t){1b e,i=15.t,r=i.2x||Q(15.1y,"2x")||"",s=0|15.s+15.c*t;1M===s&&(-1===r.1m("cJ(")&&-1===r.1m("cu(")&&-1===r.1m("cv(")?(i.5i("2x"),e=!Q(15.1y,"2x")):(i.2x=r.1N(b,""),e=!0)),e||(15.3Y&&(i.2x=r=r||"3U(2a="+s+")"),-1===r.1m("cw")?0===s&&15.3Y||(i.2x=r+" 3U(2a="+s+")"):i.2x=r.1N(T,"2a="+s))};1Q("2a,3U,5F",{2I:"1",2g:18(t,e,i,r,n,a){1b o=1q(Q(t,"2a",s,!1,"1")),l=t.1v,h="5F"===i;1a"1O"==1k e&&"="===e.1z(1)&&(e=("-"===e.1z(0)?-1:1)*1q(e.1u(2))+o),h&&1===o&&"6c"===Q(t,"7r",s)&&0!==e&&(o=0),j?n=1j ce(l,"2a",o,e-o,n):(n=1j ce(l,"2a",1M*o,1M*(e-o),n),n.3Y=h?1:0,l.8L=1,n.2f=2,n.b="3U(2a="+n.s+")",n.e="3U(2a="+(n.s+n.c)+")",n.1y=t,n.2L=a,n.1Y=9O),h&&(n=1j ce(l,"7r",0,0,n,-1,1g,!1,0,0!==o?"6t":"6c",0===e?"6c":"6t"),n.1U="6t",r.2P.24(n.n),r.2P.24(i)),n}});1b 4Z=18(t,e){e&&(t.9N?(("6a"===e.1u(0,2)||"9U"===e.1u(0,6))&&(e="-"+e),t.9N(e.1N(O,"-$1").6i())):t.5i(e))},81=18(t){1c(15.t.54=15,1===t||0===t){15.t.4b("4l",0===t?15.b:15.e);1d(1b e=15.1y,i=15.t.1v;e;)e.v?i[e.p]=e.v:4Z(i,e.p),e=e.1h;1===t&&15.t.54===15&&(15.t.54=1g)}1o 15.t.4U("4l")!==15.e&&15.t.4b("4l",15.e)};1Q("3M",{2g:18(t,e,r,n,a,o,l){1b h,u,f,p,19,c=t.4U("4l")||"",d=t.1v.3B;1c(a=n.7E=1j ce(t,r,0,0,a,2),a.1Y=81,a.2w=-11,i=!0,a.b=c,u=K(t,s),f=t.54){1d(p={},19=f.1y;19;)p[19.p]=1,19=19.1h;f.1Y(1)}1a t.54=a,a.e="="!==e.1z(1)?e:c.1N(4D("\\\\s*\\\\b"+e.1u(2)+"\\\\b"),"")+("+"===e.1z(0)?" "+e.1u(2):""),t.4b("4l",a.e),h=J(t,u,K(t),l,p),t.4b("4l",c),a.1y=h.4R,t.1v.3B=d,a=a.46=n.31(t,h.5O,a,o)}});1b 7U=18(t){1c((1===t||0===t)&&15.1y.1E===15.1y.2i&&"82"!==15.1y.1y){1b e,i,r,s,n,a=15.t.1v,o=l.2Q.31;1c("4A"===15.e)a.3B="",s=!0;1o 1d(e=15.e.1t(" ").1I("").1t(","),r=e.1f;--r>-1;)i=e[r],l[i]&&(l[i].31===o?s=!0:i="5x"===i?4P:l[i].p),4Z(a,i);s&&(4Z(a,be),n=15.t.3w,n&&(n.2v&&15.t.5i("1y-2v-6p"),4d 15.t.3w))}};1d(1Q("cx",{2g:18(t,e,r,s,n){1a n=1j ce(t,r,0,0,n,2),n.1Y=7U,n.e=e,n.2w=-10,n.1y=s.3u,i=!0,n}}),h="ct,cs,co,cp".1t(","),2b=h.1f;2b--;)89(h[2b]);h=a.1A,h.1s=h.73=h.3I=1g,h.72=18(t,e,o){1c(!t.3S)1a!1;15.7Z=t,15.3u=o,15.7K=e,u=e.7M,i=!1,r=e.79||a.79,s=G(t,""),n=15.2P;1b h,19,d,m,g,v,x,y,T,b=t.1v;1c(f&&""===b.4c&&(h=Q(t,"4c",s),("2m"===h||""===h)&&15.6l(b,"4c",0)),"1O"==1k e&&(m=b.3B,h=K(t,s),b.3B=m+";"+e,h=J(t,h,K(t)).5O,!j&&w.35(e)&&(h.2a=1q(4D.$1)),e=h,b.3B=m),15.1s=19=e.3M?l.3M.31(t,e.3M,"3M",15,1g,1g,e):15.31(t,e,1g),15.4k){1d(T=3===15.4k,be?p&&(f=!0,""===b.4c&&(x=Q(t,"4c",s),("2m"===x||""===x)&&15.6l(b,"4c",0)),c&&15.6l(b,"7L",15.7K.7L||(T?"cq":"6c"))):b.8L=1,d=19;d&&d.1h;)d=d.1h;y=1j ce(t,"2Q",0,0,1g,2),15.5y(y,1g,d),y.1Y=be?8N:8K,y.1y=15.3I||4N(t,s,!0),y.3V=o,y.2w=-1,n.4K()}1c(i){1d(;19;){1d(v=19.1h,d=m;d&&d.2w>19.2w;)d=d.1h;(19.1n=d?d.1n:g)?19.1n.1h=19:m=19,(19.1h=d)?d.1n=19:g=19,19=v}15.1s=m}1a!0},h.31=18(t,e,i,n){1b a,o,h,f,p,19,c,d,m,g,v=t.1v;1d(a 1x e)19=e[a],o=l[a],o?i=o.31(t,19,a,15,i,n,e):(p=Q(t,a,s)+"",m="1O"==1k 19,"4G"===a||"cr"===a||"cy"===a||-1!==a.1m("cz")||m&&P.35(19)?(m||(19=6d(19),19=(19.1f>3?"6Z(":"6e(")+19.1I(",")+")"),i=5l(v,a,p,19,!0,"4L",i,0,n)):!m||-1===19.1m(" ")&&-1===19.1m(",")?(h=1q(p),c=h||0===h?p.1u((h+"").1f):"",(""===p||"2m"===p)&&("2D"===a||"3j"===a?(h=8R(t,a,s),c="2j"):"51"===a||"4T"===a?(h=H(t,a,s),c="2j"):(h="2a"!==a?0:1,c="")),g=m&&"="===19.1z(1),g?(f=3l(19.1z(0)+"1",10),19=19.1u(2),f*=1q(19),d=19.1N(y,"")):(f=1q(19),d=m?19.1N(y,""):""),""===d&&(d=a 1x r?r[a]:c),19=f||0===f?(g?f+h:f)+d:e[a],c!==d&&""!==d&&(f||0===f)&&h&&(h=$(t,a,h,c),"%"===d?(h/=$(t,a,1M,"%")/1M,e.8D!==!0&&(p=h+"%")):"em"===d?h/=$(t,a,1,"em"):"2j"!==d&&(f=$(t,a,f,d),d="2j"),g&&(f||0===f)&&(19=f+h+d)),g&&(f+=h),!h&&0!==h||!f&&0!==f?2y 0!==v[a]&&(19||"cG"!=19+""&&1g!=19)?(i=1j ce(v,a,f||h||0,0,i,-1,a,!1,0,p,19),i.1U="3E"!==19||"6S"!==a&&-1===a.1m("cH")?19:p):U("cI "+a+" 3V cF: "+e[a]):(i=1j ce(v,a,h,f-h,i,0,a,u!==!1&&("2j"===d||"4c"===a),0,p,19),i.1U=d)):i=5l(v,a,p,19,!0,1g,i,0,n)),n&&i&&!i.2L&&(i.2L=n);1a i},h.1Y=18(t){1b e,i,r,s=15.1s,n=1e-6;1c(1!==t||15.3u.1p!==15.3u.1D&&0!==15.3u.1p)1c(t||15.3u.1p!==15.3u.1D&&0!==15.3u.1p||15.3u.1B===-1e-6)1d(;s;){1c(e=s.c*t+s.s,s.r?e=1i.3P(e):n>e&&e>-n&&(e=0),s.2f)1c(1===s.2f)1c(r=s.l,2===r)s.t[s.p]=s.1U+e+s.4h+s.3Y+s.6g;1o 1c(3===r)s.t[s.p]=s.1U+e+s.4h+s.3Y+s.6g+s.6L+s.6N;1o 1c(4===r)s.t[s.p]=s.1U+e+s.4h+s.3Y+s.6g+s.6L+s.6N+s.8Q+s.8V;1o 1c(5===r)s.t[s.p]=s.1U+e+s.4h+s.3Y+s.6g+s.6L+s.6N+s.8Q+s.8V+s.cE+s.cA;1o{1d(i=s.1U+e+s.4h,r=1;s.l>r;r++)i+=s["3r"+r]+s["38"+(r+1)];s.t[s.p]=i}1o-1===s.2f?s.t[s.p]=s.1U:s.1Y&&s.1Y(t);1o s.t[s.p]=e+s.1U;s=s.1h}1o 1d(;s;)2!==s.2f?s.t[s.p]=s.b:s.1Y(t),s=s.1h;1o 1d(;s;){1c(2!==s.2f)1c(s.r&&-1!==s.2f)1c(e=1i.3P(s.s+s.c),s.2f){1c(1===s.2f){1d(r=s.l,i=s.1U+e+s.4h,r=1;s.l>r;r++)i+=s["3r"+r]+s["38"+(r+1)];s.t[s.p]=i}}1o s.t[s.p]=e+s.1U;1o s.t[s.p]=s.e;1o s.1Y(t);s=s.1h}},h.cB=18(t){15.3I=15.3I||4N(15.7Z,s,!0),15.4k=15.3I.2v&&3p||!t&&3!==15.4k?2:3};1b 8m=18(){15.t[15.p]=15.e,15.1y.5y(15,15.1h,1g,!0)};h.6l=18(t,e,i){1b r=15.1s=1j ce(t,e,0,0,15.1s,2);r.e=i,r.1Y=8m,r.1y=15},h.5y=18(t,e,i,r){1a t&&(e&&(e.1n=t),t.1h&&(t.1h.1n=t.1n),t.1n?t.1n.1h=t.1h:15.1s===t&&(15.1s=t.1h,r=!0),i?i.1h=t:r||1g!==15.1s||(15.1s=t),t.1h=e,t.1n=i),t},h.2s=18(e){1b i,r,s,n=e;1c(e.5F||e.3U){n={};1d(r 1x e)n[r]=e[r];n.2a=1,n.5F&&(n.7r=1)}1a e.3M&&(i=15.7E)&&(s=i.46,s&&s.1n?15.5y(s.1n,i.1h,s.1n.1n):s===15.1s&&(15.1s=i.1h),i.1h&&15.5y(i.1h,i.1h.1h,s.1n),15.7E=1g),t.1A.2s.2h(15,n)};1b 53=18(t,e,i){1b r,s,n,a;1c(t.cC)1d(s=t.1f;--s>-1;)53(t[s],e,i);1o 1d(r=t.8c,s=r.1f;--s>-1;)n=r[s],a=n.2f,n.1v&&(e.24(K(n)),i&&i.24(n)),1!==a&&9!==a&&11!==a||!n.8c.1f||53(n,e,i)};1a a.cD=18(t,i,r){1b s,n,a,o,l=e.4p(t,i,r),h=[l],u=[],f=[],p=[],19=e.5f.9C;1d(t=l.2N||l.2J,53(t,u,p),l.1G(i,!0,!0),53(t,f),l.1G(0,!0,!0),l.1H(!0),s=p.1f;--s>-1;)1c(n=J(p[s],u[s],f[s]),n.4R){n=n.5O;1d(a 1x r)19[a]&&(n[a]=r[a]);o={};1d(a 1x n)o[a]=u[s][a];h.24(e.5Z(p[s],i,o,n))}1a h},t.6O([a]),a},!0)}),1J.3J&&1J.3t.4K()(),18(t){"4I 4J";1b e=18(){1a(1J.5r||1J)[t]};"18"==1k 3H&&3H.6R?3H(["3A"],e):"37"!=1k 2k&&2k.3n&&(8i("../3A.6V"),2k.3n=e())}("9L");',62,901,'|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||this|||function|_|return|var|if|for||length|null|_next|Math|new|typeof|_startTime|indexOf|_prev|else|_time|parseFloat|_timeline|_firstPT|split|substr|style|vars|in|data|charAt|prototype|_rawPrevTime|_timeScale|_duration|_totalTime|_paused|render|_enabled|join|_gsScope|_gc|0px|100|replace|string|Number|xe|255|yPercent|xPercent|xs0|add|rotation|immediateRender|setRatio|_startAt||skewX|rotationX|_p1|push||timeline|totalDuration|_first|rotationY|opacity|ge|yOrigin|xOrigin||type|parser|call|_totalDuration|px|module|_active|auto|arguments|_p2|instanceof|scaleX|smoothChildTiming|_kill|sin|_initted|svg|pr|filter|void|_dirty|easing|duration|getRatio|width|number|_reversed|scaleY|ne|defaultValue|target|_delay|plugin|_ease|_targets|match|_overwriteProps|transform|totalTime|cos|skewY|_labels|constructor|paused|5625|128|lazy||parse|zOrigin||Se|test|scaleZ|undefined|xs|prefix|perspective|_siblings|splice|format|currentStyle|sqrt|wake|xOffset|_last|height|_lazy|parseInt|_uncache|exports|startAt|Te|time|xn|yOffset|_gsQueue|_tween|matrix|_gsTransform|ratio|config|_overwrittenProps|TweenLite|cssText|frame|180|none|_parseTimeOrLabel|global|define|_transform|_gsDefine|_p3|pow|className|autoRemoveChildren|_onUpdate|round|gi|kill|nodeType|_calcEnd|alpha|tween|ue|tweens|xn1|onReverseComplete|_remove|seek|Array|window|oe||xfirst|force3D|selector|API|_propLookup|setAttribute|zIndex|delete|ease|appendXtra|rawTime|xs1|apply|_callback|_transformType|class|multi|_listeners|getPropertyValue|to|object|re|getBBox|dflt|parseComplex|delayedCall|border|skewType|reversed|position|all|onUpdate|getTweensOf|RegExp|onComplete|delay|color|invalidate|use|strict|pop|transparent|version|Ie|concat|Oe|set|firstMPT|PI|top|getAttribute|_sortChildren|_recent|offsetWidth|offsetHeight|Ye||left|document|Ue|_gsClassPT||_notifyPluginsOfEnabled|css|_forcingPlayhead|sc|ke|translate|isActive|runBackwards|overwrite|_internals|_pauseTime|onStart|removeAttribute|scale|atan2|me|_initProps|onOverwrite|greensock|com|plugins|GreenSockGlobals|callbackScope|_propName|pg|self|formatter|transformOrigin|_linkCSSP|keyword|easeInOut|isPause|gsClass|prev|next|autoAlpha|easeIn|le|createElementNS|parentNode|9999999999|ze|repeat|core|difs|rxp|toUpperCase|_swapSelfInParams|_onInitAllProps|abs|ieOffsetX|1e5|01|getChildren|192|fromTo||remove|_e|ox|_onPluginEvent|appendChild|ieOffsetY|sleep|pe|easeParams|ms|_gsTweenID|hidden|he|rgb|Ticker|xs2|tick|toLowerCase|setTimeout|solid|_addLazySet|360|priority|ve|origin|from|hsl|onCompleteParams|inherit|se|Pe|001|000|oy|DXImageTransform|Matrix|Microsoft|borderTopWidth|Fe|Re|Ce|staggerTo|defaultTransformPerspective|Xe|cssFloat|Left|xn2|timeScale|xs3|activate|SlowMo|check|amd|display|fps|easeOut|js|9375|984375|625|rgba|globals|_gsCache|_onInitTween|_lastParsedTransform|_priority||isNaN|center|ticker|suffixMap|_params|_func|_hasPausedChild|console|lagSmoothing|pause|throw|TweenMax|_easeType|_overwrite|fe|useFrames|shortRotationY|autoCSS|_init|_short|padding|visibility|rotationZ|shortRotation|we|shortRotationX|svgOrigin|_onDisable|autoSleep|De|_power|defaultEase|_type|body|_classNamePT|removeChild|rect|margin|inset|absolute|_vars|WebkitBackfaceVisibility|autoRound|defaultView|defaultOverwrite|play|log|_eventTarget|exec|Quad|je|directionalRotation|Cannot|jQuery|transformPerspective|_target|reverse|Be|isFromStart|red|Date|insert|Right|addLabel|filters|ye|Top|te|childNodes|bottom|right|Width|removeLabel|Scope|require|useRAF|gap|1e3|Ve|_rootFramesTimeline|borderLeft|EventDispatcher|events|_easePower|TimelineLite|random|break|dispatchEvent|_p|Back|register|_class|Ease|strength|template|strictUnits|2e3|url|defaultSkewType|_updateRoot|Params|_contains|Ne|zoom|startTime|Ee|TweenPlugin|get|xn3|ie|smoothOrigin|shiftChildren|GreenSockAMDPath|xs4|SteppedEase|RoughEase|map|up||querySelectorAll|borderLeftWidth|Animation|Android|SimpleTimeline|onReverseCompleteParams|matrix3d|marginBottom|getCTM|Ae|defaultSmoothOrigin|styleFloat|org|clrs|marginRight|isSelector|not|_onEnable|Transform|w3|www|http|defaultForce3D|Linear|marginLeft|M22|M21|M12|M11|oxp|oyp|999|Dy|Dx|simple|progid|tan|reservedProps|func|Me|useSVGTransformAttr|_roundProps|init|translate3d|propName|120|CSSPlugin|getBoundingClientRect|removeProperty|Le|lazyRender|Plugin|parseTransform|autoRotate|proxy|webkit|addEventListener|black|marginTop|isArray|lazyTweens|exportRoot|toString|normal|_super|definition|500|_addTween|525|CancelRequestAnimationFrame|tweenLookup|resume|eventCallback|onRepeatScope|999999999999||getElementById|start|restart|usesFrames|killTweensOf|sequence|overwriteProps|_plugins|swing|clearTimeout|_rootTimeline|killDelayedCallsTo|repeatDelay|false|onCompleteScope|allOnStart|preexisting|cancelAnimationFrame|staggerFrom|illegal|Object|_tempKill|staggerFromTo|yoyo|min|initAll|004|70158|easeNone|1500|requestAnimationFrame|concurrent|encountered|Quint|now|pauseCallback|Strong|jquery|endTime|onReverseCompleteScope|recent|insertMultiple|continue|Quart|_autoCSS|onUpdateParams|onStartScope|onStartParams|stagger|getLabelTime|addPause|stop|onUpdateScope|appendMultiple|gotoAndStop|align|gotoAndPlay|Power|append|it|the||dependency|is|onRepeatParams|into|missing|CancelAnimationFrame|GSAP|removeEventListener|BackOut|true|RequestAnimationFrame|moz|totalProgress|getTime|Cubic|clear|progress|on|or|onRepeat|linear|_dummyGS|file|BackIn|Alpha|set3DTransformRatio|setTransformRatio|expand|sizingMethod|chrome|getTransform|359|270|shortRotationZ|block|borderTop|backgroundPosition|background|backgroundPositionX|borderBottomLeftRadius|borderBottomRightRadius|boxShadow|borderRadius|borderTopLeftRadius|borderTopRightRadius|documentElement|setAttributeNS|parseColor|hsla|_setPluginRatio|_parseToProxy|cyan|203|gray|purple|green|pink|end|pt|loaded|registerSpecialProp||SVGElement|2000|Error|_cssRegister|CSSPropTween|collapsible|_registerComplexSpecialProp|backgroundPositionY|backgroundImage|physicsProps|physics2D|visible|fill|throwProps|bezier|radient|oader|pacity|clearProps|stroke|Color|xs5|_enableTransforms|slice|cascadeTo|xn4|value|NaN|Style|invalid|atrix|float|paddingTop|paddingRight|paddingBottom|paddingLeft|userSelect|backfaceVisibility|src|backgroundSize|perspectiveOrigin|transformStyle|clip|clipTop|borderTopColor|borderWidth|borderRightWidth|borderBottomWidth|borderTopStyle|textShadow|clipRight|clipBottom|clipLeft|165|gradient|1999|Z0|xhtml|createElement|div|zA||lineHeight|find|orange|compensated|fontSize|img|_specialProps|Trident|MSIE|points|taper|1px|Firefox|Version|navigator|userAgent|Safari|Chrome|EaseLookup|SineInOut|randomize|clamp|Circ|CircOut|CircIn|out|sort|Bounce|BounceOut|BounceIn|BounceInOut|CircInOut|asin|ExpoInOut|ExpoIn|Sine|SineOut|SineIn|ExpoOut|Expo|Elastic|ElasticOut|ElasticIn|ElasticInOut|999999999|rv|_cw|short|convertToPixels|ccw|getStyle|lime|getComputedStyle|aqua|rad|oyr|calculateOffset|cacheWidths|clientHeight|offset|Origin||clientWidth|oxr|Bottom|line|Webkit|BackInOut|silver||white|fuchsia|yellow|olive|blue|navy|maroon|Ms|Moz|teal'.split('|'),0,{}));;

/*
	* 2D & 3D Transitions for LayerSlider
	*
	* (c) 2011-2014 George Krupa, John Gera & Kreatura Media
	*
	* Plugin web:			http://kreaturamedia.com/
	* Licenses: 			http://codecanyon.net/licenses/
*/



;eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('20 1Z={27:[{j:"13 N E",d:1,g:1,f:{e:0,i:"o"},c:{n:"W",b:"1e",a:G,h:"r"}},{j:"13 N r",d:1,g:1,f:{e:0,i:"o"},c:{n:"W",b:"1e",a:G,h:"E"}},{j:"13 N L",d:1,g:1,f:{e:0,i:"o"},c:{n:"W",b:"1e",a:G,h:"J"}},{j:"13 N J",d:1,g:1,f:{e:0,i:"o"},c:{n:"W",b:"1e",a:G,h:"L"}},{j:"26",d:1,g:1,f:{e:0,i:"o"},c:{n:"14",b:"1e",a:G,h:"r"}},{j:"Z R o",d:[2,4],g:[4,7],f:{e:1k,i:"o"},c:{n:"14",b:"z",a:G,h:"r"}},{j:"Z R D",d:[2,4],g:[4,7],f:{e:1k,i:"D"},c:{n:"14",b:"z",a:G,h:"r"}},{j:"Z R 1j-o",d:[2,4],g:[4,7],f:{e:1k,i:"1j-o"},c:{n:"14",b:"z",a:G,h:"r"}},{j:"Z R 1j-D",d:[2,4],g:[4,7],f:{e:1k,i:"1j-D"},c:{n:"14",b:"z",a:G,h:"r"}},{j:"Z R (k)",d:[2,4],g:[4,7],f:{e:1k,i:"k"},c:{n:"14",b:"z",a:G,h:"r"}},{j:"1y 1H N E",d:1,g:1s,f:{e:25,i:"D"},c:{n:"14",b:"1X",a:V,h:"r"}},{j:"1y 1H N r",d:1,g:1s,f:{e:25,i:"o"},c:{n:"14",b:"w",a:V,h:"r"}},{j:"1y 1H N L",d:1s,g:1,f:{e:25,i:"1j-D"},c:{n:"14",b:"w",a:V,h:"r"}},{j:"1y 1H N J",d:1s,g:1,f:{e:25,i:"1j-o"},c:{n:"14",b:"w",a:V,h:"r"}},{j:"1y Y N E",d:1,g:25,f:{e:1k,i:"D"},c:{n:"W",b:"w",a:1g,h:"r"}},{j:"1y Y N r",d:1,g:25,f:{e:1k,i:"o"},c:{n:"W",b:"w",a:1g,h:"E"}},{j:"1y 1W N L",d:25,g:1,f:{e:1k,i:"1j-D"},c:{n:"W",b:"w",a:1g,h:"J"}},{j:"1y Y N J",d:25,g:1,f:{e:1k,i:"1j-o"},c:{n:"W",b:"w",a:1g,h:"L"}},{j:"13 R m E (k)",d:[2,4],g:[4,7],f:{e:1f,i:"k"},c:{n:"W",b:"z",a:1m,h:"E"}},{j:"13 R m r (k)",d:[2,4],g:[4,7],f:{e:1f,i:"k"},c:{n:"W",b:"z",a:1m,h:"r"}},{j:"13 R m L (k)",d:[2,4],g:[4,7],f:{e:1f,i:"k"},c:{n:"W",b:"z",a:1m,h:"L"}},{j:"13 R m J (k)",d:[2,4],g:[4,7],f:{e:1f,i:"k"},c:{n:"W",b:"z",a:1m,h:"J"}},{j:"13 k R m k 1S",d:[2,4],g:[4,7],f:{e:1f,i:"k"},c:{n:"W",b:"z",a:1m,h:"k"}},{j:"13 d m E (o)",d:[7,11],g:1,f:{e:1d,i:"o"},c:{n:"W",b:"w",a:p,h:"E"}},{j:"13 d m E (D)",d:[7,11],g:1,f:{e:1d,i:"D"},c:{n:"W",b:"w",a:p,h:"E"}},{j:"13 d m E (k)",d:[7,11],g:1,f:{e:1d,i:"k"},c:{n:"W",b:"w",a:p,h:"E"}},{j:"13 d m r (o)",d:[7,11],g:1,f:{e:1d,i:"o"},c:{n:"W",b:"w",a:p,h:"r"}},{j:"13 d m r (D)",d:[7,11],g:1,f:{e:1d,i:"D"},c:{n:"W",b:"w",a:p,h:"r"}},{j:"13 d m r (k)",d:[7,11],g:1,f:{e:1d,i:"k"},c:{n:"W",b:"w",a:p,h:"r"}},{j:"13 d N J m L (o)",d:[7,11],g:1,f:{e:1d,i:"o"},c:{n:"W",b:"w",a:p,h:"L"}},{j:"13 d N J m L (k)",d:[7,11],g:1,f:{e:1d,i:"k"},c:{n:"W",b:"w",a:p,h:"L"}},{j:"13 d N L m J (D)",d:[7,11],g:1,f:{e:1d,i:"D"},c:{n:"W",b:"w",a:p,h:"J"}},{j:"13 d N L m J (k)",d:[7,11],g:1,f:{e:1d,i:"k"},c:{n:"W",b:"w",a:p,h:"J"}},{j:"13 P m L (o)",d:1,g:[12,16],f:{e:q,i:"o"},c:{n:"W",b:"w",a:p,h:"L"}},{j:"13 P m L (D)",d:1,g:[12,16],f:{e:q,i:"D"},c:{n:"W",b:"w",a:p,h:"L"}},{j:"13 P m L (k)",d:1,g:[12,16],f:{e:q,i:"k"},c:{n:"W",b:"w",a:p,h:"L"}},{j:"13 P m J (o)",d:1,g:[12,16],f:{e:q,i:"o"},c:{n:"W",b:"w",a:p,h:"J"}},{j:"13 P m J (D)",d:1,g:[12,16],f:{e:q,i:"D"},c:{n:"W",b:"w",a:p,h:"J"}},{j:"13 P m J (k)",d:1,g:[12,16],f:{e:q,i:"k"},c:{n:"W",b:"w",a:p,h:"J"}},{j:"13 P N r m E (o)",d:1,g:[12,16],f:{e:q,i:"o"},c:{n:"W",b:"w",a:p,h:"E"}},{j:"13 P N r m E (k)",d:1,g:[12,16],f:{e:q,i:"k"},c:{n:"W",b:"w",a:p,h:"E"}},{j:"13 P N E m r (D)",d:1,g:[12,16],f:{e:q,i:"D"},c:{n:"W",b:"w",a:p,h:"r"}},{j:"13 P N E m r (k)",d:1,g:[12,16],f:{e:q,i:"k"},c:{n:"W",b:"w",a:p,h:"r"}},{j:"Z v Y R m E (k)",d:[2,4],g:[4,7],f:{e:1f,i:"k"},c:{n:"Q",b:"z",a:1m,h:"E"}},{j:"Z v Y R m r (k)",d:[2,4],g:[4,7],f:{e:1f,i:"k"},c:{n:"Q",b:"z",a:1m,h:"r"}},{j:"Z v Y R m L (k)",d:[2,4],g:[4,7],f:{e:1f,i:"k"},c:{n:"Q",b:"z",a:1m,h:"L"}},{j:"Z v Y R m J (k)",d:[2,4],g:[4,7],f:{e:1f,i:"k"},c:{n:"Q",b:"z",a:1m,h:"J"}},{j:"Z v Y k R m k 1S",d:[2,4],g:[4,7],f:{e:1f,i:"k"},c:{n:"Q",b:"z",a:1m,h:"k"}},{j:"Z v Y R N J-r (o)",d:[2,4],g:[4,7],f:{e:1f,i:"o"},c:{n:"Q",b:"z",a:1m,h:"1V"}},{j:"Z v Y R N L-E (D)",d:[2,4],g:[4,7],f:{e:1f,i:"D"},c:{n:"Q",b:"z",a:1m,h:"21"}},{j:"Z v Y R N J-E (k)",d:[2,4],g:[4,7],f:{e:1f,i:"k"},c:{n:"Q",b:"z",a:1m,h:"1T"}},{j:"Z v Y R N L-r (k)",d:[2,4],g:[4,7],f:{e:1f,i:"k"},c:{n:"Q",b:"z",a:1m,h:"1U"}},{j:"Z v Y d m E (o)",d:[7,11],g:1,f:{e:1d,i:"o"},c:{n:"Q",b:"w",a:p,h:"E"}},{j:"Z v Y d m E (D)",d:[7,11],g:1,f:{e:1d,i:"D"},c:{n:"Q",b:"w",a:p,h:"E"}},{j:"Z v Y d m E (k)",d:[7,11],g:1,f:{e:1d,i:"k"},c:{n:"Q",b:"w",a:p,h:"E"}},{j:"Z v Y d m r (o)",d:[7,11],g:1,f:{e:1d,i:"o"},c:{n:"Q",b:"w",a:p,h:"r"}},{j:"Z v Y d m r (D)",d:[7,11],g:1,f:{e:1d,i:"D"},c:{n:"Q",b:"w",a:p,h:"r"}},{j:"Z v Y d m r (k)",d:[7,11],g:1,f:{e:1d,i:"k"},c:{n:"Q",b:"w",a:p,h:"r"}},{j:"Z v Y d N J m L (o)",d:[7,11],g:1,f:{e:1d,i:"o"},c:{n:"Q",b:"w",a:p,h:"L"}},{j:"Z v Y d N J m L (k)",d:[7,11],g:1,f:{e:1d,i:"k"},c:{n:"Q",b:"w",a:p,h:"L"}},{j:"Z v Y d N L m J (D)",d:[7,11],g:1,f:{e:1d,i:"D"},c:{n:"Q",b:"w",a:p,h:"J"}},{j:"Z v Y d N L m J (k)",d:[7,11],g:1,f:{e:1d,i:"k"},c:{n:"Q",b:"w",a:p,h:"J"}},{j:"Z v Y P m L (o)",d:1,g:[12,16],f:{e:q,i:"o"},c:{n:"Q",b:"w",a:p,h:"L"}},{j:"Z v Y P m L (D)",d:1,g:[12,16],f:{e:q,i:"D"},c:{n:"Q",b:"w",a:p,h:"L"}},{j:"Z v Y P m L (k)",d:1,g:[12,16],f:{e:q,i:"k"},c:{n:"Q",b:"w",a:p,h:"L"}},{j:"Z v Y P m J (o)",d:1,g:[12,16],f:{e:q,i:"o"},c:{n:"Q",b:"w",a:p,h:"J"}},{j:"Z v Y P m J (D)",d:1,g:[12,16],f:{e:q,i:"D"},c:{n:"Q",b:"w",a:p,h:"J"}},{j:"Z v Y P m J (k)",d:1,g:[12,16],f:{e:q,i:"k"},c:{n:"Q",b:"w",a:p,h:"J"}},{j:"Z v Y P N r m E (o)",d:1,g:[12,16],f:{e:q,i:"o"},c:{n:"Q",b:"w",a:p,h:"E"}},{j:"Z v Y P N r m E (k)",d:1,g:[12,16],f:{e:q,i:"k"},c:{n:"Q",b:"w",a:p,h:"E"}},{j:"Z v Y P N E m r (D)",d:1,g:[12,16],f:{e:q,i:"D"},c:{n:"Q",b:"w",a:p,h:"r"}},{j:"Z v Y P N E m r (k)",d:1,g:[12,16],f:{e:q,i:"k"},c:{n:"Q",b:"w",a:p,h:"r"}},{j:"1u",d:1,g:1,f:{e:0,i:"o"},c:{n:"Q",b:"1e",a:V,h:"r",1h:.5}},{j:"1u d",d:4,g:1,f:{e:1f,i:"o"},c:{n:"Q",b:"1e",a:V,h:"r",1h:.5}},{j:"1u g",d:1,g:4,f:{e:1f,i:"o"},c:{n:"Q",b:"1e",a:V,h:"r",1h:.5}},{j:"1u R A",d:3,g:4,f:{e:1s,i:"o"},c:{n:"Q",b:"1e",a:V,h:"r",1h:.5,y:x}},{j:"1u R F",d:3,g:4,f:{e:1s,i:"o"},c:{n:"Q",b:"1e",a:V,h:"J",1h:.5,u:-x}},{j:"1u-1I R A",d:3,g:4,f:{e:15,i:"o"},c:{n:"Q",b:"1e",a:V,h:"r",1h:.5,y:x}},{j:"1u-1I R F",d:3,g:4,f:{e:15,i:"o"},c:{n:"Q",b:"1e",a:V,h:"J",1h:.5,u:-x}},{j:"1u 1I d",d:4,g:1,f:{e:1f,i:"o"},c:{n:"Q",b:"1e",a:V,h:"E",1h:.5}},{j:"1u 1I g",d:1,g:4,f:{e:1f,i:"o"},c:{n:"Q",b:"1e",a:V,h:"r",1h:.5}},{j:"1c f N r",d:1,g:1,f:{e:0,i:"o"},c:{n:"W",b:"z",a:V,h:"E",y:x}},{j:"1c f N E",d:1,g:1,f:{e:0,i:"o"},c:{n:"W",b:"z",a:V,h:"r",y:-x}},{j:"1c f N J",d:1,g:1,f:{e:0,i:"o"},c:{n:"W",b:"z",a:V,h:"L",u:-x}},{j:"1c f N L",d:1,g:1,f:{e:0,i:"o"},c:{n:"W",b:"z",a:V,h:"J",u:x}},{j:"1c R N r",d:[3,4],g:[3,4],f:{e:19,i:"o"},c:{n:"14",b:"z",a:V,h:"r",y:x}},{j:"1c R N E",d:[3,4],g:[3,4],f:{e:19,i:"D"},c:{n:"14",b:"z",a:V,h:"r",y:-x}},{j:"1c R N J",d:[3,4],g:[3,4],f:{e:19,i:"o"},c:{n:"14",b:"z",a:V,h:"r",u:-x}},{j:"1c R N L",d:[3,4],g:[3,4],f:{e:19,i:"D"},c:{n:"14",b:"z",a:V,h:"r",u:x}},{j:"1c d N J",d:[6,12],g:1,f:{e:19,i:"o"},c:{n:"14",b:"z",a:V,h:"r",u:x}},{j:"1c d N L",d:[6,12],g:1,f:{e:19,i:"D"},c:{n:"14",b:"z",a:V,h:"r",u:-x}},{j:"1c g N r",d:1,g:[6,12],f:{e:19,i:"o"},c:{n:"14",b:"z",a:V,h:"r",y:-x}},{j:"1c g N E",d:1,g:[6,12],f:{e:19,i:"D"},c:{n:"14",b:"z",a:V,h:"r",y:x}},{j:"1v d N r",d:[3,10],g:1,f:{e:19,i:"o"},c:{n:"14",b:"z",a:V,h:"r",y:x}},{j:"1v d N E",d:[3,10],g:1,f:{e:19,i:"D"},c:{n:"14",b:"z",a:V,h:"r",y:-x}},{j:"1v g N J",d:1,g:[3,10],f:{e:19,i:"o"},c:{n:"14",b:"z",a:V,h:"r",u:-x}},{j:"1v g N L",d:1,g:[3,10],f:{e:19,i:"D"},c:{n:"14",b:"z",a:V,h:"r",u:x}},{j:"1v v 1z f N r",d:1,g:1,f:{e:q,i:"o"},c:{n:"Q",b:"z",a:V,h:"E",1h:.1,1r:-x,y:x}},{j:"1v v 1z f N E",d:1,g:1,f:{e:q,i:"o"},c:{n:"Q",b:"z",a:V,h:"r",1h:.1,1r:x,y:-x}},{j:"1v v 1z R N r",d:[3,4],g:[3,4],f:{e:19,i:"o"},c:{n:"Q",b:"z",a:V,h:"E",1r:-1w}},{j:"1v v 1z R N E",d:[3,4],g:[3,4],f:{e:19,i:"o"},c:{n:"Q",b:"z",a:V,h:"r",1r:-1w}},{j:"1v v 1z R N k",d:[3,4],g:[3,4],f:{e:19,i:"k"},c:{n:"Q",b:"z",a:V,h:"k",1r:-1w}},{j:"B f 1O",d:1,g:1,f:{e:0,i:"o"},c:{n:"14",b:"z",a:1a,h:"r",1h:.8}},{j:"B f N 1L",d:1,g:1,f:{e:0,i:"o"},c:{n:"14",b:"w",a:1a,h:"r",1h:1.2}},{j:"B R k",d:[3,4],g:[3,4],f:{e:1s,i:"k"},c:{n:"14",b:"z",a:V,h:"r",1h:.1}},{j:"B R N 1L k",d:[3,4],g:[3,4],f:{e:1s,i:"k"},c:{n:"14",b:"z",a:V,h:"r",1h:2}},{j:"B 1O v 1z R k",d:[3,4],g:[3,4],f:{e:1s,i:"k"},c:{n:"14",b:"z",a:V,h:"r",1h:.1,1r:x}},{j:"B v 1z R N 1L k",d:[3,4],g:[3,4],f:{e:1s,i:"k"},c:{n:"14",b:"z",a:V,h:"r",1h:2,1r:-x}},{j:"1D-Y R 24",d:3,g:4,f:{e:15,i:"o"},c:{n:"W",b:"w",a:1Y,h:"1T"}},{j:"1D-Y d A",d:6,g:1,f:{e:0,i:"o"},c:{n:"Q",b:"z",a:V,h:"r"}},{j:"1D-Y d F",d:6,g:1,f:{e:0,i:"o"},c:{n:"Q",b:"z",a:V,h:"J"}},{j:"1D-Y g A",d:1,g:8,f:{e:0,i:"o"},c:{n:"Q",b:"z",a:V,h:"r"}},{j:"1D-Y g F",d:1,g:8,f:{e:0,i:"o"},c:{n:"Q",b:"z",a:V,h:"J"}}],23:[{j:"1b f m E (l&#t;)",d:1,g:1,f:{e:q,i:"o"},s:{c:{y:1E},b:"1F",a:G,h:"A"},C:{c:{y:l},b:"z",a:G,h:"A"}},{j:"1b f m r (l&#t;)",d:1,g:1,f:{e:q,i:"o"},s:{c:{y:-1E},b:"1F",a:G,h:"A"},C:{c:{y:-l},b:"z",a:G,h:"A"}},{j:"1b f m L (l&#t;)",d:1,g:1,f:{e:q,i:"o"},s:{c:{u:-1E},b:"1F",a:1x,h:"F"},C:{c:{u:-l},b:"z",a:1x,h:"F"}},{j:"1b f m J (l&#t;)",d:1,g:1,f:{e:q,i:"o"},s:{c:{u:1E},b:"1F",a:1x,h:"F"},C:{c:{u:l},b:"z",a:1x,h:"F"}},{j:"1b R m E (l&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"o"},s:{c:{y:l},b:"w",a:G,h:"A"}},{j:"1b R m r (l&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"D"},s:{c:{y:-l},b:"w",a:G,h:"A"}},{j:"1b R m L (l&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"1j-o"},s:{c:{u:-l},b:"w",a:G,h:"F"}},{j:"1b R m J (l&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"1j-D"},s:{c:{u:l},b:"w",a:G,h:"F"}},{j:"1B S R k (l&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"k"},s:{c:{y:l},b:"w",a:1G,h:"A"}},{j:"1C S R k (l&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"k"},s:{c:{u:l},b:"w",a:1G,h:"F"}},{j:"B v S R m E (l&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"o"},M:{c:{I:.1A},a:1l,b:"18"},s:{c:{y:l},b:"H",a:G,h:"A"},C:{a:1g,b:"H"}},{j:"B v S R m r (l&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"D"},M:{c:{I:.1A},a:1l,b:"18"},s:{c:{y:-l},b:"H",a:G,h:"A"},C:{a:1g,b:"H"}},{j:"B v S R m L (l&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"1j-o"},M:{c:{I:.1A},a:1l,b:"18"},s:{c:{u:-l},b:"H",a:G,h:"F"},C:{a:1g,b:"H"}},{j:"B v S R m J (l&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"1j-D"},M:{c:{I:.1A},a:1l,b:"18"},s:{c:{u:l},b:"H",a:G,h:"F"},C:{a:1g,b:"H"}},{j:"B v A S R k (l&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"k"},M:{c:{I:.1A,u:1k},a:1l,b:"18"},s:{c:{y:l,u:-1k},b:"H",a:1G,h:"A"},C:{c:{u:0},a:1g,b:"H"}},{j:"B v F S R k (l&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"k"},M:{c:{I:.1A,y:-15},a:1l,b:"18"},s:{c:{u:l,y:15},b:"H",a:1G,h:"F"},C:{c:{y:0},a:1g,b:"H"}},{j:"1b d m E (l&#t;)",d:[5,9],g:1,f:{e:q,i:"o"},s:{c:{y:l},b:"w",a:1a,h:"A"}},{j:"1b d m r (l&#t;)",d:[5,9],g:1,f:{e:q,i:"o"},s:{c:{y:-l},b:"w",a:1a,h:"A"}},{j:"1b d m L (l&#t;)",d:[5,9],g:1,f:{e:q,i:"o"},s:{c:{u:-l},b:"w",a:G,h:"F"}},{j:"1b d m J (l&#t;)",d:[5,9],g:1,f:{e:q,i:"D"},s:{c:{u:l},b:"w",a:G,h:"F"}},{j:"1B S d k (l&#t;)",d:[5,9],g:1,f:{e:q,i:"k"},s:{c:{y:l},b:"w",a:1a,h:"A"}},{j:"1C S d k (l&#t;)",d:[5,9],g:1,f:{e:q,i:"k"},s:{c:{u:-l},b:"w",a:1a,h:"F"}},{j:"1C S d k (1J&#t;)",d:[3,7],g:1,f:{e:1Q,i:"k"},s:{c:{u:-1J},b:"w",a:1R,h:"F"}},{j:"B v S d m E (l&#t;)",d:[5,9],g:1,f:{e:19,i:"o"},M:{c:{I:.O},a:p,b:"K"},s:{c:{y:l},b:"H",a:1p,h:"A"},C:{c:{e:X},b:"K",a:p}},{j:"B v S d m r (l&#t;)",d:[5,9],g:1,f:{e:19,i:"D"},M:{c:{I:.O},a:p,b:"K"},s:{c:{y:-l},b:"H",a:1p,h:"A"},C:{c:{e:X},b:"K",a:p}},{j:"B v S d m L (l&#t;)",d:[5,9],g:1,f:{e:19,i:"o"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:-l},b:"w",a:p,h:"F"},C:{c:{e:X},b:"K",a:p}},{j:"B v S d m J (l&#t;)",d:[5,9],g:1,f:{e:19,i:"D"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:l},b:"w",a:p,h:"F"},C:{c:{e:X},b:"K",a:p}},{j:"B v A S d k (l&#t;)",d:[5,9],g:1,f:{e:19,i:"k"},M:{c:{I:.O},a:p,b:"K"},s:{c:{y:l},b:"H",a:1p,h:"A"},C:{c:{e:X},b:"K",a:p}},{j:"B v F S d k (l&#t;)",d:[5,9],g:1,f:{e:19,i:"k"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:-l},b:"H",a:p,h:"F"},C:{c:{e:X},b:"K",a:p}},{j:"1b P m E (l&#t;)",d:1,g:[5,9],f:{e:q,i:"o"},s:{c:{y:l},b:"w",a:1a,h:"A"}},{j:"1b P m r (l&#t;)",d:1,g:[5,9],f:{e:q,i:"o"},s:{c:{y:-l},b:"w",a:1a,h:"A"}},{j:"1b P m L (l&#t;)",d:1,g:[5,9],f:{e:q,i:"o"},s:{c:{u:-l},b:"w",a:G,h:"F"}},{j:"1b P m J (l&#t;)",d:1,g:[5,9],f:{e:q,i:"D"},s:{c:{u:l},b:"w",a:G,h:"F"}},{j:"1B S P k (l&#t;)",d:1,g:[5,9],f:{e:q,i:"k"},s:{c:{y:l},b:"w",a:1a,h:"A"}},{j:"1C S P k (l&#t;)",d:1,g:[5,9],f:{e:q,i:"k"},s:{c:{u:-l},b:"w",a:1a,h:"F"}},{j:"1B S P k (1J&#t;)",d:1,g:[4,9],f:{e:1Q,i:"k"},s:{c:{y:1J},b:"w",a:1R,h:"A"}},{j:"B v S P m E (l&#t;)",d:1,g:[7,11],f:{e:19,i:"o"},M:{c:{I:.O},a:p,b:"K"},s:{c:{y:l},b:"w",a:p,h:"A"},C:{c:{e:X},b:"K",a:p}},{j:"B v S P m r (l&#t;)",d:1,g:[7,11],f:{e:19,i:"D"},M:{c:{I:.O},a:p,b:"K"},s:{c:{y:-l},b:"w",a:p,h:"A"},C:{c:{e:X},b:"K",a:p}},{j:"B v S P m L (l&#t;)",d:1,g:[7,11],f:{e:19,i:"o"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:-l},b:"H",a:1p,h:"F"},C:{c:{e:X},b:"K",a:p}},{j:"B v S P m J (l&#t;)",d:1,g:[7,11],f:{e:q,i:"D"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:l},b:"H",a:1p,h:"F"},C:{c:{e:X},b:"K",a:p}},{j:"B v A S P k (l&#t;)",d:1,g:[7,11],f:{e:q,i:"k"},M:{c:{I:.O},a:p,b:"K"},s:{c:{y:l},b:"H",a:p,h:"A"},C:{c:{e:X},b:"K",a:p}},{j:"B v F S P k (l&#t;)",d:1,g:[7,11],f:{e:q,i:"k"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:-l},b:"H",a:1p,h:"F"},C:{c:{e:X},b:"K",a:p}},{j:"1N 1P 1M v S m E (l&#t;)",d:1,g:[7,11],f:{e:q,i:"o"},M:{c:{I:.O,u:-1k},a:p,b:"z"},s:{c:{u:-1k,y:l},b:"w",a:G,h:"A"},C:{c:{u:0,e:X},b:"z",a:p}},{j:"1N 1P 1M v S m r (l&#t;)",d:1,g:[7,11],f:{e:q,i:"D"},M:{c:{I:.O,u:-1k},a:p,b:"z"},s:{c:{u:1k,y:-l},b:"w",a:G,h:"A"},C:{c:{u:0,e:X},b:"z",a:p}},{j:"1c 1t m E (x&#t;)",d:1,g:1,f:{e:q,i:"o"},s:{c:{y:x},b:"w",a:1a,h:"A"}},{j:"1c 1t m r (x&#t;)",d:1,g:1,f:{e:q,i:"o"},s:{c:{y:-x},b:"w",a:1a,h:"A"}},{j:"1c 1t m L (x&#t;)",d:1,g:1,f:{e:q,i:"o"},s:{c:{u:-x},b:"w",a:1a,h:"F"}},{j:"1c 1t m J (x&#t;)",d:1,g:1,f:{e:q,i:"o"},s:{c:{u:x},b:"w",a:1a,h:"F"}},{j:"B v 17 1t m E (x&#t;)",d:1,g:1,f:{e:q,i:"k"},s:{c:{I:.8,1r:7,u:10,y:1w},b:"1e",a:1x,h:"A"},C:{c:{1r:0,u:0,y:x},a:1x,b:"1e"}},{j:"B v 17 1t m r (x&#t;)",d:1,g:1,f:{e:q,i:"k"},s:{c:{I:.8,1r:-7,u:10,y:-1w},b:"1e",a:1x,h:"A"},C:{c:{1r:0,u:0,y:-x},a:1x,b:"1e"}},{j:"B v 17 1n m E (x&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"o"},M:{c:{I:.O},a:1l,b:"18"},s:{c:{y:x},b:"H",a:G,h:"A"},C:{a:1g,b:"H"}},{j:"B v 17 1n m r (x&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"D"},M:{c:{I:.O},a:1l,b:"18"},s:{c:{y:-x},b:"H",a:G,h:"A"},C:{a:1g,b:"H"}},{j:"B v 17 1n m L (x&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"1j-o"},M:{c:{I:.O},a:1l,b:"18"},s:{c:{u:-x},b:"H",a:G,h:"F"},C:{a:1g,b:"H"}},{j:"B v 17 1n m J (x&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"1j-D"},M:{c:{I:.O},a:1l,b:"18"},s:{c:{u:x},b:"H",a:G,h:"F"},C:{a:1g,b:"H"}},{j:"B v A 17 1n k (x&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"k"},M:{c:{I:.1i,u:-15},a:1o,b:"18"},s:{c:{y:q,u:15},b:"H",a:1o,h:"A"},C:{c:{y:x,u:0},a:1o,b:"H"}},{j:"B v F 17 1n k (x&#t;)",d:[2,4],g:[4,7],f:{e:q,i:"k"},M:{c:{I:.1i,y:15},a:1o,b:"18"},s:{c:{u:q,y:-15},b:"H",a:1o,h:"F"},C:{c:{u:x,y:0},a:1o,b:"H"}},{j:"1c d m E (x&#t;)",d:[5,9],g:1,f:{e:q,i:"o"},s:{c:{y:x},b:"w",a:1a,h:"A"}},{j:"1c d m r (x&#t;)",d:[5,9],g:1,f:{e:q,i:"o"},s:{c:{y:-x},b:"w",a:1a,h:"A"}},{j:"1B 17 d k (x&#t;)",d:[5,9],g:1,f:{e:q,i:"k"},s:{c:{y:x},b:"w",a:1a,h:"A"}},{j:"B v 17 d m E (x&#t;)",d:[5,9],g:1,f:{e:q,i:"o"},M:{c:{I:.O,u:3},a:p,b:"K"},s:{c:{y:22,u:0},b:"H",a:G,h:"A"},C:{c:{e:X,y:x},b:"K",a:p}},{j:"B v 17 d m r (x&#t;)",d:[5,9],g:1,f:{e:q,i:"D"},M:{c:{I:.O,u:3},a:p,b:"K"},s:{c:{y:-x,u:0},b:"H",a:G,h:"A"},C:{c:{e:X},b:"K",a:p}},{j:"B v 17 d m L (x&#t;)",d:[5,9],g:1,f:{e:q,i:"o"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:-x},b:"H",a:G,h:"F"},C:{c:{e:X},b:"K",a:p}},{j:"B v 17 d m J (x&#t;)",d:[5,9],g:1,f:{e:q,i:"D"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:x},b:"H",a:G,h:"F"},C:{c:{e:X},b:"K",a:p}},{j:"B v A 17 d k (x&#t;)",d:[5,9],g:1,f:{e:q,i:"k"},M:{c:{I:.O,u:3},a:p,b:"K"},s:{c:{y:x,u:0},b:"H",a:G,h:"A"},C:{c:{e:X},b:"K",a:p}},{j:"B v F 17 d k (x&#t;)",d:[5,9],g:1,f:{e:q,i:"k"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:-x},b:"H",a:G,h:"F"},C:{c:{e:X},b:"K",a:p}},{j:"B v A 17 1K d m E (x&#t;)",d:[7,11],g:1,f:{e:q,i:"o"},s:{c:{I:.O,u:5,y:1w},b:"18",a:G,h:"A"},C:{c:{u:0,y:x},b:"18",a:G}},{j:"B v A 17 1K d m r (x&#t;)",d:[7,11],g:1,f:{e:q,i:"D"},s:{c:{I:.O,u:5,y:-1w},b:"18",a:G,h:"A"},C:{c:{u:0,y:-x},b:"18",a:G}},{j:"1c P m L (x&#t;)",d:1,g:[5,9],f:{e:q,i:"o"},s:{c:{u:-x},b:"w",a:G,h:"F"}},{j:"1c P m J (x&#t;)",d:1,g:[5,9],f:{e:q,i:"D"},s:{c:{u:x},b:"w",a:G,h:"F"}},{j:"1C 17 P k (x&#t;)",d:1,g:[5,9],f:{e:q,i:"k"},s:{c:{u:-x},b:"w",a:G,h:"F"}},{j:"B v 17 P m L (x&#t;)",d:1,g:[7,11],f:{e:q,i:"o"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:-x},b:"H",a:G,h:"F"},C:{c:{e:X},b:"K",a:p}},{j:"B v 17 P m J (x&#t;)",d:1,g:[7,11],f:{e:q,i:"D"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:x},b:"H",a:G,h:"F"},C:{c:{e:X},b:"K",a:p}},{j:"B v 17 P m E (x&#t;)",d:1,g:[7,11],f:{e:q,i:"o"},M:{c:{I:.O},a:p,b:"K"},s:{c:{y:x},b:"H",a:G,h:"A"},C:{c:{e:X},b:"K",a:p}},{j:"B v 17 P m r (x&#t;)",d:1,g:[7,11],f:{e:q,i:"D"},M:{c:{I:.O},a:p,b:"K"},s:{c:{y:-x},b:"H",a:G,h:"A"},C:{c:{e:X},b:"K",a:p}},{j:"B v A 17 P k (x&#t;)",d:1,g:[7,11],f:{e:q,i:"k"},M:{c:{I:.O},a:p,b:"K"},s:{c:{y:x},b:"H",a:G,h:"A"},C:{c:{e:X},b:"K",a:p}},{j:"B v F 17 P k (x&#t;)",d:1,g:[7,11],f:{e:q,i:"k"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:-x},b:"H",a:G,h:"F"},C:{c:{e:X},b:"K",a:p}},{j:"B v F 17 1K P m E (x&#t;)",d:1,g:[7,11],f:{e:q,i:"o"},s:{c:{I:.O,u:1w,y:-5},b:"18",a:G,h:"F"},C:{c:{u:x,y:0},b:"18",a:G}},{j:"B v F 17 1K P m r (x&#t;)",d:1,g:[7,11],f:{e:q,i:"D"},s:{c:{I:.O,u:-1w,y:-5},b:"18",a:G,h:"F"},C:{c:{u:-x,y:0},b:"18",a:G}},{j:"1b 1t m E (l&#t;, T U)",d:1,g:1,f:{e:q,i:"o",U:"T"},s:{c:{y:l},b:"w",a:1a,h:"A"}},{j:"1b 1t m r (l&#t;, T U)",d:1,g:1,f:{e:q,i:"o",U:"T"},s:{c:{y:-l},b:"w",a:1a,h:"A"}},{j:"1b 1t m L (l&#t;, T U)",d:1,g:1,f:{e:q,i:"o",U:"T"},s:{c:{u:-l},b:"w",a:1a,h:"F"}},{j:"1b 1t m J (l&#t;, T U)",d:1,g:1,f:{e:q,i:"o",U:"T"},s:{c:{u:l},b:"w",a:1a,h:"F"}},{j:"B v S 1n m E (l&#t;, T U)",d:[2,4],g:[4,7],f:{e:q,i:"o",U:"T"},M:{c:{I:.O},a:1l,b:"18"},s:{c:{y:l},b:"H",a:G,h:"A"},C:{a:1g,b:"H"}},{j:"B v S 1n m r (l&#t;, T U)",d:[2,4],g:[4,7],f:{e:q,i:"D",U:"T"},M:{c:{I:.O},a:1l,b:"18"},s:{c:{y:-l},b:"H",a:G,h:"A"},C:{a:1g,b:"H"}},{j:"B v S 1n m L (l&#t;, T U)",d:[2,4],g:[4,7],f:{e:q,i:"1j-o",U:"T"},M:{c:{I:.O},a:1l,b:"18"},s:{c:{u:-l},b:"H",a:G,h:"F"},C:{a:1g,b:"H"}},{j:"B v S 1n m J (l&#t;, T U)",d:[2,4],g:[4,7],f:{e:q,i:"1j-D",U:"T"},M:{c:{I:.O},a:1l,b:"18"},s:{c:{u:l},b:"H",a:G,h:"F"},C:{a:1g,b:"H"}},{j:"B v A S 1n k (l&#t;, T U)",d:[2,4],g:[4,7],f:{e:q,i:"k",U:"T"},M:{c:{I:.1i},a:1o,b:"18"},s:{c:{y:l},b:"H",a:1o,h:"A"},C:{a:1o,b:"H"}},{j:"B v F S 1n k (l&#t;, T U)",d:[2,4],g:[4,7],f:{e:q,i:"k",U:"T"},M:{c:{I:.1i},a:1o,b:"18"},s:{c:{u:l},b:"H",a:1o,h:"F"},C:{a:1o,b:"H"}},{j:"B v S d m E (l&#t;, T U)",d:[5,9],g:1,f:{e:1i,i:"o",U:"T"},M:{c:{I:.O,u:3},a:p,b:"K"},s:{c:{y:l,u:-3},b:"w",a:1p,h:"A"},C:{c:{e:X,u:0},b:"z",a:1q}},{j:"B v S d m r (l&#t;, T U)",d:[5,9],g:1,f:{e:1i,i:"D",U:"T"},M:{c:{I:.O,u:3},a:p,b:"K"},s:{c:{y:-l,u:-3},b:"w",a:1p,h:"A"},C:{c:{e:X,u:0},b:"z",a:1q}},{j:"B v S d m L (l&#t;, T U)",d:[5,9],g:1,f:{e:1i,i:"o",U:"T"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:-l},b:"H",a:G,h:"F"},C:{c:{e:X},b:"z",a:1q}},{j:"B v S d m J (l&#t;, T U)",d:[5,9],g:1,f:{e:1i,i:"D",U:"T"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:l},b:"H",a:G,h:"F"},C:{c:{e:X},b:"z",a:1q}},{j:"B v A S d k (l&#t;, T U)",d:[5,9],g:1,f:{e:1i,i:"k",U:"T"},M:{c:{I:.O,u:3},a:p,b:"K"},s:{c:{y:l,u:-3},b:"w",a:1p,h:"A"},C:{c:{e:X,u:0},b:"z",a:1q}},{j:"B v F S d k (l&#t;, T U)",d:[5,9],g:1,f:{e:1i,i:"k",U:"T"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:-l},b:"H",a:G,h:"F"},C:{c:{e:X},b:"z",a:1q}},{j:"B v S P m L (l&#t;, T U)",d:1,g:[7,11],f:{e:1i,i:"o",U:"T"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:-l},b:"w",a:1p,h:"F"},C:{c:{e:X},b:"z",a:1q}},{j:"B v S P m J (l&#t;, T U)",d:1,g:[7,11],f:{e:1i,i:"D",U:"T"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:l},b:"w",a:1p,h:"F"},C:{c:{e:X},b:"z",a:1q}},{j:"B v S P m E (l&#t;, T U)",d:1,g:[7,11],f:{e:1i,i:"o",U:"T"},M:{c:{I:.O},a:p,b:"K"},s:{c:{y:l},b:"H",a:G,h:"A"},C:{c:{e:X},b:"z",a:1q}},{j:"B v S P m r (l&#t;, T U)",d:1,g:[7,11],f:{e:1i,i:"D",U:"T"},M:{c:{I:.O},a:p,b:"K"},s:{c:{y:-l},b:"H",a:G,h:"A"},C:{c:{e:X},b:"z",a:1q}},{j:"B v A S P k (l&#t;, T U)",d:1,g:[7,11],f:{e:1i,i:"k",U:"T"},M:{c:{I:.O},a:p,b:"K"},s:{c:{y:l},b:"H",a:G,h:"A"},C:{c:{e:X},b:"z",a:1q}},{j:"B v F S P k (l&#t;, T U)",d:1,g:[7,11],f:{e:1i,i:"k",U:"T"},M:{c:{I:.O},a:p,b:"K"},s:{c:{u:-l},b:"w",a:1p,h:"F"},C:{c:{e:X},b:"z",a:1q}}]}',62,132,'||||||||||duration|easing|transition|rows|delay|tile|cols|direction|sequence|name|random|180|to|type|forward|600|75|left|animation|176|rotateX|and|easeInOutQuart|90|rotateY|easeOutQuart|horizontal|Scaling|after|reverse|right|vertical|1e3|easeInOutBack|scale3d|top|easeOutBack|bottom|before|from|85|columns|mixed|tiles|spinning|large|depth|750|slide|200|sliding|Fading||||Sliding|fade|||turning|easeInOutQuint|55|1500|Spinning|Turning|100|easeInOutQuad|50|350|scale|65|col|30|450|500|cuboids|700|1200|400|rotate|35|cuboid|Carousel|Flying|45|800|Smooth|rotating|95|Horizontal|Vertical|Mirror|91|easeInQuart|1300|fading|mirror|540|drunk|out|scaling|Drunk|in|colums|150|2e3|directions|topright|bottomleft|topleft|sliging|linear|850|layerSliderTransitions|var|bottomright|87|t3d|diagonal||Crossfading|t2d'.split('|')));
;

/*
	* LayerSlider
	*
	* (c) 2011-2015 George Krupa, John Gera & Kreatura Media
	*
	* Plugin web:			http://kreaturamedia.com/
	* licenses:				http://codecanyon.net/licenses/
*/



function lsShowNotice(lsobj,issue,ver){

	var el;

	if( typeof lsobj == 'string' ){
		el = jQuery('#'+lsobj);
	}else if( typeof lsobj == 'object' ){
		el = lsobj;
	}

	var errorTitle, errorText;
	switch(issue){
		case 'jquery':
		errorTitle = 'multiple jQuery issue';
		errorText = 'It looks like that another plugin or your theme loads an extra copy of the jQuery library causing problems for LayerSlider to show your sliders. <strong>Please navigate on your WordPress admin area to the main page of LayerSlider and enable the "Put JS includes to body" option within the Troubleshooting & Advanced Settings box.</strong>';
		break;
		case 'oldjquery':
		errorTitle = 'old jQuery issue';
		errorText = 'It looks like you are using an old version ('+ver+') of the jQuery library. LayerSlider requires at least version 1.7.0 or newer. Please update jQuery to 1.10.x or higher. Important: Please do not use the jQuery Updater plugin on WordPress and do not update to 2.x version of jQuery because it is not compatible with older browsers like IE 7 & 8. <a href="http://support.kreaturamedia.com/faq/4/layerslider-for-wordpress/#group-13&entry-60">You can read more about updating jQuery by clicking here.</a>';
		break;
	}

	el.addClass('ls-error');
	el.append('<p class="ls-exclam">!</p>');
	el.append('<p class="ls-error-title">LayerSlider: '+errorTitle+'</p>');
	el.append('<p class="ls-error-text">'+errorText+'</p>');
}

(function($) {

	// IMPROVEMENT v5.3.0 Fixed multiple Greensock issues

	if( typeof kmGS !== 'undefined' ){
		for(var prop in kmGS) {
			this[prop] = kmGS[prop];
		}
	}

	$.fn.layerSlider = function( options ){

		// IMPROVEMENT v4.1.0 Checking jQuery version
		// IMPROVEMENT v4.1.3 Changed required version from 1.7.2 to 1.7.0

		var reqVer = '1.7.0';
		var curVer = $.fn.jquery;
		var el = $(this);

		var checkVersions = function(v1,v2){

			var v1parts = v1.split('.');
			var v2parts = v2.split('.');

			for (var i = 0; i < v1parts.length; ++i) {

				if (v2parts.length == i) {
					return false;
				}

				if(parseInt(v1parts[i]) == parseInt(v2parts[i])){
					continue;
				}else if (parseInt(v1parts[i]) > parseInt(v2parts[i])){
					return false;
				}else{
					return true;
				}
			}

			if (v1parts.length != v2parts.length) {
				return true;
			}

			return true;
		};

		if( !checkVersions('1.8.0',curVer) ){
			el.addClass('ls-norotate');
		}

		// Initializing if jQuery version is greater than 1.7.0

		if( !checkVersions(reqVer,curVer) ){
			lsShowNotice( el, 'oldjquery', curVer );
		}else{

			if( (typeof(options)).match('object|undefined') ){
				return this.each(function(i){
					new layerSlider(this, options);
				});
			}else{
				if( options === 'data' ){
					var lsData = $(this).data('LayerSlider').g;
					if( lsData ){
						return lsData;
					}

				// NEW FEATURES v5.2.0 option to get userInitData & defaultInitData

				}else if( options === 'userInitData' ){
					var lsInitData = $(this).data('LayerSlider').o;
					if( lsInitData ){
						return lsInitData;
					}
				}else if( options === 'defaultInitData' ){
					var lsInitData = $(this).data('LayerSlider').defaults;
					if( lsInitData ){
						return lsInitData;
					}

				}else{
					return this.each(function(i){

						// Control functions: prev, next, start, stop & change

						var lsData = $(this).data('LayerSlider');
						if( lsData ){
							if( !lsData.g.isAnimating && !lsData.g.isLoading ){
								if( typeof options == 'number' ){
									if( options > 0 && options < lsData.g.layersNum + 1 && options != lsData.g.curLayerIndex ){
										lsData.change(options);
									}
								}else{
									switch(options){
										case 'prev':
											lsData.o.cbPrev(lsData.g);
											lsData.prev('clicked');
											break;
										case 'next':
											lsData.o.cbNext(lsData.g);
											lsData.next('clicked');
											break;
										case 'start':
											if( !lsData.g.autoSlideshow ){
												lsData.o.cbStart(lsData.g);
												lsData.g.originalAutoSlideshow = true;
												lsData.start();
											}
											break;
									}
								}
							}
							// if( options === 'debug' ){
							// 	lsData.d.show();
							// }
							if( options === 'redraw' ){
								lsData.resize();
							}
							if( ( lsData.g.autoSlideshow || ( !lsData.g.autoSlideshow && lsData.g.originalAutoSlideshow ) ) && options == 'stop' ){
								lsData.o.cbStop(lsData.g);
								lsData.g.originalAutoSlideshow = false;
								lsData.g.curLayer.find('iframe[src*="youtube.com"], iframe[src*="youtu.be"], iframe[src*="player.vimeo"]').each(function(){

									// Clearing videoTimeouts

									clearTimeout( $(this).data( 'videoTimer') );
								});

								lsData.stop();
							}
							if( options == 'forceStop'){
								lsData.forcestop();
							}
						}
					});
				}
			}
		}
	};

	// LayerSlider methods

	var layerSlider = function(el, options) {

		var ls = this;
		ls.$el = $(el).addClass('ls-container');
		ls.$el.data('LayerSlider', ls);

		ls.load = function(){

			// Setting options (user settings) and global (not modificable) parameters

			ls.defaults = layerSlider.options;
			ls.o = $.extend({},ls.defaults, options);
			ls.g = $.extend({},layerSlider.global);
			ls.lt = $.extend({},layerSlider.layerTransitions );
			ls.st = $.extend({},layerSlider.slideTransitions );

			ls.g.enableCSS3 = $(el).hasClass('ls-norotate') ? false : true;

			// NEW FEATURE v5.2.0 saving original HTML Markup

			ls.g.originalMarkup = $(el).html();

			if( ls.g.ie78 ){
				ls.o.lazyLoad = false;
			}

			// WP parameters

			if( ls.o.autoPauseSlideshow === 'enabled' ){
				ls.o.autoPauseSlideshow = true;
			}
			if( ls.o.autoPauseSlideshow === 'disabled' ){
				ls.o.autoPauseSlideshow = false;
			}

			// If layerslider.transitions.js is loaded...

			if( typeof layerSliderTransitions !== 'undefined' ){
				ls.t = $.extend({},layerSliderTransitions);
			}

			// If custom transitions are loaded...

			if( typeof layerSliderCustomTransitions !== 'undefined' ){
				ls.ct = $.extend({},layerSliderCustomTransitions);
			}

			// NEW IMPROVEMENT v3.6 forbid to call the init code more than once on the same element

			if( !ls.g.initialized ){

				ls.g.initialized = true;

				// Added debug mode v3.5

				// ls.debug();

				if( $('html').find('meta[content*="WordPress"]').length ){
					ls.g.wpVersion = $('html').find('meta[content*="WordPress"]').attr('content').split('WordPress')[1];
				}

				if( $('html').find('script[src*="layerslider"]').length ){
					if( $('html').find('script[src*="layerslider"]').attr('src').indexOf('?') != -1 ){
						ls.g.lswpVersion = $('html').find('script[src*="layerslider"]').attr('src').split('?')[1].split('=')[1];
					}
				}

				// Debug mode controls

				// ls.d.aT('LayerSlider controls');
				// ls.d.aU('<a href="#">prev</a> | <a href="#">next</a> | <a href="#">start</a> | <a href="#">stop</a> | <a href="#">force stop</a>');
				// ls.d.history.find('a').each(function(){
				// 	$(this).click(function(e){
				// 		e.preventDefault();
				// 		$(el).layerSlider($(this).text());
				// 	});
				// });

				// ls.d.aT('LayerSlider version information');
				// ls.d.aU('JS version: <strong>' + ls.g.version + '</strong>');
				// if(ls.g.lswpVersion){
				// 	ls.d.aL('WP version: <strong>' + ls.g.lswpVersion + '</strong>');
				// }
				// if(ls.g.wpVersion){
				// 	ls.d.aL('WordPress version: <strong>' + ls.g.wpVersion + '</strong>');
				// }

				// ls.d.aL('jQuery version: <strong>' + $().jquery + '</strong>');

				// if( $(el).attr('id') ){

				// 	ls.d.aT('LayerSlider container');
				// 	ls.d.aU('#'+$(el).attr('id'));
				// }

                // Modified code assuming skin css file has been preloaded

                if (!ls.o.skin || ls.o.skin == '' || !ls.o.skinsPath || ls.o.skinsPath == '') {
                } else {
                    $(el).addClass('ls-' + ls.o.skin);
                }
                
                ls.g.loaded = true;
                ls.init();
			}
		};

		ls.init = function(){

			// NEW FEATURE v5.5.0 Appending the slider element into the element specified in prependTo

			$(el).prependTo( $( ls.o.prependTo ) );

			// IMPROVEMENT v4.0.1 Trying to add special ID to <body> or <html> (required to overwrite WordPresss global styles)

			if( !$('html').attr('id') ){
				$('html').attr('id','ls-global');
			}else if( !$('body').attr('id') ){
				$('body').attr('id','ls-global');
			}

			// NEW FEATURES v5.2.0 Hiding the slider on mobile devices, smaller resolutions
			// or changing it to a static but responsive image

			if( ls.g.isMobile() === true && ls.o.hideOnMobile === true ){
				$(el).addClass('ls-forcehide');
				$(el).closest('.ls-wp-fullwidth-container').addClass('ls-forcehide');
			}

			var showHide = function(){

				if( ls.o.hideOnMobile === true && ls.g.isMobile() === true ){
					$(el).addClass('ls-forcehide');
					$(el).closest('.ls-wp-fullwidth-container').addClass('ls-forcehide');
					ls.o.autoStart = false;
				}else{
					if( $(window).width() < ls.o.hideUnder || $(window).width() > ls.o.hideOver ){
						$(el).addClass('ls-forcehide');
						$(el).closest('.ls-wp-fullwidth-container').addClass('ls-forcehide');
					}else{
						$(el).removeClass('ls-forcehide');
						$(el).closest('.ls-wp-fullwidth-container').removeClass('ls-forcehide');
					}
				}
			};

			$(window).resize( function(){

				showHide();
			});

			showHide();

			// NEW FEATURE v1.7 making the slider responsive

			ls.g.sliderWidth = function(){
				return $(el).width();
			}

			ls.g.sliderHeight = function(){
				return $(el).height();
			}

			// Compatibility mode v5.0.0
			//	.ls-layer 	-> .ls-slide
			//	.ls-s 		-> .ls-l

			$(el).find('.ls-layer').removeClass('ls-layer').addClass('ls-slide');
			$(el).find('.ls-slide > *[class*="ls-s"]').each(function(){
				var oldDistanceNum = $(this).attr('class').split('ls-s')[1].split(' ')[0];
				$(this).removeClass('ls-s'+oldDistanceNum).addClass('ls-l'+oldDistanceNum);
			});

			if( ls.o.firstLayer ){
				ls.o.firstSlide = ls.o.firstLayer;
			}
			if( ls.o.animateFirstLayer === false ){
				ls.o.animateFirstSlide = false;
			}

			// REPLACED FEATURE v2.0 If there is only ONE layer, instead of duplicating it, turning off slideshow and loops, hiding all controls, etc.

			if( $(el).find('.ls-slide').length == 1 ){
				ls.o.autoStart = false;
				ls.o.navPrevNext = false;
				ls.o.navStartStop = false;
				ls.o.navButtons = false;
				ls.o.loops = 0;
				ls.o.forceLoopNum = false;
				ls.o.autoPauseSlideshow	= true;
				ls.o.firstSlide = 1;
				ls.o.thumbnailNavigation = 'disabled';
			}

			// IMPROVEMENT v5.2.0 the original width of a full width slider should be always 100% even if the user forgot to set that value
			// BUGFIX v5.3.0 An additional check required (with the original improvement full-width sliders with "normal" responsiveness couldn't be created)

			if( $(el).parent().hasClass('ls-wp-fullwidth-helper') && ls.o.responsiveUnder !== 0 ){
				$(el)[0].style.width = '100%';
			}

			// NEW FEATURE v3.0 added "normal" responsive mode with image and font resizing
			// NEW FEATURE v3.5 responsiveUnder

			if( ls.o.width ){
				ls.g.sliderOriginalWidthRU = ls.g.sliderOriginalWidth = '' + ls.o.width;
			}else{
				ls.g.sliderOriginalWidthRU = ls.g.sliderOriginalWidth = $(el)[0].style.width;
			}

			if( ls.o.height ){
				ls.g.sliderOriginalHeight = '' + ls.o.height;
			}else{
				ls.g.sliderOriginalHeight = $(el)[0].style.height;
			}

			if( ls.g.sliderOriginalWidth.indexOf('%') == -1 && ls.g.sliderOriginalWidth.indexOf('px') == -1 ){
				ls.g.sliderOriginalWidth += 'px';
			}

			if( ls.g.sliderOriginalHeight.indexOf('%') == -1 && ls.g.sliderOriginalHeight.indexOf('px') == -1 ){
				ls.g.sliderOriginalHeight += 'px';
			}

			if( ls.o.responsive && ls.g.sliderOriginalWidth.indexOf('px') != -1 && ls.g.sliderOriginalHeight.indexOf('px') != -1 ){
				ls.g.responsiveMode = true;
			}else{
				ls.g.responsiveMode = false;
			}

			// NEW FEATURE v5.5.0 We must overwrite some user settings if fullScreen mode is enabled

			if( ls.o.fullScreen === true ){
				ls.o.responsiveUnder = 0;
				ls.g.responsiveMode = true;

				if( ls.g.sliderOriginalWidth.indexOf('%') != -1 ){
					ls.g.sliderOriginalWidth = parseInt( ls.g.sliderOriginalWidth) + 'px';
				}

				if( ls.g.sliderOriginalHeight.indexOf('%') != -1 ){
					ls.g.sliderOriginalHeight = parseInt( ls.g.sliderOriginalHeight) + 'px';
				}
			}

			// IMPROVEMENT v3.0 preventing WordPress to wrap your sublayers in <code> or <p> elements

			$(el).find('*[class*="ls-l"], *[class*="ls-bg"]').each(function(){
				if( !$(this).parent().hasClass('ls-slide') ){
					$(this).insertBefore( $(this).parent() );
				}
			});

			$(el).find('.ls-slide').each(function(){

				// Future Feature Saving Slide Index

				$(this).data( 'index', $(this).index() + 1 ).addClass( 'ls-slide-' + ( $(this).index() + 1 ) );

				$(this).children(':not([class*="ls-"])').each(function(){
					$(this).remove();
				});

				var hd = $('<div>').addClass('ls-gpuhack');
				if( $(this).find('.ls-bg').length ){
					hd.insertAfter( $(this).find('.ls-bg').eq('0') );
				}else{
					hd.prependTo( $(this) );
				}
			});

			$(el).find('.ls-slide, *[class*="ls-l"]').each(function(){

				if( $(this).data('ls') || $(this).attr('rel') || $(this).attr('style') ){
					if( $(this).data('ls') ){
						var params = $(this).data('ls').toLowerCase().split(';');
					}else if( $(this).attr('rel') && $(this).attr('rel').indexOf(':') != -1 && $(this).attr('rel').indexOf(';') != -1 ){
						var params = $(this).attr('rel').toLowerCase().split(';');
					}else{
						var params = $(this).attr('style').toLowerCase().split(';');
					}
					for(x=0;x<params.length;x++){
						param = params[x].split(':');

						if( param[0].indexOf('easing') != -1 ){
							param[1] = ls.ieEasing( param[1] );
						}

						var p2 = '';
						if( param[2] ){
							p2 = ':'+$.trim(param[2]);
						}

						if( param[0] != ' ' && param[0] != '' ){
							$(this).data( $.trim(param[0]), $.trim(param[1]) + p2 );
						}
					}
				}

				// NEW FEATURE v5.2.0 Starts the slider only if it is in the viewport

				if( ls.o.startInViewport === true && ls.o.autoStart === true ){

					ls.o.autoStart = false;
					ls.g.originalAutoStart = true;
				}

				// NEW FEATURE v1.7 and v3.0 making the slider responsive - we have to use style.left instead of jQuery's .css('left') function!

				var sl = $(this);

				sl.data( 'originalLeft', sl[0].style.left );
				sl.data( 'originalTop', sl[0].style.top );

				if( $(this).is('a') && $(this).children().length > 0 ){
					sl = $(this).children();
				}

				var _w = sl.width();
				var _h = sl.height();

				if( sl[0].style.width && sl[0].style.width.indexOf('%') != -1 ){
					_w = sl[0].style.width;
				}
				if( sl[0].style.height && sl[0].style.height.indexOf('%') != -1 ){
					_h = sl[0].style.height;
				}

				sl.data( 'originalWidth', _w );
				sl.data( 'originalHeight', _h );

				sl.data( 'originalPaddingLeft', sl.css('padding-left') );
				sl.data( 'originalPaddingRight', sl.css('padding-right') );
				sl.data( 'originalPaddingTop', sl.css('padding-top') );
				sl.data( 'originalPaddingBottom', sl.css('padding-bottom') );

				// iOS fade bug when GPU acceleration is enabled #1

				var _o = typeof parseFloat( sl.css('opacity') ) == 'number'  ? Math.round( parseFloat( sl.css('opacity') ) * 100 ) / 100  : 1;
				$(this).data( 'originalOpacity', _o );

				if( sl.css('border-left-width').indexOf('px') == -1 ){
					sl.data( 'originalBorderLeft', sl[0].style.borderLeftWidth );
				}else{
					sl.data( 'originalBorderLeft', sl.css('border-left-width') );
				}
				if( sl.css('border-right-width').indexOf('px') == -1 ){
					sl.data( 'originalBorderRight', sl[0].style.borderRightWidth );
				}else{
					sl.data( 'originalBorderRight', sl.css('border-right-width') );
				}
				if( sl.css('border-top-width').indexOf('px') == -1 ){
					sl.data( 'originalBorderTop', sl[0].style.borderTopWidth );
				}else{
					sl.data( 'originalBorderTop', sl.css('border-top-width') );
				}
				if( sl.css('border-bottom-width').indexOf('px') == -1 ){
					sl.data( 'originalBorderBottom', sl[0].style.borderBottomWidth );
				}else{
					sl.data( 'originalBorderBottom', sl.css('border-bottom-width') );
				}

				sl.data( 'originalFontSize', sl.css('font-size') );
				sl.data( 'originalLineHeight', sl.css('line-height') );
			});

			// CHANGED FEATURE v3.5 url- / deep linking layers

			if( document.location.hash ){
				for( var dl = 0; dl < $(el).find('.ls-slide').length; dl++ ){
					if( $(el).find('.ls-slide').eq(dl).data('deeplink') == document.location.hash.split('#')[1] ){
						ls.o.firstSlide = dl+1;
					}
				}
			}

			// NEW FEATURE v2.0 linkTo

			$(el).find('*[class*="ls-linkto-"]').each(function(){
				var lClasses = $(this).attr('class').split(' ');
				for( var ll=0; ll<lClasses.length; ll++ ){
					if( lClasses[ll].indexOf('ls-linkto-') != -1 ){
						var linkTo = parseInt( lClasses[ll].split('ls-linkto-')[1] );
						$(this).css({
							cursor: 'pointer'
						}).click(function(e){
							e.preventDefault();
							$(el).layerSlider( linkTo );
						});
					}
				}
			});

			// Setting variables

			ls.g.layersNum = $(el).find('.ls-slide').length;

			// NEW FEATURE v3.5 randomSlideshow

			if( ls.o.randomSlideshow && ls.g.layersNum > 2 ){
				ls.o.firstSlide == 'random';
				ls.o.twoWaySlideshow = false;
			}else{
				ls.o.randomSlideshow = false;
			}

			// NEW FEATURE v3.0 random firstSlide

			if( ls.o.firstSlide == 'random' ){
				ls.o.firstSlide = Math.floor(Math.random() * ls.g.layersNum+1);
			}

			ls.o.fisrtSlide = ls.o.fisrtSlide < ls.g.layersNum + 1 ? ls.o.fisrtSlide : 1;
			ls.o.fisrtSlide = ls.o.fisrtSlide < 1 ? 1 : ls.o.fisrtSlide;

			// NEW FEATURE v2.0 loops

			ls.g.nextLoop = 1;

			if( ls.o.animateFirstSlide ){
				ls.g.nextLoop = 0;
			}

			// NEW FEATURE v2.0 videoPreview

			ls.media.youtube.init();
			ls.media.vimeo.init();
			ls.media.html5.init();

			// NEW FEATURE v1.7 animating first layer

			if( ls.o.animateFirstSlide ){
				ls.o.firstSlide = ls.o.firstSlide - 1 === 0 ? ls.g.layersNum : ls.o.firstSlide-1;
			}

			ls.g.curLayerIndex = ls.o.firstSlide;
			ls.g.curLayer = $(el).find('.ls-slide:eq('+(ls.g.curLayerIndex-1)+')');

			// Moving all layers to .ls-inner container

			$(el).find('.ls-slide').wrapAll('<div class="ls-inner"></div>');
			ls.g.i = $(el).find('.ls-inner');

			// NEW FEATURE v4.5.0 Timers

			if( ls.o.showBarTimer ){
				ls.g.barTimer = $('<div>').addClass('ls-bar-timer').appendTo( ls.g.i );
			}

			if( ls.o.showCircleTimer && !ls.g.ie78 ){
				ls.g.circleTimer = $('<div>').addClass('ls-circle-timer').appendTo( ls.g.i );
				ls.g.circleTimer.append( $('<div class="ls-ct-left"><div class="ls-ct-rotate"><div class="ls-ct-hider"><div class="ls-ct-half"></div></div></div></div><div class="ls-ct-right"><div class="ls-ct-rotate"><div class="ls-ct-hider"><div class="ls-ct-half"></div></div></div></div><div class="ls-ct-center"></div>') );
			}

			// NEW FEATURE v4.0 Adding loading indicator into the element

			ls.g.li = $('<div>').css({
				zIndex: -1,
				display: 'none'
			}).addClass('ls-loading-container').appendTo( $(el) );

			$('<div>').addClass('ls-loading-indicator').appendTo( ls.g.li );

			// Adding styles

			if( $(el).css('position') == 'static' ){
				$(el).css('position','relative');
			}

			// IMPROVEMENT & BUGFIX v4.6.0 Fixed transparent global background issue under IE7 & IE8

			if( ls.o.globalBGImage ){
				ls.g.i.css({
					backgroundImage : 'url('+ls.o.globalBGImage+')'
				});
			}else{
				ls.g.i.css({
					backgroundColor : ls.o.globalBGColor
				});
			}

			if( ls.o.globalBGColor == 'transparent' && ls.o.globalBGImage == false ){
				ls.g.i.css({
					background : 'none transparent !important'
				});
			}

			// NEW FEATURES v5.0.0 Lazy-load & remove unnecessary width & height attributes from images

			$(el).find('.ls-slide img').each(function(){

				$(this).removeAttr('width').removeAttr('height');

				if( ls.o.imgPreload === true && ls.o.lazyLoad === true ){

					if( typeof $(this).data('src') !== 'string' ){

						$(this).data('src', $(this).attr('src') );
						var src = ls.o.skinsPath+'../css/blank.gif';
						$(this).attr('src',src);
					}
				}else{
					if( typeof $(this).data('src') === 'string' ){

						$(this).attr('src',$(this).data('src'));
						$(this).removeAttr('data-src');
					}
				}

			});

			// NEW FEATURE v5.0.0 Parallax layers by mousemove

			var parallaxLayers = $([]);

			$(el).find('*:not(.ls-bg)').each(function(){

					if( typeof $(this).data('parallaxlevel') !== 'undefined' && parseInt( $(this).data('parallaxlevel') ) !== 0 ){

						parallaxLayers = parallaxLayers.add( $(this) );
					}
				});


			ls.g.i.on('mouseenter',function(e){

				ls.g.parallaxStartX = e.pageX - $(this).parent().offset().left;
				ls.g.parallaxStartY = e.pageY - $(this).parent().offset().top;
			});

			ls.g.i.on('mousemove',function(e){

				var mX0 = $(this).parent().offset().left + ls.g.parallaxStartX;
				var mY0 = $(this).parent().offset().top + ls.g.parallaxStartY;

				var mX = e.pageX - mX0;
				var mY = e.pageY - mY0;

				parallaxLayers.each(function(){

					$(this).css({
						marginLeft : -mX / 100 * parseInt( $(this).data('parallaxlevel') ),
						marginTop : -mY / 100 * parseInt( $(this).data('parallaxlevel') )
					});
				});
			});

			ls.g.i.on('mouseleave',function(){

				parallaxLayers.each(function(){

					TweenLite.to( this, .4, {
						css:{
							marginLeft : 0,
							marginTop : 0
						}
					});
				});
			});

			// Creating navigation

			if( ls.o.navPrevNext ){

			    $('<a class="ls-nav-prev" href="#"><span class="sr-only">Previous Slide</span></a>').click(function (e) {
					e.preventDefault();
					$(el).layerSlider('prev');
				}).appendTo($(el));

			    $('<a class="ls-nav-next" href="#"><span class="sr-only">Next Slide</span></a>').click(function (e) {
					e.preventDefault();
					$(el).layerSlider('next');
				}).appendTo($(el));

				if( ls.o.hoverPrevNext ){
					$(el).find('.ls-nav-prev, .ls-nav-next').css({
						display: 'none'
					});

					$(el).hover(
						function(){
 							if( !ls.g.forceHideControls ){
								if( ls.g.ie78 ){
									$(el).find('.ls-nav-prev, .ls-nav-next').css('display','block');
								}else{
									$(el).find('.ls-nav-prev, .ls-nav-next').stop(true,true).fadeIn(300);
								}
							}
						},
						function(){
							if( ls.g.ie78 ){
								$(el).find('.ls-nav-prev, .ls-nav-next').css('display','none');
							}else{
								$(el).find('.ls-nav-prev, .ls-nav-next').stop(true,true).fadeOut(300);
							}
						}
					);
				}
			}

			// Creating bottom navigation

			if( ls.o.navStartStop || ls.o.navButtons ){

				var bottomNav = $('<div class="ls-bottom-nav-wrapper" />').appendTo( $(el) );

				ls.g.bottomWrapper = bottomNav;

				if( ls.o.thumbnailNavigation == 'always' ){
					bottomNav.addClass('ls-above-thumbnails');
				}

				if( ls.o.navButtons && ls.o.thumbnailNavigation != 'always' ){

					$('<span class="ls-bottom-slidebuttons" />').appendTo( $(el).find('.ls-bottom-nav-wrapper') );

					// NEW FEATURE v3.5 thumbnailNavigation ('hover')

					if( ls.o.thumbnailNavigation == 'hover' ){

						var thumbs = $('<div class="ls-thumbnail-hover"><div class="ls-thumbnail-hover-inner"><div class="ls-thumbnail-hover-bg"></div><div class="ls-thumbnail-hover-img"><img></div><span></span></div></div>').appendTo( $(el).find('.ls-bottom-slidebuttons') );
					}

					for(x=1;x<ls.g.layersNum+1;x++){

						var btn = $('<a href="#"><span class="sr-only">Slide ' + x + '</span></a>').appendTo( $(el).find('.ls-bottom-slidebuttons') ).click(function(e){
							e.preventDefault();
							$(el).layerSlider( ($(this).index() + 1) );
						});

						// NEW FEATURE v3.5 thumbnailNavigation ('hover')

						if( ls.o.thumbnailNavigation == 'hover' ){

							$(el).find('.ls-thumbnail-hover, .ls-thumbnail-hover-img').css({
								width : ls.o.tnWidth,
								height : ls.o.tnHeight
							});

							var th = $(el).find('.ls-thumbnail-hover');

							var ti = th.find('img').css({
								height : ls.o.tnHeight
							});

							var thi = $(el).find('.ls-thumbnail-hover-inner').css({
								visibility : 'hidden',
								display: 'block'
							});

							btn.hover(
								function(){

									var hoverLayer = $(el).find('.ls-slide').eq( $(this).index() );
									var tnSrc;

									if( ls.o.imgPreload === true && ls.o.lazyLoad === true ){

										if( hoverLayer.find('.ls-tn').length ){
											tnSrc = hoverLayer.find('.ls-tn').data('src');
										}else if( hoverLayer.find('.ls-videopreview').length ){

											// BUGFIX v5.6.0 YouTube video thumbnails have not been loaded until the previous slide

											tnSrc = hoverLayer.find('.ls-videopreview').attr('src');

										}else if( hoverLayer.find('.ls-bg').length ){
											tnSrc = hoverLayer.find('.ls-bg').data('src');
										}else{
											tnSrc = ls.o.skinsPath+ls.o.skin+'/nothumb.png';
										}
									}else{

										if( hoverLayer.find('.ls-tn').length ){
											tnSrc = hoverLayer.find('.ls-tn').attr('src');
										}else if( hoverLayer.find('.ls-videopreview').length ){
											tnSrc = hoverLayer.find('.ls-videopreview').attr('src');
										}else if( hoverLayer.find('.ls-bg').length ){
											tnSrc = hoverLayer.find('.ls-bg').attr('src');
										}else{
											tnSrc = ls.o.skinsPath+ls.o.skin+'/nothumb.png';
										}
									}

									$(el).find('.ls-thumbnail-hover-img').css({
										left: parseInt( th.css('padding-left') ),
										top: parseInt( th.css('padding-top') )
									});

									ti.load(function(){

										if( $(this).width() == 0 ){
											ti.css({
												position: 'relative',
												margin: '0 auto',
												left: 'auto'
											});
										}else{
											ti.css({
												position: 'absolute',
												marginLeft : - $(this).width() / 2,
												left: '50%'
											});
										}
									}).attr( 'src', tnSrc );

									th.css({
										display: 'block'
									}).stop().animate({
										left: $(this).position().left + ( $(this).width() - th.outerWidth() ) / 2
									}, 250 );

									thi.css({
										display : 'none',
										visibility : 'visible'
									}).stop().fadeIn(250);
								},
								function(){
									thi.stop().fadeOut(250, function(){
										th.css({
											visibility : 'hidden',
											display: 'block'
										});
									});
								}
							);
						}
					}

					if( ls.o.thumbnailNavigation == 'hover' ){

						thumbs.appendTo( $(el).find('.ls-bottom-slidebuttons') );
					}

					$(el).find('.ls-bottom-slidebuttons a:eq('+(ls.o.firstSlide-1)+')').addClass('ls-nav-active');
				}

				if( ls.o.navStartStop ){

				    var buttonStart = $('<a class="ls-nav-start" href="#"><span class="sr-only">Start Slideshow</span></a>').click(function (e) {
						e.preventDefault();
						$(el).layerSlider('start');
					}).prependTo( $(el).find('.ls-bottom-nav-wrapper') );

				    var buttonStop = $('<a class="ls-nav-stop" href="#"><span class="sr-only">Stop Slideshow</span></a>').click(function (e) {
						e.preventDefault();
						$(el).layerSlider('stop');
					}).appendTo( $(el).find('.ls-bottom-nav-wrapper') );

				}else if( ls.o.thumbnailNavigation != 'always' ){

					$('<span class="ls-nav-sides ls-nav-sideleft" />').prependTo( $(el).find('.ls-bottom-nav-wrapper') );
					$('<span class="ls-nav-sides ls-nav-sideright" />').appendTo( $(el).find('.ls-bottom-nav-wrapper') );
				}

				if( ls.o.hoverBottomNav && ls.o.thumbnailNavigation != 'always' ){

					bottomNav.css({
						display: 'none'
					});

					$(el).hover(
						function(){
							if( !ls.g.forceHideControls ){
								if( ls.g.ie78 ){
									bottomNav.css('display','block');
								}else{
									bottomNav.stop(true,true).fadeIn(300);
								}
							}
						},
						function(){
							if( ls.g.ie78 ){
								bottomNav.css('display','none');
							}else{
								bottomNav.stop(true,true).fadeOut(300);
							}
						}
					)
				}
			}

			// NEW FEATURE v3x.5 thumbnailNavigation ('always')

			if( ls.o.thumbnailNavigation == 'always' ){

				ls.g.thumbsWrapper = $('<div class="ls-thumbnail-wrapper"></div>').appendTo( $(el) );
				var thumbs = $('<div class="ls-thumbnail"><div class="ls-thumbnail-inner"><div class="ls-thumbnail-slide-container"><div class="ls-thumbnail-slide"></div></div></div></div>').appendTo( ls.g.thumbsWrapper );

				ls.g.thumbnails = $(el).find('.ls-thumbnail-slide-container');

				if( !('ontouchstart' in window) ){
					ls.g.thumbnails.hover(
						function(){
							$(this).addClass('ls-thumbnail-slide-hover');
						},
						function(){
							$(this).removeClass('ls-thumbnail-slide-hover');
							ls.scrollThumb();
						}
					).mousemove(function(e){

						var mL = parseInt(e.pageX - $(this).offset().left ) / $(this).width() * ( $(this).width() - $(this).find('.ls-thumbnail-slide').width() );
						$(this).find('.ls-thumbnail-slide').stop().css({
							marginLeft : mL
						});
					});
				}else{
					ls.g.thumbnails.addClass('ls-touchscroll');
				}

				$(el).find('.ls-slide').each(function(){

					var tempIndex = $(this).index() + 1;
					var tnSrc;

					if( ls.o.imgPreload === true && ls.o.lazyLoad === true ){

						if( $(this).find('.ls-tn').length ){
							tnSrc = $(this).find('.ls-tn').data('src');
						}else if( $(this).find('.ls-videopreview').length ){
							tnSrc = $(this).find('.ls-videopreview').attr('src');
						}else if( $(this).find('.ls-bg').length ){
							tnSrc = $(this).find('.ls-bg').data('src');
						}else{
							tnSrc = ls.o.skinsPath+ls.o.skin+'/nothumb.png';
						}
					}else{

						if( $(this).find('.ls-tn').length ){
							tnSrc = $(this).find('.ls-tn').attr('src');
						}else if( $(this).find('.ls-videopreview').length ){
							tnSrc = $(this).find('.ls-videopreview').attr('src');
						}else if( $(this).find('.ls-bg').length ){
							tnSrc = $(this).find('.ls-bg').attr('src');
						}else{
							tnSrc = ls.o.skinsPath+ls.o.skin+'/nothumb.png';
						}
					}

					var thumb = $('<a href="#" class="ls-thumb-' + tempIndex + '"><img src="'+tnSrc+'"><span class="sr-only">Ad Slide</span></a>');
					thumb.appendTo( $(el).find('.ls-thumbnail-slide') );

					if( !('ontouchstart' in window) ){

						thumb.hover(
							function(){
								$(this).children().stop().fadeTo(300,ls.o.tnActiveOpacity/100);
							},
							function(){
								if( !$(this).children().hasClass('ls-thumb-active') ){
									$(this).children().stop().fadeTo(300,ls.o.tnInactiveOpacity/100);
								}
							}
						);
					}

					thumb.click(function(e){
						e.preventDefault();
						$(el).layerSlider( tempIndex );
					});
				});

				if( buttonStart && buttonStop ){
					var lsBottomBelowTN = ls.g.bottomWrapper = $('<div class="ls-bottom-nav-wrapper ls-below-thumbnails"></div>').appendTo( $(el) );
					buttonStart.clone().click(function(e){
						e.preventDefault();
						$(el).layerSlider('start');
					}).appendTo( lsBottomBelowTN );
					buttonStop.clone().click(function(e){
						e.preventDefault();
						$(el).layerSlider('stop');
					}).appendTo( lsBottomBelowTN );
				}

				if( ls.o.hoverBottomNav ){

					ls.g.thumbsWrapper.css('display','none');

					if( lsBottomBelowTN ){
						ls.g.bottomWrapper = lsBottomBelowTN.css('display') == 'block' ? lsBottomBelowTN : $(el).find('.ls-above-thumbnails');
						ls.g.bottomWrapper.css('display','none');
					}

					// BUGFIXES v4.1.3 Added checking of the bottomWrapper variable

					$(el).hover(
						function(){
							$(el).addClass('ls-hover');
							if( !ls.g.forceHideControls ){
								if( ls.g.ie78 ){
									ls.g.thumbsWrapper.css('display','block');
									if( ls.g.bottomWrapper ){
										ls.g.bottomWrapper.css('display','block');
									}
								}else{
									ls.g.thumbsWrapper.stop(true,true).fadeIn(300);
									if( ls.g.bottomWrapper ){
										ls.g.bottomWrapper.stop(true,true).fadeIn(300);
									}
								}
							}
						},
						function(){
							$(el).removeClass('ls-hover');
							if( ls.g.ie78 ){
								ls.g.thumbsWrapper.css('display','none');
								if( ls.g.bottomWrapper ){
									ls.g.bottomWrapper.css('display','none');
								}
							}else{
								ls.g.thumbsWrapper.stop(true,true).fadeOut(300);
								if( ls.g.bottomWrapper ){
									ls.g.bottomWrapper.stop(true,true).fadeOut(300);
								}
							}
						}
					)
				}
			}

			// Adding shadow wrapper

			ls.g.shadow = $('<div class="ls-shadow"></div>').appendTo( $(el) );
			if( ls.g.shadow.css('display') == 'block' && !ls.g.shadow.find('img').length ){
				ls.g.showShadow = function(){
					ls.g.shadow.css({
						display: 'none',
						visibility: 'visible'
					}).fadeIn( 500, function(){
						ls.g.showShadow = false;
					});
				}
				ls.g.shadowImg = $('<img>').attr('src',ls.o.skinsPath+ls.o.skin+'/shadow.png').appendTo( ls.g.shadow );
				ls.g.shadowBtmMod = typeof parseInt( $(el).css('padding-bottom') ) == 'number' ? parseInt( $(el).css('padding-bottom') ) : 0;
			}
			ls.resizeShadow();

			// Adding keyboard navigation if turned on and if number of layers > 1

			if( ls.o.keybNav && $(el).find('.ls-slide').length > 1 ){

				$('body').bind('keydown',function(e){
					if( !ls.g.isAnimating && !ls.g.isLoading ){
						if( e.which == 37 ){
							ls.o.cbPrev(ls.g);
							ls.prev('clicked');
						}else if( e.which == 39 ){
							ls.o.cbNext(ls.g);
							ls.next('clicked');
						}
					}
				});
			}

			// Adding touch-control navigation if number of layers > 1

			if('ontouchstart' in window && $(el).find('.ls-slide').length > 1 && ls.o.touchNav ){

			   ls.g.i.bind('touchstart', function( e ) {
					var t = e.touches ? e.touches : e.originalEvent.touches;
					if( t.length == 1 ){
						ls.g.touchStartX = ls.g.touchEndX = t[0].clientX;
					}
			    });

			   ls.g.i.bind('touchmove', function( e ) {
					var t = e.touches ? e.touches : e.originalEvent.touches;
					if( t.length == 1 ){
						ls.g.touchEndX = t[0].clientX;
					}
					if( Math.abs( ls.g.touchStartX - ls.g.touchEndX ) > 45 ){
						e.preventDefault();
					}
			    });

				ls.g.i.bind('touchend',function( e ){
					if( Math.abs( ls.g.touchStartX - ls.g.touchEndX ) > 45 ){
						if( ls.g.touchStartX - ls.g.touchEndX > 0 ){
							ls.o.cbNext(ls.g);
							$(el).layerSlider('next');
						}else{
							ls.o.cbPrev(ls.g);
							$(el).layerSlider('prev');
						}
					}
				});
			}

			// Feature: pauseOnHover (if number of layers > 1)

			if( ls.o.pauseOnHover == true && $(el).find('.ls-slide').length > 1 ){

				// BUGFIX v1.6 stop was not working because of pause on hover

				ls.g.i.hover(
					function(){

						// Calling cbPause callback function

						ls.o.cbPause(ls.g);
						if( ls.g.autoSlideshow ){
							ls.g.paused = true;
							ls.stop();

							// Stopping the animation of Timers

							if( ls.g.barTimer ){
								ls.g.barTimer.stop();
							}

							if( ls.g.circleTimer ){
								if( ls.g.cttl ){
									ls.g.cttl.pause();
								}
							}
							ls.g.pausedSlideTime = new Date().getTime();
						}
					},
					function(){
						if( ls.g.paused == true ){
							ls.start();
							ls.g.paused = false;
						}
					}
				);
			}

			ls.resizeSlider();

			// NEW FEATURE v1.7 added yourLogo

			if( ls.o.yourLogo ){
				ls.g.yourLogo = $('<img>').addClass('ls-yourlogo').appendTo($(el)).attr('style', ls.o.yourLogoStyle ).css({
					visibility: 'hidden',
					display: 'bock'
				}).load(function(){

					// NEW FEATURE v3.0 added responsive yourLogo

					var logoTimeout = 0;

					if( !ls.g.yourLogo ){
						logoTimeout = 1000;
					}

					setTimeout( function(){

						ls.g.yourLogo.data( 'originalWidth', ls.g.yourLogo.width() );
						ls.g.yourLogo.data( 'originalHeight', ls.g.yourLogo.height() );
						if( ls.g.yourLogo.css('left') != 'auto' ){
							ls.g.yourLogo.data( 'originalLeft', ls.g.yourLogo[0].style.left );
						}
						if( ls.g.yourLogo.css('right') != 'auto' ){
							ls.g.yourLogo.data( 'originalRight', ls.g.yourLogo[0].style.right );
						}
						if( ls.g.yourLogo.css('top') != 'auto' ){
							ls.g.yourLogo.data( 'originalTop', ls.g.yourLogo[0].style.top );
						}
						if( ls.g.yourLogo.css('bottom') != 'auto' ){
							ls.g.yourLogo.data( 'originalBottom', ls.g.yourLogo[0].style.bottom );
						}

						// NEW FEATURES v1.8 added yourLogoLink & yourLogoTarget

						if( ls.o.yourLogoLink != false ){
							$('<a>').appendTo($(el)).attr( 'href', ls.o.yourLogoLink ).attr('target', ls.o.yourLogoTarget ).css({
								textDecoration : 'none',
								outline : 'none'
							}).append( ls.g.yourLogo );
						}

						ls.g.yourLogo.css({
							display: 'none',
							visibility: 'visible'
						});

						ls.resizeYourLogo();

					}, logoTimeout );

				}).attr( 'src', ls.o.yourLogo );
			}

			// NEW FEATURE v1.7 added window resize function for make responsive layout better

			$(window).resize(function(){

				ls.resize();
			});

			// BUGFIX v5.3.0 Responsiveness not worked in some cases while changed orientation on mobile devices

			$(window).on('orientationchange',function(){

				$(window).resize();
			});

			ls.g.showSlider = true;

			// NEW FEATURE v1.7 animating first slide

			if( ls.o.animateFirstSlide == true ){
				if( ls.o.autoStart ){
					ls.g.autoSlideshow = true;
					$(el).find('.ls-nav-start').addClass('ls-nav-start-active');
				}else{
					$(el).find('.ls-nav-stop').addClass('ls-nav-stop-active');
				}
				ls.next();
			}else if( typeof ls.g.curLayer[0] !== 'undefined' ){
				ls.imgPreload(ls.g.curLayer,function(){
					ls.g.curLayer.fadeIn(ls.o.sliderFadeInDuration, function(){

						ls.g.isLoading = false;

						$(this).addClass('ls-active');

						// NEW FEATURE v2.0 autoPlayVideos

						if( ls.o.autoPlayVideos ){
							$(this).delay( $(this).data('delayin') + 25 ).queue(function(){

								// YouTube & Vimeo videos

								$(this).find('.ls-videopreview').click();

								// HTML5 videos

								$(this).find('video, audio').each(function(){
									if( typeof $(this)[0].currentTime !== 0){
										$(this)[0].currentTime = 0;
									}
									$(this).click();
								});

								$(this).dequeue();
							});
						}

						// NEW FEATURE v3.0 showUntil sublayers

						ls.g.curLayer.find(' > *[class*="ls-l"]').each(function(){

							// Setting showUntilTimers

							var cursub = $(this);

							// IMPROVEMENT v5.2.0 video layers with auto play will skip showuntil feature

							if( ( !cursub.hasClass('ls-video-layer') || ( cursub.hasClass('ls-video-layer') && ls.o.autoPlayVideos === false ) ) && cursub.data('showuntil') > 0 ){

								// IMPROVEMENT v4.5.0 sublayerShowUntil will be called anly if necessary

								cursub.data('showUntilTimer', setTimeout(function(){
									ls.sublayerShowUntil( cursub );
								}, cursub.data('showuntil') ));
							}
						});
					});

					ls.changeThumb(ls.g.curLayerIndex)

					// If autoStart is true

					if( ls.o.autoStart ){
						ls.g.isLoading = false;
						ls.start();
					}else{
						$(el).find('.ls-nav-stop').addClass('ls-nav-stop-active');
					}
				});
			}

			// NEW FEATURE v1.7 added cbInit function

			ls.o.cbInit($(el));
		};

		ls.resize = function(){

				ls.g.resize = true;

				if( !ls.g.isAnimating ){

					ls.makeResponsive( ls.g.curLayer, function(){
						if( ls.g.ltContainer ){
							ls.g.ltContainer.empty();
						}
						ls.g.resize = false;
					});
					if( ls.g.yourLogo ){
						ls.resizeYourLogo();
					}
				}
		};

		ls.start = function(){

			if( ls.g.autoSlideshow ){
				if( ls.g.prevNext == 'prev' && ls.o.twoWaySlideshow ){
					ls.prev();
				}else{
					ls.next();
				}
			}else{
				ls.g.autoSlideshow = true;
				if( !ls.g.isAnimating && !ls.g.isLoading ){
					ls.timer();
				}
			}

			$(el).find('.ls-nav-start').addClass('ls-nav-start-active');
			$(el).find('.ls-nav-stop').removeClass('ls-nav-stop-active');
		};

		ls.timer = function(){

			if( $(el).find('.ls-active').data('ls') ){
				var sD = ls.st.slideDelay;
			}else{
				var sD = ls.o.slideDelay;
			}

			var delaytime = $(el).find('.ls-active').data('slidedelay') ? parseInt( $(el).find('.ls-active').data('slidedelay') ) : sD;

			// BUGFIX v3.0 delaytime did not work on first layer if animateFirstSlide was set to off
			// BUGFIX v3.5 delaytime did not work on all layers in standalone version after bugfix 3.0 :)

			if( !ls.o.animateFirstSlide && !$(el).find('.ls-active').data('slidedelay') ){
				var tempD = $(el).find('.ls-slide:eq('+(ls.o.firstSlide-1)+')').data('slidedelay');
				delaytime = tempD ? tempD : sD;
			}

			clearTimeout( ls.g.slideTimer );

			// NEW FEATURE v4.5.0 Timers

			if( ls.g.pausedSlideTime ){
				if( !ls.g.startSlideTime ){
					ls.g.startSlideTime = new Date().getTime();
				}
				if( ls.g.startSlideTime > ls.g.pausedSlideTime ){
					ls.g.pausedSlideTime =  new Date().getTime();
				}
				if(! ls.g.curSlideTime ){
					ls.g.curSlideTime = delaytime;
				}
				ls.g.curSlideTime -= (ls.g.pausedSlideTime - ls.g.startSlideTime);
				ls.g.pausedSlideTime = false;
				ls.g.startSlideTime = new Date().getTime();
			}else{
				ls.g.curSlideTime = delaytime;
				ls.g.startSlideTime = new Date().getTime();
			}

			// BUGFIX v4.6.0 fixed Bar Timer animation on the fisrt slide if animateFirstSlide is false

			ls.g.curSlideTime = parseInt( ls.g.curSlideTime );

			ls.g.slideTimer = setTimeout(function(){
				ls.g.startSlideTime = ls.g.pausedSlideTime = ls.g.curSlideTime = false;
				ls.start();
			}, ls.g.curSlideTime );

			// Animating Timers

			if( ls.g.barTimer ){
				ls.g.barTimer.animate({
					width : ls.g.sliderWidth()
				}, ls.g.curSlideTime, 'linear', function(){
					$(this).css({
						width: 0
					});
				});
			}

			if( ls.g.circleTimer ){

				var ct1 = ls.g.circleTimer.find('.ls-ct-right .ls-ct-rotate');
				var ct2 = ls.g.circleTimer.find('.ls-ct-left .ls-ct-rotate');

				if( ls.g.circleTimer.css('display') == 'none' ){

					ct1.css({
						rotate : 0
					});

					ct2.css({
						rotate : 0
					});

					ls.g.circleTimer.fadeIn(350);
				}

				if( !ls.g.cttl ){
					ls.g.cttl = new TimelineLite();
					ls.g.cttl.add( TweenLite.fromTo(ct1[0],delaytime/2000,{
						rotation : 0
					},{
						ease : Linear.easeNone,
						rotation : 180,
						onReverseComplete : function(){
							ls.g.cttl = false;
						}
					}));
					ls.g.cttl.add( TweenLite.fromTo(ct2[0],delaytime/2000,{
						rotation : 0
					},{
						ease : Linear.easeNone,
						rotation : 180
					}));
				}else{
					ls.g.cttl.resume();
				}

			}
		};

		ls.stop = function(){

			// Stopping Timers

			ls.g.pausedSlideTime = new Date().getTime();

			if( ls.g.barTimer ){
				ls.g.barTimer.stop();
			}

			if( ls.g.circleTimer ){
				if( ls.g.cttl ){
					ls.g.cttl.pause();
				}
			}

			if( !ls.g.paused && !ls.g.originalAutoSlideshow ){
				$(el).find('.ls-nav-stop').addClass('ls-nav-stop-active');
				$(el).find('.ls-nav-start').removeClass('ls-nav-start-active');
			}
			clearTimeout( ls.g.slideTimer );
			ls.g.autoSlideshow = false;
		};

		ls.forcestop = function(){

			clearTimeout( ls.g.slideTimer );
			ls.g.autoSlideshow = false;

			clearTimeout( ls.g.t1 );
			clearTimeout( ls.g.t2 );
			clearTimeout( ls.g.t3 );
			clearTimeout( ls.g.t4 );
			clearTimeout( ls.g.t5 );

			if( ls.g.barTimer ){
				ls.g.barTimer.stop();
			}

			if( ls.g.circleTimer ){
				if( ls.g.cttl ){
					ls.g.cttl.pause();
				}
			}

			$(el).find('*').stop(true,false).dequeue();
			$(el).find('.ls-slide >').each(function(){
				if( $(this).data('tr') ){
					$(this).data('tr').pause();
				}
			});

			if( !ls.g.paused && !ls.g.originalAutoSlideshow ){
				$(el).find('.ls-nav-stop').addClass('ls-nav-stop-active');
				$(el).find('.ls-nav-start').removeClass('ls-nav-start-active');
			}
		};

		ls.restart = function(){

			$(el).find('*').stop();
			clearTimeout( ls.g.slideTimer );
			ls.change(ls.g.curLayerIndex,ls.g.prevNext);
		};

		// Because of an ie7 bug, we have to check & format the strings correctly

		ls.ieEasing = function( e ){

			// BUGFIX v1.6 and v1.8 some type of animations didn't work properly

			if( $.trim(e.toLowerCase()) == 'swing' || $.trim(e.toLowerCase()) == 'linear'){
				return e.toLowerCase();
			}else{
				return e.replace('easeinout','easeInOut').replace('easein','easeIn').replace('easeout','easeOut').replace('quad','Quad').replace('quart','Quart').replace('cubic','Cubic').replace('quint','Quint').replace('sine','Sine').replace('expo','Expo').replace('circ','Circ').replace('elastic','Elastic').replace('back','Back').replace('bounce','Bounce');
			}
		};

		// Calculating prev layer

		ls.prev = function(clicked){

			// NEW FEATURE v2.0 loops

			if( ls.g.curLayerIndex < 2 ){
				ls.g.nextLoop += 1;
			}

			if( ( ls.g.nextLoop > ls.o.loops ) && ( ls.o.loops > 0 ) && !clicked ){
				ls.g.nextLoop = 0;
				ls.stop();
				if( ls.o.forceLoopNum == false ){
					ls.o.loops = 0;
				}
			}else{
				var prev = ls.g.curLayerIndex < 2 ? ls.g.layersNum : ls.g.curLayerIndex - 1;
				ls.g.prevNext = 'prev';
				ls.change(prev,ls.g.prevNext);
			}
		};

		// Calculating next layer

		ls.next = function(clicked){

			// NEW FEATURE v2.0 loops

			if( !ls.o.randomSlideshow ){

				if( !(ls.g.curLayerIndex < ls.g.layersNum) ){
					ls.g.nextLoop += 1;
				}

				if( ( ls.g.nextLoop > ls.o.loops ) && ( ls.o.loops > 0 ) && !clicked ){

					ls.g.nextLoop = 0;
					ls.stop();
					if( ls.o.forceLoopNum == false ){
						ls.o.loops = 0;
					}
				}else{

					var next = ls.g.curLayerIndex < ls.g.layersNum ? ls.g.curLayerIndex + 1 : 1;
					ls.g.prevNext = 'next';
					ls.change(next,ls.g.prevNext);
				}
			}else if( !clicked ){

				// NEW FEATURE v3.5 randomSlideshow

				var next = ls.g.curLayerIndex;

				var calcRand = function(){

					next = Math.floor(Math.random() * ls.g.layersNum) + 1;

					if( next == ls.g.curLayerIndex ){

						calcRand();
					}else{
						ls.g.prevNext = 'next';
						ls.change(next,ls.g.prevNext);
					}
				}

				calcRand();
			}else if( clicked ){

				var next = ls.g.curLayerIndex < ls.g.layersNum ? ls.g.curLayerIndex + 1 : 1;
				ls.g.prevNext = 'next';
				ls.change(next,ls.g.prevNext);
			}

		};

		// ls.media > EMBEDDED VIDEO & AUDIO FUNCTIONS > added in v5.6.0

		ls.media = {

			youtube : {

				// BUGFIX v5.6.0 Fixed YouTube Iframe Player API issue

				init : function(){

					// IMPROVEMENT v4.6.0 http / https support of embedded videos

					var HTTP = document.location.href.indexOf('file:') === -1 ? '' : 'http:';

					// Youtube videos

					var youTube = $(el).find('iframe[src*="youtube.com"], iframe[src*="youtu.be"]');

					// UPDATE v5.5.0 Changed to YouTube iFrame Player API 3.0

					if( youTube.length ){

						$('<script>').attr({
							'src' : HTTP + '//www.youtube.com/iframe_api',
							'type' : 'text/javascript'
						}).appendTo('head');

						var numOfYouTube = youTube.length;

						window.onYouTubeIframeAPIReady = function(){

							youTube.each(function(){

								// BUGFIX v4.1.0 Firefox embedded video fix

								$(this).parent().addClass('ls-video-layer');

								if( $(this).parent('[class*="ls-l"]') ){

									var http = HTTP;

									var vpContainer = $('<div>').addClass('ls-vpcontainer').appendTo( $(this).parent() );

									$('<img>').appendTo( vpContainer ).addClass('ls-videopreview').attr('alt', 'Play video').attr('src',  http + '//img.youtube.com/vi/' + $(this).attr('src').split('embed/')[1].split('?')[0] + '/' + ls.o.youtubePreview );

									$('<div>').appendTo( vpContainer ).addClass('ls-playvideo');

									$(this).parent().css({
										width : $(this).width(),
										height : $(this).height()
									}).click(function(){

										var iframe = $(this).find('iframe');

										iframe.css('display','block');

										// IMPROVEMENT v5.2.0 if video playing is in progress, video layers with auto play will skip showuntil feature

										if( $(this).data('showuntil') > 0 && $(this).data('showUntilTimer') ){
											clearTimeout( $(this).data('showUntilTimer') );
										}

										if( !ls.g.pausedByVideo ){

											ls.g.isAnimating = true;

											if( ls.g.paused ){
												if( ls.o.autoPauseSlideshow != false ){
													ls.g.paused = false;
												}
												ls.g.originalAutoSlideshow = true;
											}else{
												ls.g.originalAutoSlideshow = ls.g.autoSlideshow;
											}

											if( ls.o.autoPauseSlideshow != false ){
												ls.stop();
											}

											ls.g.pausedByVideo = true;
										}

										if( typeof iframe.data('ytplayer') == 'undefined' ){

											iframe.attr('src', src );

											var videoEnded = function(event){
												if( event.data === 0 ){
													ls.g.numYouTubeCurSlide += 1;
													if( ls.o.autoPauseSlideshow == 'auto' && ls.g.originalAutoSlideshow == true ){
														if( ls.g.numYouTubeCurSlide == ls.g.curLayer.find('iframe[src*="youtube.com"], iframe[src*="youtu.be"]').length ){
															ls.g.curSlideTime = 1;
															ls.start();
														}
													}
												}
											}

											var onPlayerReady = function(event){
												event.target.playVideo();
											}

											iframe.data('ytplayer', new YT.Player( iframe[0], {
												events : {
													'onReady': onPlayerReady,
													'onStateChange' : videoEnded
												}
											}));
										}else{
											iframe.data('ytplayer').playVideo();
										}


										$(this).find('.ls-vpcontainer').delay(ls.g.v.d).fadeOut(ls.g.v.fo, function(){

											ls.g.isAnimating = false;
											if( ls.g.resize == true ){
												ls.makeResponsive( ls.g.curLayer, function(){
													ls.g.resize = false;
												});
											}
										});
									});

									http = $(this).attr('src').indexOf('http') === -1 ? HTTP : '';

									var src = http + $(this).attr('src');

									var sep = '&';
									if( src.indexOf('?') == -1 ){
										sep = '?';
									}

									// BUGFIX v5.6.0 We don't need autoplay parameter any more

									if( src.indexOf('autoplay') == -1 ){
										src += sep;
									}else{
										src.replace('autoplay=1','autoplay=0');
									}

									// BUGFIX v5.1.0 Fixed several issues with embedded videos (mostly under Firefox and IE)
									// fixed 'only audio but no video' bug, fixed 'unclickable video controls' bug, fixed 'hidden slider controls' bug
									// UPDATE v5.5.0 Changed to YouTube iFrame Player API 3.0

									src += '&wmode=opaque&html5=1&enablejsapi=1&version=3';

									$(this).data( 'videoSrc', src );

									$(this).data( 'originalWidth', $(this).attr('width') );
									$(this).data( 'originalHeight', $(this).attr('height') );

									$(this).attr('src', '');

								}
							});
						};
					}
				},

				play : function( video ){

				},

				stop : function( video ){

					video.parent().find('.ls-vpcontainer').fadeIn(ls.g.v.fi,function(){

						video.parent().find('iframe').data('ytplayer').stopVideo();
						video.parent().find('iframe').css('display','none');
					});
				}
			},

			vimeo : {

				init : function(){

					// IMPROVEMENT v4.6.0 http / https support of embedded videos

					var HTTP = document.location.href.indexOf('file:') === -1 ? '' : 'http:';

					// Vimeo videos

					$(el).find('iframe[src*="player.vimeo"]').each(function(){

						// BUGFIX v4.1.0 Firefox embedded video fix

						$(this).parent().addClass('ls-video-layer');

						if( $(this).parent('[class*="ls-l"]') ){

							var iframe = $(this);
							var http = HTTP;

							// Getting thumbnail

							var vpContainer = $('<div>').addClass('ls-vpcontainer').appendTo( $(this).parent() );

							$.getJSON( http + '//vimeo.com/api/v2/video/'+ ( $(this).attr('src').split('video/')[1].split('?')[0] ) +'.json?callback=?', function(data){

								$('<img>').appendTo( vpContainer ).addClass('ls-videopreview').attr('alt', 'Play video').attr('src', data[0]['thumbnail_large'] );

								iframe.data( 'videoDuration', parseInt( data[0]['duration'] ) * 1000 );
								$('<div>').appendTo( vpContainer ).addClass('ls-playvideo');
							});


							$(this).parent().css({
								width : $(this).width(),
								height : $(this).height()
							}).click(function(){

								// IMPROVEMENT v5.2.0 if video playing is in progress, video layers with auto play will skip showuntil feature

								if( $(this).data('showuntil') > 0 && $(this).data('showUntilTimer') ){
									clearTimeout( $(this).data('showUntilTimer') );
								}

								ls.g.isAnimating = true;

								if( ls.g.paused ){
									if( ls.o.autoPauseSlideshow != false ){
										ls.g.paused = false;
									}
									ls.g.originalAutoSlideshow = true;
								}else{
									ls.g.originalAutoSlideshow = ls.g.autoSlideshow;
								}

								if( ls.o.autoPauseSlideshow != false ){
									ls.stop();
								}

								ls.g.pausedByVideo = true;

								http = $(this).find('iframe').data('videoSrc').indexOf('http') === -1 ? HTTP : '';

								$(this).find('iframe').attr('src', http + $(this).find('iframe').data('videoSrc') );
								$(this).find('.ls-vpcontainer').delay(ls.g.v.d).fadeOut(ls.g.v.fo, function(){
									if( ls.o.autoPauseSlideshow == 'auto' && ls.g.originalAutoSlideshow == true ){
										var videoTimer = setTimeout(function() {
												ls.start();
										}, iframe.data( 'videoDuration') - ls.g.v.d );
										iframe.data( 'videoTimer', videoTimer );
									}
									ls.g.isAnimating = false;
									if( ls.g.resize == true ){
										ls.makeResponsive( ls.g.curLayer, function(){
											ls.g.resize = false;
										});
									}
								});
							});

							var sep = '&';

							if( $(this).attr('src').indexOf('?') == -1 ){
								sep = '?';
							}

							// BUGFIX v5.1.0 Fixed several issues with embedded videos (mostly under Firefox and IE)
							// fixed 'only audio but no video' bug, fixed 'unclickable video controls' bug, fixed 'hidden slider controls' bug

							var videoFix = '&wmode=opaque';

							// BUGFIX v5.1.0 Fixed autoplay parameter

							if( $(this).attr('src').indexOf('autoplay') == -1 ){
								$(this).data( 'videoSrc', $(this).attr('src') + sep + 'autoplay=1' + videoFix );
							}else{
								$(this).data( 'videoSrc', $(this).attr('src').replace('autoplay=0','autoplay=1') + videoFix );
							}

							$(this).data( 'originalWidth', $(this).attr('width') );
							$(this).data( 'originalHeight', $(this).attr('height') );
							$(this).attr('src','');
						}
					});
				},

				play : function( video ){

				},

				stop : function( video ){

					video.parent().find('.ls-vpcontainer').fadeIn(ls.g.v.fi,function(){

						video.parent().find('iframe').attr('src','');
					});
				}
			},

			html5 : {

				init : function(){

					// NEW FEATURE v5.0.0 HTML5 Video & Audio Support

					$(el).find('video, audio').each(function(){

						// BUGFIX v5.1.0 fixed HTML5 video sizing issue (again :)

						var ow = typeof $(this).attr('width') !== 'undefined' ? $(this).attr('width') : '640';
						var oh = typeof $(this).attr('height') !== 'undefined' ? $(this).attr('height') : '' + $(this).height();

						if( ow.indexOf('%') === -1 ){
							ow = parseInt( ow );
						}

						if( oh.indexOf('%') === -1 ){
							oh = parseInt( oh );
						}

						if( ow === '100%' && ( oh === 0 || oh === '0' || oh === '100%' ) ){
							$(this).attr('height', '100%');
							oh = 'auto';
						}

						$(this).parent().addClass('ls-video-layer').css({
							width : ow,
							height : oh
						}).data({
							originalWidth : ow,
							originalHeight : oh
						});

						var curVideo = $(this);

						// BUGFIX v5.3.0 'ended' function removed from 'click' function due to multiply

						$(this).on('ended', function(){
							if( ls.o.autoPauseSlideshow === 'auto' && ls.g.originalAutoSlideshow === true ){
								ls.start();
							}
						});

						$(this).removeAttr('width').removeAttr('height').css({
							width : '100%',
							height : '100%'
						}).click(function(e){

							// BUGFIX v5.3.0 autoplay didn't work in all cases

							if( !ls.g.pausedByVideo ){

								if( this.paused ){
									e.preventDefault();
								}

								this.play();

								ls.g.isAnimating = true;

								if( ls.g.paused ){
									if( ls.o.autoPauseSlideshow !== false ){
										ls.g.paused = false;
									}
									ls.g.originalAutoSlideshow = true;
								}else{
									ls.g.originalAutoSlideshow = ls.g.autoSlideshow;
								}

								if( ls.o.autoPauseSlideshow !== false ){
									ls.stop();
								}

								ls.g.pausedByVideo = true;
								ls.g.isAnimating = false;

								if( ls.g.resize === true ){
									ls.makeResponsive( ls.g.curLayer, function(){
										ls.g.resize = false;
									});
								}
							}
						});
					});
				},

				play : function( video ){

				},

				stop : function( video ){

					video[0].pause();
				}
			}
		};

		ls.change = function(num,prevnext){

			// Stopping Timers if needed

			ls.g.startSlideTime = ls.g.pausedSlideTime = ls.g.curSlideTime = false;

			// IMPROVEMENT v4.6.0 Bar Timer animation

			if( ls.g.barTimer ){
				ls.g.barTimer.stop().delay(300).animate({
					width: 0
				},450);
			}
			if( ls.g.circleTimer ){
				ls.g.circleTimer.fadeOut(500);
				if( ls.g.cttl ){
					ls.g.cttl.reverse().duration(.35);
				}
			}

			// NEW FEATURE v2.0 videoPreview & autoPlayVideos

			if( ls.g.pausedByVideo == true ){
				ls.g.pausedByVideo = false;
				ls.g.autoSlideshow = ls.g.originalAutoSlideshow;

				ls.g.curLayer.find('iframe[src*="youtube.com"], iframe[src*="youtu.be"]').each(function(){

					ls.media.youtube.stop( $(this) );
				});

				ls.g.curLayer.find('iframe[src*="player.vimeo"]').each(function(){

					ls.media.vimeo.stop( $(this) );
				});

				ls.g.curLayer.find('video, audio').each(function(){

					ls.media.html5.stop( $(this) );
				});
			}

			$(el).find('iframe[src*="youtube.com"], iframe[src*="youtu.be"], iframe[src*="player.vimeo"]').each(function(){

				// Clearing videoTimeouts

				clearTimeout( $(this).data( 'videoTimer') );
			});

			clearTimeout( ls.g.slideTimer );
			ls.g.nextLayerIndex = num;
			ls.g.nextLayer = $(el).find('.ls-slide:eq('+(ls.g.nextLayerIndex-1)+')');

			// BUGFIX v1.6 fixed wrong directions of animations if navigating by slidebuttons

			if( !prevnext ){

				if( ls.g.curLayerIndex < ls.g.nextLayerIndex ){
					ls.g.prevNext = 'next';
				}else{
					ls.g.prevNext = 'prev';
				}
			}

			// Added timeOut to wait for the fade animation of videoPreview image...

			var timeOut = 0;

			if( $(el).find('iframe[src*="youtube.com"], iframe[src*="youtu.be"], iframe[src*="player.vimeo"]').length > 0 ){
				timeOut = ls.g.v.fi;
			}

			if( typeof ls.g.nextLayer[0] !== 'undefined' ){
				ls.imgPreload(ls.g.nextLayer,function(){
					ls.animate();
				});
			}
		};

		// Preloading images

		ls.imgPreload = function(layer,callback){

			ls.g.isLoading = true;

			// Showing slider for the first time

			if( ls.g.showSlider ){
				$(el).css({
					visibility : 'visible'
				});
			}

			// If image preload is on

			if( ls.o.imgPreload ){

				var preImages = [];
				var preloaded = 0;

				// NEW FEATURE v1.8 Preloading background images of layers

				if( layer.css('background-image') != 'none' && layer.css('background-image').indexOf('url') != -1 && !layer.hasClass('ls-preloaded') && !layer.hasClass('ls-not-preloaded') ){
					var bgi = layer.css('background-image');
					bgi = bgi.match(/url\((.*)\)/)[1].replace(/"/gi, '');
					preImages[preImages.length] = [bgi, layer];
				}

				// Images inside layers

				layer.find('img:not(.ls-preloaded, .ls-not-preloaded)').each(function(){

					// NEW FEATURE v5.0.0 Lazy-load

					if( ls.o.lazyLoad === true ){
						$(this).attr('src',$(this).data('src'));
					}
					preImages[preImages.length] = [$(this).attr('src'), $(this)];
				});

				// Background images inside layers

				layer.find('*').each(function(){

					// BUGFIX v1.7 fixed preload bug with sublayers with gradient backgrounds

					if( $(this).css('background-image') != 'none' && $(this).css('background-image').indexOf('url') != -1 && !$(this).hasClass('ls-preloaded') && !$(this).hasClass('ls-not-preloaded') ){
						var bgi = $(this).css('background-image');
						bgi = bgi.match(/url\((.*)\)/)[1].replace(/"/gi, '');
						preImages[preImages.length] = [bgi, $(this)];
					}
				});

				// BUGFIX v1.7 if there are no images in a layer, calling the callback function

				if(preImages.length == 0){

					$('.ls-thumbnail-wrapper, .ls-nav-next, .ls-nav-prev, .ls-bottom-nav-wrapper').css({
						visibility : 'visible'
					});

					ls.makeResponsive(layer, callback);
				}else{

					// NEW FEATURE v4.0 Showing loading indicator

					if( ls.g.ie78 ){
						ls.g.li.css('display','block');
					}else{

						// BUGIFX v4.1.3 Adding delay to the showing of the loading indicator

						ls.g.li.delay(400).fadeIn(300);
					}

					var afterImgLoad = function(){

						// NEW FEATURE v4.0 Hiding loading indicator

						ls.g.li.stop(true,true).css({
							display: 'none'
						});

						$('.ls-thumbnail-wrapper, .ls-nav-next, .ls-nav-prev, .ls-bottom-nav-wrapper').css({
							visibility : 'visible'
						});

						// We love you so much IE... -.-

						if( navigator.userAgent.indexOf('Trident/7') !== -1 || ls.g.ie78 ){
							setTimeout(function(){
								ls.makeResponsive(layer, callback);
							},50);
						}else{
							ls.makeResponsive(layer, callback);
						}

					};

					for(x=0;x<preImages.length;x++){

						$('<img>').data('el',preImages[x]).load(function(){

							$(this).data('el')[1].addClass('ls-preloaded');

							if( ++preloaded == preImages.length ){

								afterImgLoad();
							}
						}).error(function(){
							var imgURL = $(this).data('el')[0].substring($(this).data('el')[0].lastIndexOf("/") + 1, $(this).data('el')[0].length);
							//if( window.console ){
							//	console.log('LayerSlider error:\r\n\r\nIt seems like the URL of the image or background image "'+imgURL+'" is pointing to a wrong location and it cannot be loaded. Please check the URLs of all your images used in the slider.');
							//}else{
							//	alert('LayerSlider error:\r\n\r\nIt seems like the URL of the image or background image "'+imgURL+'" is pointing to a wrong location and it cannot be loaded. Please check the URLs of all your images used in the slider.');
							//}

							$(this).addClass('ls-not-preloaded');

							// IMPROVEMENT v5.2.0 The slider should not stop even if an image cannot be loaded

							if( ++preloaded == preImages.length ){

								afterImgLoad();
							}

						}).attr('src',preImages[x][0]);
					}
				}
			}else{

				$('.ls-thumbnail-wrapper, .ls-nav-next, .ls-nav-prev, .ls-bottom-nav-wrapper').css({
					visibility : 'visible'
				});

				ls.makeResponsive(layer, callback);
			}
		};

		// NEW FEATURE v1.7 making the slider responsive

		ls.makeResponsive = function(layer, callback ){

			layer.css({
				visibility: 'hidden',
				display: 'block'
			});

			if( ls.g.showShadow ){
				ls.g.showShadow();
			}

			ls.resizeSlider();

			if( ls.o.thumbnailNavigation == 'always' ){
				ls.resizeThumb();
			}

			var layers = layer.children();

			layers.each(function(){

				var sl = $(this);

				// positioning

				var ol = sl.data('originalLeft') ? sl.data('originalLeft') : '0';
				var ot = sl.data('originalTop') ? sl.data('originalTop') : '0';


				if( sl.is('a') && sl.children().length > 0 ){
					sl.css({
						display : 'block'
					});
					sl = sl.children();
				}

				var ow = 'auto';
				var oh = 'auto';

				if( sl.data('originalWidth') ){

					if( typeof sl.data('originalWidth') == 'number' ){
						ow = parseInt( sl.data('originalWidth') ) * ls.g.ratio;
					}else if( sl.data('originalWidth').indexOf('%') != -1 ){
						ow = sl.data('originalWidth');
					}
				}

				if( sl.data('originalHeight') ){
					if( typeof sl.data('originalHeight') == 'number' ){
						oh = parseInt( sl.data('originalHeight') ) * ls.g.ratio;
					}else if( sl.data('originalHeight').indexOf('%') != -1 ){
						oh = sl.data('originalHeight');
					}
				}
				// padding

				var opl = sl.data('originalPaddingLeft') ? parseInt( sl.data('originalPaddingLeft') ) * ls.g.ratio : 0;
				var opr = sl.data('originalPaddingRight') ? parseInt( sl.data('originalPaddingRight') ) * ls.g.ratio : 0;
				var opt = sl.data('originalPaddingTop') ? parseInt( sl.data('originalPaddingTop') ) * ls.g.ratio : 0;
				var opb = sl.data('originalPaddingBottom') ? parseInt( sl.data('originalPaddingBottom') ) * ls.g.ratio : 0;

				// border

				var obl = sl.data('originalBorderLeft') ? parseInt( sl.data('originalBorderLeft') ) * ls.g.ratio : 0;
				var obr = sl.data('originalBorderRight') ? parseInt( sl.data('originalBorderRight') ) * ls.g.ratio : 0;
				var obt = sl.data('originalBorderTop') ? parseInt( sl.data('originalBorderTop') ) * ls.g.ratio : 0;
				var obb = sl.data('originalBorderBottom') ? parseInt( sl.data('originalBorderBottom') ) * ls.g.ratio : 0;

				// font

				var ofs = sl.data('originalFontSize');
				var olh = sl.data('originalLineHeight');

				// NEW FEATURE v3.0 added "normal" responsive mode with image and font resizing
				// NEW FEATURE v3.5 added responsiveUnder

				if( ls.g.responsiveMode || ls.o.responsiveUnder > 0 ){

					if( sl.is('img') && !sl.hasClass('ls-bg') && sl.attr('src') ){

						sl.css({
							width: 'auto',
							height: 'auto'
						});

						// IMPROVEMENT v4.5.0 Images can have now starting width / height

						if( ( ow == 0 || ow == 'auto' ) && typeof oh == 'number' && oh != 0 ){
							ow = ( oh / sl.height() ) * sl.width();
						}

						if( ( oh == 0 || oh == 'auto' ) && typeof ow == 'number' && ow != 0 ){
							oh = ( ow / sl.width() ) * sl.height();
						}

						if( ow == 'auto'){
							ow = sl.width() * ls.g.ratio;
						}

						if( oh == 'auto'){
							oh = sl.height() * ls.g.ratio;
						}

						sl.css({
							width : ow,
							height : oh
						});
					}

					if( !sl.is('img') ){
						sl.css({
							width : ow,
							height : oh,
							'font-size' : parseInt(ofs) * ls.g.ratio +'px',
							'line-height' : parseInt(olh) * ls.g.ratio + 'px'
						});
					}

					if( sl.is('div') && sl.find('iframe').data('videoSrc') ){

						var videoIframe = sl.find('iframe');
						videoIframe.attr('width', parseInt( videoIframe.data('originalWidth') ) * ls.g.ratio ).attr('height', parseInt( videoIframe.data('originalHeight') ) * ls.g.ratio );

						sl.css({
							width : parseInt( videoIframe.data('originalWidth') ) * ls.g.ratio,
							height : parseInt( videoIframe.data('originalHeight') ) * ls.g.ratio
						});
					}

					sl.css({
						padding : opt + 'px ' + opr + 'px ' + opb + 'px ' + opl + 'px ',
						borderLeftWidth : obl + 'px',
						borderRightWidth : obr + 'px',
						borderTopWidth : obt + 'px',
						borderBottomWidth : obb + 'px'
					});
				}

				// If it is NOT a bg sublayer

				if( !sl.hasClass('ls-bg') ){

					var sl2 = sl;

					if( sl.parent().is('a') ){
						sl = sl.parent();
					}

					// NEW FEATURE v3.5 sublayerContainer

					var slC = 0;
					if( ls.o.layersContainer ){
						slC = ls.o.layersContainer > 0 ? ( ls.g.sliderWidth() - ls.o.layersContainer ) / 2 : 0;
					}else if( ls.o.sublayerContainer ){
						slC = ls.o.sublayerContainer > 0 ? ( ls.g.sliderWidth() - ls.o.sublayerContainer ) / 2 : 0;
					}
					slC = slC < 0 ? 0 : slC;

					// (RE)positioning sublayer (left property)

					if( ol.indexOf('%') != -1 ){
						sl.css({
							left : ls.g.sliderWidth() / 100 * parseInt(ol) - sl2.width() / 2 - opl - obl
						});
					}else if( slC > 0 || ls.g.responsiveMode || ls.o.responsiveUnder > 0 ){
						sl.css({
							left : slC + parseInt(ol) * ls.g.ratio
						});
					}

					// (RE)positioning sublayer (top property)

					if( ot.indexOf('%') != -1 ){
						sl.css({
							top : ls.g.sliderHeight() / 100 * parseInt(ot) - sl2.height() / 2 - opt - obt
						});
					}else if( ls.g.responsiveMode || ls.o.responsiveUnder > 0 ){
						sl.css({
							top : parseInt(ot) * ls.g.ratio
						});
					}

				}else{

					var inner = ls.g.i;

					sl.css({
						width : 'auto',
						height : 'auto'
					});

					ow = sl.width();
					oh = sl.height();

					// IMPROVEMENT v4.5.0 Resizing smaller background images in full width mode as well to fill the whole slide

					var or = ls.g.ratio;

					if( ls.g.sliderOriginalWidth.indexOf('%') != -1 ){
						if( ls.g.sliderWidth() > ow ){
							or = ls.g.sliderWidth() / ow;
							if( ls.g.sliderHeight() > oh * or ){
								or = ls.g.sliderHeight() / oh;
							}
						}else if( ls.g.sliderHeight() > oh ){
							or = ls.g.sliderHeight() / oh;
							if( ls.g.sliderWidth() > ow * or ){
								or = ls.g.sliderWidth() / ow;
							}
						}
					}

					sl.css({
						width : ow * or,
						height : oh * or,
						marginLeft : inner.width() / 2 - ow * or / 2,
						marginTop : inner.height() / 2 - oh * or / 2
					});
//					$('#w2 span:eq(0)').html( ( inner.width() / 2 ) - Math.round( ow * or / 2 ) );
				}
			});

			layer.css({
				display: 'none',
				visibility: 'visible'
			});

			// Resizing shadow

			ls.resizeShadow();

			callback();

			$(this).dequeue();
		};

		// Resizing shadow

		ls.resizeShadow = function(){
			if( ls.g.shadowImg ){
				var resizeShadow = function(){
					if( ls.g.shadowImg.height() > 0 ){
						if( ls.g.shadowBtmMod > 0 ){
							ls.g.shadow.css({
								height: ls.g.shadowImg.height() / 2
							});
						}else{
							ls.g.shadow.css({
								height: ls.g.shadowImg.height(),
								marginTop: - ls.g.shadowImg.height() / 2
							});
						}
					}else{
						setTimeout(function(){
							resizeShadow();
						},50);
					}
				};

				resizeShadow();
			}
		};

		// Resizing the slider

		ls.resizeSlider = function(){

			if( ls.o.responsiveUnder > 0 ){

				if( $(window).width() < ls.o.responsiveUnder ){
					ls.g.responsiveMode = true;
					ls.g.sliderOriginalWidth = ls.o.responsiveUnder + 'px';
				}else{
					ls.g.responsiveMode = false;
					ls.g.sliderOriginalWidth = ls.g.sliderOriginalWidthRU;
					ls.g.ratio = 1;
				}
			}

			// BUGFIX 5.3.0 Fixed full-width resize issue

			if( $(el).closest('.ls-wp-fullwidth-container').length ){

					$(el).closest('.ls-wp-fullwidth-helper').css({
						width : $(window).width()
					});
			}

			// NEW FEATURE v3.0 added "normal" responsive mode with image and font resizing

			if( ls.g.responsiveMode ){

				var parent = $(el).parent();

				// Future FEATURE FullScreen mode

				if( ls.o.fullScreen === true ){

					$(el).css({
						width : '100%',
						height : $(window).height()
					});
				}else{

					// BUGFIX v4.0 there is no need to subtract the values of the left and right paddings of the container element!

					$(el).css({
					       width : parent.width() - parseInt($(el).css('padding-left')) - parseInt($(el).css('padding-right'))
      					});
					ls.g.ratio = $(el).width() / parseInt( ls.g.sliderOriginalWidth );
					$(el).css({
						height : ls.g.ratio * parseInt( ls.g.sliderOriginalHeight )
					});
				}

			}else{
				ls.g.ratio = 1;
				$(el).css({
					width : ls.g.sliderOriginalWidth,
					height : ls.g.sliderOriginalHeight
				});
			}

			// WP fullWidth mode (originally forceResponsive mode)

			if( $(el).closest('.ls-wp-fullwidth-container').length ){

				$(el).closest('.ls-wp-fullwidth-helper').css({
					height : $(el).outerHeight(true)
				});

				$(el).closest('.ls-wp-fullwidth-container').css({
					height : $(el).outerHeight(true)
				});

				$(el).closest('.ls-wp-fullwidth-helper').css({
					width : $(window).width(),
					left : - $(el).closest('.ls-wp-fullwidth-container').offset().left
				});

				if( ls.g.sliderOriginalWidth.indexOf('%') != -1 ){

					var percentWidth = parseInt( ls.g.sliderOriginalWidth );
					var newWidth = $('body').width() / 100 * percentWidth - ( $(el).outerWidth() - $(el).width() );
					$(el).width( newWidth );
				}
			}

			$(el).find('.ls-inner, .ls-lt-container').css({
				width : ls.g.sliderWidth(),
				height : ls.g.sliderHeight()
			});

			// BUGFIX v2.0 fixed width problem if firstSlide is not 1

			if( ls.g.curLayer && ls.g.nextLayer ){

				ls.g.curLayer.css({
					width : ls.g.sliderWidth(),
					height : ls.g.sliderHeight()
				});

				ls.g.nextLayer.css({
					width : ls.g.sliderWidth(),
					height : ls.g.sliderHeight()
				});

			}else{

				$(el).find('.ls-slide').css({
					width : ls.g.sliderWidth(),
					height : ls.g.sliderHeight()
				});
			}
		};

		// NEW FEATURE v3.0 added responsive yourLogo

		ls.resizeYourLogo = function(){

			ls.g.yourLogo.css({
				width : ls.g.yourLogo.data( 'originalWidth' ) * ls.g.ratio,
				height : ls.g.yourLogo.data( 'originalHeight' ) * ls.g.ratio
			});

			if( ls.g.ie78 ){
				ls.g.yourLogo.css('display','block');
			}else{
				ls.g.yourLogo.fadeIn(300);
			}

			var oL = oR = oT = oB = 'auto';

			if( ls.g.yourLogo.data( 'originalLeft' ) && ls.g.yourLogo.data( 'originalLeft' ).indexOf('%') != -1 ){
				oL = ls.g.sliderWidth() / 100 * parseInt( ls.g.yourLogo.data( 'originalLeft' ) ) - ls.g.yourLogo.width() / 2 + parseInt( $(el).css('padding-left') );
			}else{
				oL = parseInt( ls.g.yourLogo.data( 'originalLeft' ) ) * ls.g.ratio;
			}

			if( ls.g.yourLogo.data( 'originalRight' ) && ls.g.yourLogo.data( 'originalRight' ).indexOf('%') != -1 ){
				oR = ls.g.sliderWidth() / 100 * parseInt( ls.g.yourLogo.data( 'originalRight' ) ) - ls.g.yourLogo.width() / 2 + parseInt( $(el).css('padding-right') );
			}else{
				oR = parseInt( ls.g.yourLogo.data( 'originalRight' ) ) * ls.g.ratio;
			}

			if( ls.g.yourLogo.data( 'originalTop' ) && ls.g.yourLogo.data( 'originalTop' ).indexOf('%') != -1 ){
				oT = ls.g.sliderHeight() / 100 * parseInt( ls.g.yourLogo.data( 'originalTop' ) ) - ls.g.yourLogo.height() / 2 + parseInt( $(el).css('padding-top') );
			}else{
				oT = parseInt( ls.g.yourLogo.data( 'originalTop' ) ) * ls.g.ratio;
			}

			if( ls.g.yourLogo.data( 'originalBottom' ) && ls.g.yourLogo.data( 'originalBottom' ).indexOf('%') != -1 ){
				oB = ls.g.sliderHeight() / 100 * parseInt( ls.g.yourLogo.data( 'originalBottom' ) ) - ls.g.yourLogo.height() / 2 + parseInt( $(el).css('padding-bottom') );
			}else{
				oB = parseInt( ls.g.yourLogo.data( 'originalBottom' ) ) * ls.g.ratio;
			}

			ls.g.yourLogo.css({
				left : oL,
				right : oR,
				top : oT,
				bottom : oB
			});
		};

		// NEW FEATURE v3.5 thumbnailNavigation ('always')

		// Resizing thumbnails

		ls.resizeThumb = function(){

			ls.bottomNavSizeHelper('on');

			var sliderW = ls.g.sliderOriginalWidth.indexOf('%') == -1 ? parseInt( ls.g.sliderOriginalWidth ) : ls.g.sliderWidth();

			$(el).find('.ls-thumbnail-slide a').css({
				width : parseInt( ls.o.tnWidth * ls.g.ratio ),
				height : parseInt( ls.o.tnHeight * ls.g.ratio )
			});

			$(el).find('.ls-thumbnail-slide a:last').css({
				margin: 0
			});

			$(el).find('.ls-thumbnail-slide').css({
				height : parseInt( ls.o.tnHeight * ls.g.ratio )
			});

			var tn = $(el).find('.ls-thumbnail');

			var originalWidth = ls.o.tnContainerWidth.indexOf('%') == -1 ? parseInt( ls.o.tnContainerWidth ) : parseInt( sliderW / 100 * parseInt( ls.o.tnContainerWidth ) );

			tn.css({
				width : originalWidth * Math.floor( ls.g.ratio * 100 ) / 100
			});

			if( tn.width() > $(el).find('.ls-thumbnail-slide').width() ){
				tn.css({
					width : $(el).find('.ls-thumbnail-slide').width()
				});
			}

			ls.bottomNavSizeHelper('off');
		};

		// Changing thumbnails

		ls.changeThumb = function(index){

			var curIndex = index ? index : ls.g.nextLayerIndex;

			$(el).find('.ls-thumbnail-slide a:not(.ls-thumb-'+curIndex+')').children().each(function(){
				$(this).removeClass('ls-thumb-active').stop().fadeTo(750,ls.o.tnInactiveOpacity/100);
			});

			$(el).find('.ls-thumbnail-slide a.ls-thumb-'+curIndex).children().addClass('ls-thumb-active').stop().fadeTo(750,ls.o.tnActiveOpacity/100);
		};

		// Scrolling thumbnails

		ls.scrollThumb = function(){

			if( !$(el).find('.ls-thumbnail-slide-container').hasClass('ls-thumbnail-slide-hover') ){
				var curThumb = $(el).find('.ls-thumb-active').length ? $(el).find('.ls-thumb-active').parent() : false;
				if( curThumb ){
					var thumbCenter = curThumb.position().left + curThumb.width() / 2;
					var mL = $(el).find('.ls-thumbnail-slide-container').width() / 2 - thumbCenter;
					mL = mL < $(el).find('.ls-thumbnail-slide-container').width() - $(el).find('.ls-thumbnail-slide').width() ? $(el).find('.ls-thumbnail-slide-container').width() - $(el).find('.ls-thumbnail-slide').width() : mL;
					mL = mL > 0 ? 0 : mL;
					$(el).find('.ls-thumbnail-slide').animate({
						marginLeft : mL
					}, 600 );
				}
			}
		};

		// IMPROVEMENT v4.1.3 Changed the working of some Thumbnail and Bottom Navigation features

		ls.bottomNavSizeHelper = function(val){

			if( ls.o.hoverBottomNav && !$(el).hasClass('ls-hover') ){
				switch(val){
					case 'on':
						ls.g.thumbsWrapper.css({
							visibility: 'hidden',
							display: 'block'
						});
					break;
					case 'off':
						ls.g.thumbsWrapper.css({
							visibility: 'visible',
							display: 'none'
						});
					break;
				}
			}
		};

		// Animating layers and sublayers

		ls.animate = function(){

			/* GLOBAL (used by both old and new transitions ) */

					ls.g.numYouTubeCurSlide = 0;

					// Changing variables
					// BUGFIX v4.6.0 If there is only one layer, there is no need to set ls.g.isAnimating to true

					if( $(el).find('.ls-slide').length > 1 ){
						ls.g.isAnimating = true;
					}

					ls.g.isLoading = false;

					// Clearing timeouts

					clearTimeout( ls.g.slideTimer );
					clearTimeout( ls.g.changeTimer );

					ls.g.stopLayer = ls.g.curLayer;

					// Calling cbAnimStart callback function

					ls.o.cbAnimStart(ls.g);

					// NEW FEATURE v3.5 thumbnailNavigation ('always')

					if( ls.o.thumbnailNavigation == 'always' ){

						// ChangeThumb

						ls.changeThumb();

						// ScrollThumb

						if( !('ontouchstart' in window) ){
							ls.scrollThumb();
						}
					}

					// Adding .ls-animating class to next layer

					ls.g.nextLayer.addClass('ls-animating');

			/* OLD layer transitions (version 3.x) */

					// Setting position and styling of current and next layers

					var curLayerLeft = curLayerRight = curLayerTop = curLayerBottom = nextLayerLeft = nextLayerRight = nextLayerTop = nextLayerBottom = layerMarginLeft = layerMarginRight = layerMarginTop = layerMarginBottom = 'auto';
					var curLayerWidth = nextLayerWidth = ls.g.sliderWidth();
					var curLayerHeight = nextLayerHeight = ls.g.sliderHeight();

					// Calculating direction

					var prevOrNext = ls.g.prevNext == 'prev' ? ls.g.curLayer : ls.g.nextLayer;
					var chooseDirection = prevOrNext.data('slidedirection') ? prevOrNext.data('slidedirection') : ls.o.slideDirection;

					// Setting the direction of sliding

					var slideDirection = ls.g.slideDirections[ls.g.prevNext][chooseDirection];

					if( slideDirection == 'left' || slideDirection == 'right' ){
						curLayerWidth = curLayerTop = nextLayerWidth = nextLayerTop = 0;
						layerMarginTop = 0;
					}
					if( slideDirection == 'top' || slideDirection == 'bottom' ){
						curLayerHeight = curLayerLeft = nextLayerHeight = nextLayerLeft = 0;
						layerMarginLeft = 0;
					}

					switch(slideDirection){
						case 'left':
							curLayerRight = nextLayerLeft = 0;
							layerMarginLeft = -ls.g.sliderWidth();
							break;
						case 'right':
							curLayerLeft = nextLayerRight = 0;
							layerMarginLeft = ls.g.sliderWidth();
							break;
						case 'top':
							curLayerBottom = nextLayerTop = 0;
							layerMarginTop = -ls.g.sliderHeight();
							break;
						case 'bottom':
							curLayerTop = nextLayerBottom = 0;
							layerMarginTop = ls.g.sliderHeight();
							break;
					}

					// Setting start positions and styles of layers

					ls.g.curLayer.css({
						left : curLayerLeft,
						right : curLayerRight,
						top : curLayerTop,
						bottom : curLayerBottom
					});
					ls.g.nextLayer.css({
						width : nextLayerWidth,
						height : nextLayerHeight,
						left : nextLayerLeft,
						right : nextLayerRight,
						top : nextLayerTop,
						bottom : nextLayerBottom
					});

					// Creating variables for the OLD transitions of CURRENT LAYER

					// BUGFIX v1.6 fixed some wrong parameters of current layer
					// BUGFIX v1.7 fixed using of delayout of current layer

					var curDelay = ls.g.curLayer.data('delayout') ? parseInt(ls.g.curLayer.data('delayout')) : ls.o.delayOut;

					var curDuration = ls.g.curLayer.data('durationout') ? parseInt(ls.g.curLayer.data('durationout')) : ls.o.durationOut;
					var curEasing = ls.g.curLayer.data('easingout') ? ls.g.curLayer.data('easingout') : ls.o.easingOut;

					// Creating variables for the OLD transitions of NEXT LAYER

					var nextDelay = ls.g.nextLayer.data('delayin') ? parseInt(ls.g.nextLayer.data('delayin')) : ls.o.delayIn;
					var nextDuration = ls.g.nextLayer.data('durationin') ? parseInt(ls.g.nextLayer.data('durationin')) : ls.o.durationIn;

					// BUGFIX v5.2.0 duration cannot be 0

					if( nextDuration === 0 ){ nextDuration = 1 }
					var nextEasing = ls.g.nextLayer.data('easingin') ? ls.g.nextLayer.data('easingin') : ls.o.easingIn;

					var curLayer = function(){

						// BUGFIX v1.6 added an additional delaytime to current layer to fix the '1px gap' bug
						// BUGFIX v3.0 modified from curDuration / 80 to curDuration / 15

						ls.g.curLayer.delay( curDelay + curDuration / 15).animate({
							width : curLayerWidth,
							height : curLayerHeight
						}, curDuration, curEasing,function(){

							curLayerCallback();
						});
					};

					var curLayerCallback = function(){

						// Stopping current sublayer animations if needed (they are not visible at this point).

						ls.g.stopLayer.find(' > *[class*="ls-l"]').each(function(){
							if( $(this).data('tr') ){
								$(this).data('tr').kill();
							}

							$(this).css({
								filter: 'none'
							});
						});

						// Setting current layer

						ls.g.curLayer = ls.g.nextLayer;

						// IMPROVEMENT v5.2.0 added prevLayerIndex and fixing curLayerIndex (nextLayerIndex is the same as curLayerIndex because the slider doesn't know at this point which slide will be the next)

						ls.g.prevLayerIndex = ls.g.curLayerIndex;
						ls.g.curLayerIndex = ls.g.nextLayerIndex;

						ls.o.cbAnimStop(ls.g);

						// NEW FEATURE v5.0.0 Lazy-load (preloading here the images of the next layer)

						if( ls.o.imgPreload && ls.o.lazyLoad ){

							var preLayerIndex = ls.g.curLayerIndex == ls.g.layersNum ? 1 : ls.g.curLayerIndex + 1;
							$(el).find('.ls-slide').eq(preLayerIndex-1).find('img:not(.ls-preloaded)').each(function(){
								$(this).load(function(){
									$(this).addClass('ls-preloaded');
								}).error(function(){
									var imgURL = $(this).data('src').substring($(this).data('src').lastIndexOf("/") + 1, $(this).data('src').length);
									//if( window.console ){
									//	console('LayerSlider error:\r\n\r\nIt seems like the URL of the image or background image "'+imgURL+'" is pointing to a wrong location and it cannot be loaded. Please check the URLs of all your images used in the slider.');
									//}else{
									//	alert('LayerSlider error:\r\n\r\nIt seems like the URL of the image or background image "'+imgURL+'" is pointing to a wrong location and it cannot be loaded. Please check the URLs of all your images used in the slider.');
									//}
									$(this).addClass('ls-not-preloaded');
								}).attr('src', $(this).data('src'));
							});
						}

						// Changing some css classes

						$(el).find('.ls-slide').removeClass('ls-active');
						$(el).find('.ls-slide:eq(' + ( ls.g.curLayerIndex - 1 ) + ')').addClass('ls-active').removeClass('ls-animating');
						$(el).find('.ls-bottom-slidebuttons a').removeClass('ls-nav-active');
						$(el).find('.ls-bottom-slidebuttons a:eq('+( ls.g.curLayerIndex - 1 )+')').addClass('ls-nav-active');

						// Setting timer if needed

						if( ls.g.autoSlideshow ){
							ls.timer();
						}

						// Changing variables

						ls.g.isAnimating = false;
						if( ls.g.resize == true ){
							ls.makeResponsive( ls.g.curLayer, function(){
								ls.g.resize = false;
							});
						}

					};

					var curSubLayers = function(sublayersDurationOut){

						var curLayers = ls.g.curLayer.find(' > *[class*="ls-l"]');

						curLayers.each(function(){

							if( typeof $(this).data('originalSlide') == 'undefined' || ( typeof $(this).data('originalSlide') != 'undefined' && $(this).data('originalSlide') !== ls.g.curLayerIndex ) ){

								if( !$(this).data('transitiontype') ){
									ls.transitionType( $(this) );
								}

								// BUGFIX v5.1.0 Removing ls-videohack class before starting transition

								$(this).removeClass('ls-videohack');

								var curSubSlideDir = $(this).data('slidedirection') ? $(this).data('slidedirection') : slideDirection;
								var lml, lmt;

								switch(curSubSlideDir){
									case 'left':
										lml = -ls.g.sliderWidth();
										lmt = 0;
										break;
									case 'right':
										lml = ls.g.sliderWidth();
										lmt = 0;
										break;
									case 'top':
										lmt = -ls.g.sliderHeight();
										lml = 0;
										break;
									case 'bottom':
										lmt = ls.g.sliderHeight();
										lml = 0;
										break;
									case 'fade':
										lmt = 0;
										lml = 0;
										break;
								}

								// NEW FEATURE v1.6 added slideoutdirection to sublayers
								// NEW FEATURES 5.0.0 added axis-free transitions with offsetx and offsety properties

								if( $(this).data('transitiontype') === 'new' ){
									var curSubSlideOutDir = 'new';
								}else{
									var curSubSlideOutDir = $(this).data('slideoutdirection') ? $(this).data('slideoutdirection') : false;
								}

								switch(curSubSlideOutDir){
									case 'left':
										lml = ls.g.sliderWidth();
										lmt = 0;
										break;
									case 'right':
										lml = -ls.g.sliderWidth();
										lmt = 0;
										break;
									case 'top':
										lmt = ls.g.sliderHeight();
										lml = 0;
										break;
									case 'bottom':
										lmt = -ls.g.sliderHeight();
										lml = 0;
										break;
									case 'fade':
										lmt = 0;
										lml = 0;
										break;
									case 'new':
										if( $(this).data('offsetxout') ){
											if( $(this).data('offsetxout') === 'left' ){
												lml = ls.g.sliderWidth();
											}else if( $(this).data('offsetxout') === 'right' ){
												lml = -ls.g.sliderWidth();
											}else{
												lml = -parseInt( $(this).data('offsetxout') );
											}
										}else{
											lml = -ls.lt.offsetXOut;
										}
										if( $(this).data('offsetyout') ){
											if( $(this).data('offsetyout') === 'top' ){
												lmt = ls.g.sliderHeight();
											}else if( $(this).data('offsetyout') === 'bottom' ){
												lmt = -ls.g.sliderHeight();
											}else{
												lmt = -parseInt( $(this).data('offsetyout') );
											}
										}else{
											lmt = -ls.lt.offsetYOut;
										}
										break;
								}

								// NEW FEATURES v4.5.0 Rotating & Scaling sublayers
								// BUGFIX v4.5.5 changing the default value from 0 to 'none' (because of old jQuery, 1.7.2)
								// NEW FEATURES v5.0.0 Added SkewX, SkewY, ScaleX, ScaleY, RotateX & RotateY transitions

								var curSubRotate = curSubRotateX = curSubRotateY = curSubScale = curSubSkewX = curSubSkewY = curSubScaleX = curSubScaleY = 'none';
	//							if( !ls.g.ie78 && ls.g.enableCSS3 ){
									curSubRotate = $(this).data('rotateout') ? $(this).data('rotateout') : ls.lt.rotateOut;
									curSubRotateX = $(this).data('rotatexout') ? $(this).data('rotatexout') : ls.lt.rotateXOut;
									curSubRotateY = $(this).data('rotateyout') ? $(this).data('rotateyout') : ls.lt.rotateYOut;
									curSubScale = $(this).data('scaleout') ? $(this).data('scaleout') : ls.lt.scaleOut;
									curSubSkewX = $(this).data('skewxout') ? $(this).data('skewxout') : ls.lt.skewXOut;
									curSubSkewY = $(this).data('skewyout') ? $(this).data('skewyout') : ls.lt.skewYOut;
									if( curSubScale === 1 ){
										curSubScaleX = $(this).data('scalexout') ? $(this).data('scalexout') : ls.lt.scaleXOut;
										curSubScaleY = $(this).data('scaleyout') ? $(this).data('scaleyout') : ls.lt.scaleYOut;
									}else{
										curSubScaleX = curSubScaleY = curSubScale;
									}
									var too = $(this).data('transformoriginout') ? $(this).data('transformoriginout').split(' ') : ls.lt.transformOriginOut;
									for(var t =0;t<too.length;t++){
										if( too[t].indexOf('%') === -1 && too[t].indexOf('left') !== -1 && too[t].indexOf('right') !== -1 && too[t].indexOf('top') !== -1 && too[t].indexOf('bottom') !== -1 ){
											too[t] = '' + parseInt( too[t] ) * ls.g.ratio + 'px';
										}
									}
									var curSubTransformOrigin = too.join(' ');
									var curSubPerspective = $(this).data('perspectiveout') ? $(this).data('perspectiveout') : ls.lt.perspectiveOut;
	//							}

								// IMPROVEMENT v4.0 Distance (P.level): -1

								var endLeft = parseInt( $(this).css('left') );
								var endTop = parseInt( $(this).css('top') );

								var curSubPLevel = parseInt( $(this).attr('class').split('ls-l')[1] );

								var wh = $(this).outerWidth() > $(this).outerHeight() ? $(this).outerWidth() : $(this).outerHeight();
								var modX = parseInt( curSubRotate ) === 0 ? $(this).outerWidth() : wh;
								var modY = parseInt( curSubRotate ) === 0 ? $(this).outerHeight() : wh;

								if( ( curSubPLevel === -1 && curSubSlideOutDir !== 'new' ) || ( $(this).data('offsetxout') === 'left' || $(this).data('offsetxout') === 'right' ) ){
									if( lml < 0 ){
										lml = - ( ls.g.sliderWidth() - endLeft + ( curSubScaleX / 2 - .5 ) * modX + 100  );
									}else if( lml > 0 ){
										lml = endLeft + ( curSubScaleX / 2 + .5 ) * modX + 100;
									}
								}else{
									lml = lml * ls.g.ratio;
								}

								if( ( curSubPLevel === -1 && curSubSlideOutDir !== 'new' ) || ( $(this).data('offsetyout') === 'top' || $(this).data('offsetyout') === 'bottom' ) ){
									if( lmt < 0 ){
										lmt = - ( ls.g.sliderHeight() - endTop + ( curSubScaleY / 2 - .5 ) * modY + 100  );
									}else if( lmt > 0 ){
										lmt = endTop + ( curSubScaleY / 2 + .5 ) * modY + 100;
									}
								}else{
									lmt = lmt * ls.g.ratio;
								}

								if( curSubPLevel === -1 || curSubSlideOutDir === 'new' ){
									var curSubPar = 1;
								}else{
									var curSubParMod = ls.g.curLayer.data('parallaxout') ? parseInt(ls.g.curLayer.data('parallaxout')) : ls.o.parallaxOut;
									var curSubPar = curSubPLevel * curSubParMod;
								}

								if( $(this).data('transitiontype') === 'new' ){
									var deO = ls.lt.delayOut;
									var duO = ls.lt.durationOut;
									var eO = ls.lt.easingOut;
								}else{
									var deO = ls.o.delayOut;
									var duO = ls.o.durationOut;
									var eO = ls.o.easingOut;
								}

								var curSubDelay = $(this).data('delayout') ? parseInt($(this).data('delayout')) : deO;
								var curSubTime = $(this).data('durationout') ? parseInt($(this).data('durationout')) : duO;

								// BUGFIX v5.2.0 duration cannot be 0

								if( curSubTime === 0 ){ curSubTime = 1 }
								var curSubEasing = $(this).data('easingout') ? $(this).data('easingout') : eO;

								// On new layer transitions, all sublayer will be slide / fade out in 500ms without any delays

								if(sublayersDurationOut){
									curSubDelay = 0;
									curSubTime = sublayersDurationOut;
									// curSubEasing = 'easeInExpo';
								}

								// Clearing showUntilTimers

								if( $(this).data('showUntilTimer') ){
									clearTimeout( $(this).data('showUntilTimer') );
								}

								var css = {
									visibility : 'hidden'
								};

								var el = $(this);

								var transition = {
									rotation : curSubRotate,
									rotationX : curSubRotateX,
									rotationY : curSubRotateY,
									skewX : curSubSkewX,
									skewY : curSubSkewY,
									scaleX : curSubScaleX,
									scaleY : curSubScaleY,
									x : -lml * curSubPar,
									y : -lmt * curSubPar,
									delay : curSubDelay/1000,
									ease : lsConvertEasing( curSubEasing ),
									onComplete : function(){
										el.css( css );
									}
								};

								if( curSubSlideOutDir == 'fade' || ( !curSubSlideOutDir && curSubSlideDir === 'fade' ) || ( $(this).data('fadeout') !== 'false' && $(this).data('transitiontype') === 'new' ) ){
									transition['opacity'] = 0;
									css['opacity'] = $(this).data( 'originalOpacity' );
								}

								if( $(this).data('tr') ){
									$(this).data('tr').kill();
								}

								TweenLite.set( $(this)[0],{
									transformOrigin : curSubTransformOrigin,
									transformPerspective : curSubPerspective
								});

								$(this).data('tr', TweenLite.to($(this)[0],curSubTime/1000,transition) );

								// $(this).stop(true,false).delay( curSubDelay ).animate( transition, curSubTime, curSubEasing,function(){
								// 	$(this).css( css );
								// });
							}
						});
					};

					var nextLayer = function(){

						ls.g.nextLayer.delay( curDelay + nextDelay ).animate({
							width : ls.g.sliderWidth(),
							height : ls.g.sliderHeight()
						}, nextDuration, nextEasing );
					};

					var nextSubLayers = function(){

						if( ls.g.totalDuration ){
							curDelay = 0;
						}

						// Needed for the Timeline
						if( typeof ls.o.cbTimeLineStart === 'function' ){
							ls.o.cbTimeLineStart(ls.g, curDelay+nextDelay );
						}

						ls.g.nextLayer.find(' > *[class*="ls-l"]').each(function(){

							// Replacing global parameters with unique if need
							// NEW FEATURES 5.0.0 added axis-free transitions with offsetx and offsety properties

							if( !$(this).data('transitiontype') ){
								ls.transitionType( $(this) );
							}

							if( $(this).data('transitiontype') === 'new' ){
								var nextSubSlideDir = 'new';
							}else{
								var nextSubSlideDir = $(this).data('slidedirection') ? $(this).data('slidedirection') : slideDirection;
							}
							var lml, lmt;

							switch(nextSubSlideDir){
								case 'left':
									lml = -ls.g.sliderWidth();
									lmt = 0;
									break;
								case 'right':
									lml = ls.g.sliderWidth();
									lmt = 0;
									break;
								case 'top':
									lmt = -ls.g.sliderHeight();
									lml = 0;
									break;
								case 'bottom':
									lmt = ls.g.sliderHeight();
									lml = 0;
									break;
								case 'fade':
									lmt = 0;
									lml = 0;
									break;
								case 'new':
									if( $(this).data('offsetxin') ){
										if( $(this).data('offsetxin') === 'left' ){
											lml = -ls.g.sliderWidth();
										}else if( $(this).data('offsetxin') === 'right' ){
											lml = ls.g.sliderWidth();
										}else{
											lml = parseInt( $(this).data('offsetxin') );
										}
									}else{
										lml = ls.lt.offsetXIn;
									}
									if( $(this).data('offsetyin') ){
										if( $(this).data('offsetyin') === 'top' ){
											lmt = -ls.g.sliderHeight();
										}else if( $(this).data('offsetyin') === 'bottom' ){
											lmt = ls.g.sliderHeight();
										}else{
											lmt = parseInt( $(this).data('offsetyin') );
										}
									}else{
										lmt = ls.lt.offsetYIn;
									}
									break;
							}

							// NEW FEATURE v4.5.0 Rotating & Scaling sublayers
							// BUGFIX v4.5.5 changing the default value from 0 to 'none' (because of old jQuery, 1.7.2)
							// NEW FEATURES v5.0.0 Added SkewX, SkewY, ScaleX, ScaleY, RotateX & RotateY transitions

							var nextSubRotate = nextSubRotateX = nextSubRotateY = nextSubScale = nextSubSkewX = nextSubSkewY = nextSubScaleX = nextSubScaleY = 'none';
//							if( !ls.g.ie78 && ls.g.enableCSS3 ){
								nextSubRotate = $(this).data('rotatein') ? $(this).data('rotatein') : ls.lt.rotateIn;
								nextSubRotateX = $(this).data('rotatexin') ? $(this).data('rotatexin') : ls.lt.rotateXIn;
								nextSubRotateY = $(this).data('rotateyin') ? $(this).data('rotateyin') : ls.lt.rotateYIn;
								nextSubScale = $(this).data('scalein') ? $(this).data('scalein') : ls.lt.scaleIn;
								nextSubSkewX = $(this).data('skewxin') ? $(this).data('skewxin') : ls.lt.skewXIn;
								nextSubSkewY = $(this).data('skewyin') ? $(this).data('skewyin') : ls.lt.skewYIn;
								if( nextSubScale === 1 ){
									nextSubScaleX = $(this).data('scalexin') ? $(this).data('scalexin') : ls.lt.scaleXIn;
									nextSubScaleY = $(this).data('scaleyin') ? $(this).data('scaleyin') : ls.lt.scaleYIn;
								}else{
									nextSubScaleX = nextSubScaleY = nextSubScale;
								}

								var toi = $(this).data('transformoriginin') ? $(this).data('transformoriginin').split(' ') : ls.lt.transformOriginIn;
								for(var t =0;t<toi.length;t++){
									if( toi[t].indexOf('%') === -1 && toi[t].indexOf('left') !== -1 && toi[t].indexOf('right') !== -1 && toi[t].indexOf('top') !== -1 && toi[t].indexOf('bottom') !== -1 ){
										toi[t] = '' + parseInt( toi[t] ) * ls.g.ratio + 'px';
									}
								}
								var nextSubTransformOrigin = toi.join(' ');
								var nextSubPerspective = $(this).data('perspectivein') ? $(this).data('perspectivein') : ls.lt.perspectiveIn;
//							}

							// IMPROVEMENT v4.0 Distance (P.level): -1

							var endLeft = parseInt( $(this).css('left') );
							var endTop = parseInt( $(this).css('top') );

							var nextSubPLevel = parseInt( $(this).attr('class').split('ls-l')[1] );

							// BUGFIX v5.0.1 Fixed the starting position of layers with percentage value of width

							if( $(this)[0].style.width.indexOf('%') !== -1 ){
								$(this).css({
									width: ls.g.sliderWidth() / 100 * parseInt( $(this)[0].style.width )
								});
							}

							var wh = $(this).outerWidth() > $(this).outerHeight() ? $(this).outerWidth() : $(this).outerHeight();
							var modX = parseInt( nextSubRotate ) === 0 ? $(this).outerWidth() : wh;
							var modY = parseInt( nextSubRotate ) === 0 ? $(this).outerHeight() : wh;

							// console.log( modX, $(this).outerWidth(), $(this).width(), $(this).height(), $(this)[0].style.width, $(this).outerHeight(), wh );

							if( ( nextSubPLevel === -1 && nextSubSlideDir !== 'new' ) || ( $(this).data('offsetxin') === 'left' || $(this).data('offsetxin') === 'right' ) ){
								if( lml < 0 ){
									lml = - ( endLeft + ( nextSubScaleX / 2 + .5 ) * modX + 100  );
								}else if( lml > 0 ){
									lml = ls.g.sliderWidth() - endLeft + ( nextSubScaleX / 2 - .5 ) * modX + 100;
								}
							}else{
								lml = lml * ls.g.ratio;
							}

							if( ( nextSubPLevel === -1 && nextSubSlideDir !== 'new' ) || ( $(this).data('offsetyin') === 'top' || $(this).data('offsetyin') === 'bottom' ) ){

								if( lmt < 0 ){
									lmt = - ( endTop + ( nextSubScaleY / 2 + .5 ) * modY + 100  );
								}else if( lmt > 0 ){
									lmt = ls.g.sliderHeight() - endTop + ( nextSubScaleY / 2 - .5 ) * modY + 100;
								}
							}else{
								lmt = lmt * ls.g.ratio;
							}

							if( nextSubPLevel === -1 || nextSubSlideDir === 'new'){
								var nextSubPar = 1;
							}else{
								var nextSubParMod = ls.g.nextLayer.data('parallaxin') ? parseInt(ls.g.nextLayer.data('parallaxin')) : ls.o.parallaxIn;
								var nextSubPar = nextSubPLevel * nextSubParMod;
							}

							if( $(this).data('transitiontype') === 'new' ){
								var deI = ls.lt.delayIn;
								var duI = ls.lt.durationIn;
								var eI = ls.lt.easingIn;
							}else{
								var deI = ls.o.delayIn;
								var duI = ls.o.durationIn;
								var eI = ls.o.easingIn;
							}

							var nextSubDelay = $(this).data('delayin') ? parseInt($(this).data('delayin')) : deI;
							var nextSubTime = $(this).data('durationin') ? parseInt($(this).data('durationin')) : duI;
							var nextSubEasing = $(this).data('easingin') ? $(this).data('easingin') : eI;

							var cursub = $(this);

							var nextSubCallback = function(){

								// BUGFIX v5.1.0 Removing transition property from video layers

								if( cursub.hasClass('ls-video-layer') ){
									cursub.addClass('ls-videohack');
								}

								// NEW FEATURE v2.0 autoPlayVideos

								if( ls.o.autoPlayVideos == true ){

									// YouTube & Vimeo videos

									cursub.find('.ls-videopreview').click();
									// HTML5 videos

									cursub.find('video, audio').each(function(){
										if( typeof $(this)[0].currentTime !== 0){
											$(this)[0].currentTime = 0;
										}

										$(this).click();
									});
								}

								// NEW FEATURE v3.0 showUntil sublayers
								// IMPROVEMENT v5.2.0 video layers with auto play will skip showuntil feature

								if( ( !cursub.hasClass('ls-video-layer') || ( cursub.hasClass('ls-video-layer') && ls.o.autoPlayVideos === false ) ) && cursub.data('showuntil') > 0 ){

									// IMPROVEMENT v4.5.0 sublayerShowUntil will be called anly if necessary

									cursub.data('showUntilTimer', setTimeout(function(){
										ls.sublayerShowUntil( cursub );
									}, cursub.data('showuntil') ));
								}
							};

							$(this).css({
								marginLeft : 0,
								marginTop : 0
							});

							var css = {
								scaleX : nextSubScaleX,
								scaleY : nextSubScaleY,
								skewX : nextSubSkewX,
								skewY : nextSubSkewY,
								rotation : nextSubRotate,
								rotationX : nextSubRotateX,
								rotationY : nextSubRotateY,
								visibility : 'visible',
								x : lml * nextSubPar,
								y : lmt * nextSubPar
							};

							var transition = {
								rotation : 0,
								rotationX : 0,
								rotationY : 0,
								skewX : 0,
								skewY : 0,
								scaleX : 1,
								scaleY : 1,
								ease : lsConvertEasing( nextSubEasing ),
								delay : nextSubDelay/1000,
								x : 0,
								y : 0,
								onComplete : function(){
									nextSubCallback();
								}
							};

							if( nextSubSlideDir.indexOf('fade') != -1 || ( $(this).data('fadein') !== 'false' && $(this).data('transitiontype') === 'new' ) ){

								css['opacity'] = 0;
								transition['opacity'] = $(this).data( 'originalOpacity' );
							}

							// $(this).css( css );

							// $(this).stop().delay( curDelay + nextDelay + nextSubDelay ).animate( transition, nextSubTime, nextSubEasing, function(){
							// 	if( ls.g.ie78 & $(this).data( 'originalOpacity') === 1 ){
							// 		$(this).get(0).style.removeAttribute('filter');
							// 	}
							// 	nextSubCallback();
							// });

							if( $(this).data('tr') ){
								$(this).data('tr').kill();
							}

							TweenLite.set( $(this)[0],{
								transformPerspective : nextSubPerspective,
								transformOrigin : nextSubTransformOrigin
							});

							$(this).data('tr', TweenLite.fromTo($(this)[0],nextSubTime/1000,css,transition) );
						});
					};

			/* NEW FEATURE v4.0 2D & 3D Layer Transitions */

					// Selecting ONE transition (random)
					// If the browser doesn't support CSS3 3D, 2D fallback mode will be used instead
					// In this case, if user didn't specify any 2D transitions, a random will be selected

					var selectTransition = function(){

						// if the browser supports CSS3 3D and user specified at least one of 3D transitions

						if( lsSupport3D( $(el) ) && ( ls.g.nextLayer.data('transition3d') || ls.g.nextLayer.data('customtransition3d') ) ){

							if( ls.g.nextLayer.data('transition3d') && ls.g.nextLayer.data('customtransition3d') ){
								var rnd = Math.floor(Math.random() * 2);
								var rndT = [['3d',ls.g.nextLayer.data('transition3d')],['custom3d',ls.g.nextLayer.data('customtransition3d')]];
								getTransitionType(rndT[rnd][0],rndT[rnd][1]);
							}else if( ls.g.nextLayer.data('transition3d') ){
								getTransitionType('3d',ls.g.nextLayer.data('transition3d'));
							}else{
								getTransitionType('custom3d',ls.g.nextLayer.data('customtransition3d'));
							}

						}else{

							if( ls.g.nextLayer.data('transition2d') && ls.g.nextLayer.data('customtransition2d') ){
								var rnd = Math.floor(Math.random() * 2);
								var rndT = [['2d',ls.g.nextLayer.data('transition2d')],['custom2d',ls.g.nextLayer.data('customtransition2d')]];
								getTransitionType(rndT[rnd][0],rndT[rnd][1]);
							}else if( ls.g.nextLayer.data('transition2d') ){
								getTransitionType('2d',ls.g.nextLayer.data('transition2d'));
							}else if( ls.g.nextLayer.data('customtransition2d') ){
								getTransitionType('custom2d',ls.g.nextLayer.data('customtransition2d'));
							}else{
								getTransitionType('2d','1');
							}
						}
					};

					// Needed by the demo page

					var selectCustomTransition = function(){

						if( lsSupport3D( $(el) ) && LSCustomTransition.indexOf('3d') != -1 ){
							getTransitionType('3d',LSCustomTransition.split(':')[1]);
						}else{
							if( LSCustomTransition.indexOf('3d') != -1){
								getTransitionType('2d','all');
							}else{
								getTransitionType('2d',LSCustomTransition.split(':')[1]);
							}
						}
					};

					// Choosing layer transition type (2d, 3d, or both)

					var getTransitionType = function(type,transitionlist){

						var tr = type.indexOf('custom') == -1 ? ls.t : ls.ct;
						var tt = '3d', lt, number;

						if( type.indexOf('2d') != -1 ){
							tt = '2d';
						}

						if( transitionlist.indexOf('last') != -1 ){
							number = tr['t'+tt].length-1;
							lt = 'last';
						}else if( transitionlist.indexOf('all') != -1){
							number = Math.floor(Math.random() * lsCountProp(tr['t'+tt]) );
							lt = 'random from all';
						}else{
							var t = transitionlist.split(',');
							var l = t.length;
							number = parseInt(t[Math.floor(Math.random() * l)])-1;
							lt = 'random from specified';
						}

						slideTransition(tt,tr['t'+tt][number]);

//						$('.test').html('Originals:<br><br>t3D: '+ls.g.nextLayer.data('transition3d')+'<br>t2D: '+ls.g.nextLayer.data('transition2d')+'<br>custom3D: '+ls.g.nextLayer.data('customtransition3d')+'<br>custom2D: '+ls.g.nextLayer.data('customtransition2d')+'<br><br>Support 3D: '+lsSupport3D( $(el) )+'<br><br>Selected transition:<br><br>Type: '+type+' ('+lt+')<br>Number in transition list: '+(number+1)+'<br>Name of the transition: '+tr['t'+tt][number]['name']);
					};

					// The slideTransition function

					var slideTransition = function(type,prop){

						var inner = ls.g.i;

						// sublayersDurationOut - for future usage

						var sublayersDurationOut = ls.g.curLayer.find('*[class*="ls-l"]').length > 0 ? 1000 : 0;

						// Detecting a carousel transition - Transition name must have the carousel string

						var carousel = prop.name.toLowerCase().indexOf('carousel') == -1 ? false : true;

						// Detecting a crossfade transition - Transition name must have the crossfad string

						var crossfade = prop.name.toLowerCase().indexOf('crossfad') == -1 ? false : true;

						// Calculating cols and rows

						var cols = typeof(prop.cols);
						var rows = typeof(prop.rows);

						switch( cols ){
							case 'number':
								cols = prop.cols;
							break;
							case 'string':
								cols = Math.floor( Math.random() * ( parseInt( prop.cols.split(',')[1] ) - parseInt( prop.cols.split(',')[0] ) + 1) ) + parseInt( prop.cols.split(',')[0] );
							break;
							default:
								cols = Math.floor( Math.random() * ( prop.cols[1] - prop.cols[0] + 1) ) + prop.cols[0];
							break;
						}

						switch( rows ){
							case 'number':
								rows = prop.rows;
							break;
							case 'string':
								rows = Math.floor( Math.random() * ( parseInt( prop.rows.split(',')[1] ) - parseInt( prop.rows.split(',')[0] ) + 1) ) + parseInt( prop.rows.split(',')[0] );
							break;
							default:
								rows = Math.floor( Math.random() * ( prop.rows[1] - prop.rows[0] + 1) ) + prop.rows[0];
							break;
						}

						if( ( ls.g.isMobile() == true && ls.o.optimizeForMobile == true ) || ( ls.g.ie78 && ls.o.optimizeForIE78 == true ) ){

							// Reducing cols in three steps

							if( cols >= 15 ){
								cols = 7;
							}else if( cols >= 5 ){
								cols = 4;
							}else if( cols >= 4 ){
								cols = 3;
							}else if( cols > 2 ){
								cols = 2;
							}

							// Reducing rows in three steps

							if( rows >= 15 ){
								rows = 7;
							}else if( rows >= 5 ){
								rows = 4;
							}else if( rows >= 4 ){
								rows = 3;
							}else if( rows > 2 ){
								rows = 2;
							}

							// Reducing more :)

							if( rows > 2 && cols > 2 ){
								rows = 2;
								if( cols > 4){
									cols = 4;
								}
							}
						}

						var tileWidth = ls.g.i.width() / cols;
						var tileHeight = ls.g.i.height() / rows;

						// Creating HTML markup for layer transitions

						if( !ls.g.ltContainer ){
							ls.g.ltContainer = $('<div>').addClass('ls-lt-container').addClass('ls-overflow-hidden').css({
								width : inner.width(),
								height : inner.height()
							}).prependTo( inner );
						}else{
							ls.g.ltContainer.stop(true,true).empty().css({
								display : 'block',
								width : inner.width(),
								height : inner.height()
							});
						}

						// Setting size

						var restW = inner.width() - Math.floor(tileWidth) * cols;
						var restH = inner.height() - Math.floor(tileHeight) * rows;

						var tileSequence = [];

						// IMPROVEMENT v4.1.3 Array-randomizer is now a local function
						// Randomize array function

						tileSequence.randomize = function() {
						  var i = this.length, j, tempi, tempj;
						  if ( i == 0 ) return false;
						  while ( --i ) {
						     j       = Math.floor( Math.random() * ( i + 1 ) );
						     tempi   = this[i];
						     tempj   = this[j];
						     this[i] = tempj;
						     this[j] = tempi;
						  }
						  return this;
						}

						for(var ts=0; ts<cols * rows; ts++){
							tileSequence.push(ts);
						}

						// Setting the sequences of the transition

						switch( prop.tile.sequence ){
							case 'reverse':
								tileSequence.reverse();
							break;
							case 'col-forward':
								tileSequence = lsOrderArray(rows,cols,'forward');
							break;
							case 'col-reverse':
								tileSequence = lsOrderArray(rows,cols,'reverse');
							break;
							case 'random':
								tileSequence.randomize();
							break;
						}

						var curBG = ls.g.curLayer.find('.ls-bg');
						var nextBG = ls.g.nextLayer.find('.ls-bg');

						// IMPROVEMENT v4.6.0 If current and next layer both have no BG, skipping the slide transition

						if( curBG.length == 0 && nextBG.length == 0 ){
							type = '2d';
							prop = $.extend(true, {}, ls.t['t2d'][0]);
							prop.transition.duration = 1
							prop.tile.delay = 0;
						}

						if( type == '3d' ){
							ls.g.totalDuration = ((cols * rows) - 1) * prop.tile.delay;

							var stepDuration = 0;

							if( prop.before && prop.before.duration ){
								stepDuration += prop.before.duration;
							}
							if( prop.animation && prop.animation.duration ){
								stepDuration += prop.animation.duration;
							}
							if( prop.after && prop.after.duration ){
								stepDuration += prop.after.duration;
							}

							ls.g.totalDuration += stepDuration;

							var stepDelay = 0;

							if( prop.before && prop.before.delay ){
								stepDelay += prop.before.delay;
							}
							if( prop.animation && prop.animation.delay ){
								stepDelay += prop.animation.delay;
							}
							if( prop.after && prop.after.delay ){
								stepDelay += prop.after.delay;
							}

							ls.g.totalDuration += stepDelay;

						}else{
							ls.g.totalDuration = ((cols * rows) - 1) * prop.tile.delay + prop.transition.duration;

							// IMPROVEMENT v4.5.0 Creating separated containers for current and next tiles

							ls.g.curTiles = $('<div>').addClass('ls-curtiles').appendTo( ls.g.ltContainer );
							ls.g.nextTiles = $('<div>').addClass('ls-nexttiles').appendTo( ls.g.ltContainer );
						}

						var pn = ls.g.prevNext;

						// Creating cuboids for 3d or tiles for 2d transition (cols * rows)

						for(var tiles=0; tiles < cols * rows; tiles++){

							var rW = tiles%cols == 0 ? restW : 0;
							var rH = tiles > (rows-1)*cols-1 ? restH : 0;

							var tile = $('<div>').addClass('ls-lt-tile').css({
								width : Math.floor(tileWidth) + rW,
								height : Math.floor(tileHeight) + rH
							}).appendTo( ls.g.ltContainer );

							var curTile, nextTile;

							// If current transition is a 3d transition

							if( type == '3d' ){

								tile.addClass('ls-3d-container');

								var W = Math.floor(tileWidth) + rW;
								var H = Math.floor(tileHeight) + rH;
								var D;

								if( prop.animation.direction == 'horizontal' ){
									if( Math.abs(prop.animation.transition.rotateY) > 90 && prop.tile.depth != 'large' ){
										D = Math.floor( W / 7 ) + rW;
									}else{
										D = W;
									}
								}else{
									if( Math.abs(prop.animation.transition.rotateX) > 90 && prop.tile.depth != 'large' ){
										D = Math.floor( H / 7 ) + rH;
									}else{
										D = H;
									}
								}

								var W2 = W/2;
								var H2 = H/2;
								var D2 = D/2;

								// createCuboids function will append cuboids with their style settings to their container

								// BUGFIX v5.1.2 the prefixless transform must be the last property

								var createCuboids = function(c,a,w,h,tx,ty,tz,rx,ry){
									$('<div>').addClass(c).css({
										width: w,
										height: h,
										'-o-transform': 'translate3d('+tx+'px, '+ty+'px, '+tz+'px) rotateX('+rx+'deg) rotateY('+ry+'deg) rotateZ(0deg) scale3d(1, 1, 1)',
										'-ms-transform': 'translate3d('+tx+'px, '+ty+'px, '+tz+'px) rotateX('+rx+'deg) rotateY('+ry+'deg) rotateZ(0deg) scale3d(1, 1, 1)',
										'-moz-transform': 'translate3d('+tx+'px, '+ty+'px, '+tz+'px) rotateX('+rx+'deg) rotateY('+ry+'deg) rotateZ(0deg) scale3d(1, 1, 1)',
										'-webkit-transform': 'translate3d('+tx+'px, '+ty+'px, '+tz+'px) rotateX('+rx+'deg) rotateY('+ry+'deg) rotateZ(0deg) scale3d(1, 1, 1)',
										'transform': 'translate3d('+tx+'px, '+ty+'px, '+tz+'px) rotateX('+rx+'deg) rotateY('+ry+'deg) rotateZ(0deg) scale3d(1, 1, 1)'
									}).appendTo(a);
								};

								createCuboids('ls-3d-box',tile,0,0,0,0,-D2,0,0);

								var backRotX = 0
								var topRotX = 0
								var bottomRotX = 0

								if( prop.animation.direction == 'vertical' && Math.abs(prop.animation.transition.rotateX) > 90){
									createCuboids('ls-3d-back',tile.find('.ls-3d-box'),W,H,-W2,-H2,-D2,180,0);
								}else{
									createCuboids('ls-3d-back',tile.find('.ls-3d-box'),W,H,-W2,-H2,-D2,0,180);
								}

								createCuboids('ls-3d-bottom',tile.find('.ls-3d-box'),W,D,-W2,H2-D2,0,-90,0);
								createCuboids('ls-3d-top',tile.find('.ls-3d-box'),W,D,-W2,-H2-D2,0,90,0);
								createCuboids('ls-3d-front',tile.find('.ls-3d-box'),W,H,-W2,-H2,D2,0,0);
								createCuboids('ls-3d-left',tile.find('.ls-3d-box'),D,H,-W2-D2,-H2,0,0,-90);
								createCuboids('ls-3d-right',tile.find('.ls-3d-box'),D,H,W2-D2,-H2,0,0,90);

								curTile = tile.find('.ls-3d-front');

								if( prop.animation.direction == 'horizontal' ){
									if( Math.abs(prop.animation.transition.rotateY) > 90 ){
										nextTile = tile.find('.ls-3d-back');
									}else{
										nextTile = tile.find('.ls-3d-left, .ls-3d-right');
									}
								}else{
									if( Math.abs(prop.animation.transition.rotateX) > 90 ){
										nextTile = tile.find('.ls-3d-back');
									}else{
										nextTile = tile.find('.ls-3d-top, .ls-3d-bottom');
									}
								}

								// Animating cuboids

								var curCubDelay = tileSequence[tiles] * prop.tile.delay;

								var curCub = ls.g.ltContainer.find('.ls-3d-container:eq('+tiles+') .ls-3d-box');

								var tl = new TimelineLite();

								if( prop.before && prop.before.transition ){
									prop.before.transition.delay = prop.before.transition.delay ? (prop.before.transition.delay + curCubDelay)/1000 : curCubDelay/1000;
									tl.to( curCub[0],prop.before.duration/1000,lsConvertTransition( prop.before.transition, prop.before.easing ));
								}else{
									prop.animation.transition.delay = prop.animation.transition.delay ? (prop.animation.transition.delay + curCubDelay)/1000 : curCubDelay/1000;
								}

								tl.to( curCub[0],prop.animation.duration/1000,lsConvertTransition( prop.animation.transition, prop.animation.easing ));

								if( prop.after ){
									if( !prop.after.transition ){
										prop.after.transition = {};
									}
									tl.to( curCub[0],prop.after.duration/1000,lsConvertTransition( prop.after.transition, prop.after.easing, 'after' ));
								}

							}else{

								// If current transition is a 2d transition

								var T1 = L1 = T2 = L2 = 'auto';
								var O1 = O2 = 1;

								if( prop.transition.direction == 'random' ){
									var dir = ['top','bottom','right','left'];
									var direction = dir[Math.floor(Math.random() * dir.length )];
								}else{
									var direction = prop.transition.direction;
								}

								// IMPROVEMENT v4.5.0 Reversing animation directions if slider is moving backwards

								if( prop.name.toLowerCase().indexOf('mirror') != -1 && tiles%2 == 0 ){
									if( pn == 'prev' ){
										pn = 'next';
									}else{
										pn = 'prev';
									}
								}

								if( pn == 'prev' ){

									switch( direction ){
										case 'top':
											direction = 'bottom';
										break;
										case 'bottom':
											direction = 'top';
										break;
										case 'left':
											direction = 'right';
										break;
										case 'right':
											direction = 'left';
										break;
										case 'topleft':
											direction = 'bottomright';
										break;
										case 'topright':
											direction = 'bottomleft';
										break;
										case 'bottomleft':
											direction = 'topright';
										break;
										case 'bottomright':
											direction = 'topleft';
										break;
									}
								}

								switch( direction ){
									case 'top':
										T1 = T2 = -tile.height();
										L1 = L2 = 0;
									break;
									case 'bottom':
										T1 = T2 = tile.height();
										L1 = L2 = 0;
									break;
									case 'left':
										T1 = T2 = 0;
										L1 = L2 = -tile.width();
									break;
									case 'right':
										T1 = T2 = 0;
										L1 = L2 = tile.width();
									break;
									case 'topleft':
										T1 = tile.height();
										T2 = 0;
										L1 = tile.width();
										L2 = 0;
									break;
									case 'topright':
										T1 = tile.height();
										T2 = 0;
										L1 = - tile.width();
										L2 = 0;
									break;
									case 'bottomleft':
										T1 = - tile.height();
										T2 = 0;
										L1 = tile.width();
										L2 = 0;
									break;
									case 'bottomright':
										T1 = - tile.height();
										T2 = 0;
										L1 = - tile.width();
										L2 = 0;
									break;
								}

								ls.g.scale2D = prop.transition.scale ? prop.transition.scale : 1;

								if( carousel == true && ls.g.scale2D != 1 ){

									T1 = T1 / 2;
									T2 = T2 / 2;
									L1 = L1 / 2;
									L2 = L2 / 2;
								}

								// Selecting the type of the transition

//								if( !ls.g.ie78 || ( ls.g.ie78 && !ls.o.optimizeForIE78 ) ||  ( ls.g.ie78 && ls.o.optimizeForIE78 == true && prop.name.toLowerCase().indexOf('crossfade') != -1 ) ){
									switch( prop.transition.type ){
										case 'fade':
											T1 = T2 = L1 = L2 = 0;
											O1 = 0;
											O2 = 1;
										break;
										case 'mixed':
										O1 = 0;
										O2 = 1;
										if( ls.g.scale2D == 1 ){
											T2 = L2 = 0;
										}
										break;
									}
//								}

								// IMPROVEMENT v4.5.0 Implemented Rotation and Scale into 2D Transitions

								if((( prop.transition.rotate || prop.transition.rotateX || prop.transition.rotateY ) || ls.g.scale2D != 1 ) && !ls.g.ie78 && prop.transition.type != 'slide' ){
									tile.css({
										overflow : 'visible'
									});
								}else{
									tile.css({
										overflow : 'hidden'
									});
								}

								if( carousel == true){
									ls.g.curTiles.css({
										overflow: 'visible'
									});
								}else{
									ls.g.curTiles.css({
										overflow: 'hidden'
									});
								}

								if( crossfade == true || prop.transition.type == 'slide' || carousel == true ){
									var tileInCur = tile.appendTo( ls.g.curTiles );
									var tileInNext = tile.clone().appendTo( ls.g.nextTiles );
									curTile = $('<div>').addClass('ls-curtile').appendTo( tileInCur );
								}else{
									var tileInNext = tile.appendTo( ls.g.nextTiles );
								}

								nextTile = $('<div>').addClass('ls-nexttile').appendTo( tileInNext ).css({
									top : -T1,
									left : -L1,
									dispay : 'block',
									opacity : O1
								});

								// Animating tiles

								var curTileDelay = tileSequence[tiles] * prop.tile.delay;

								// IMPROVEMENT v4.5.0 Implemented various types of rotations into 2D Transitions

								var r = prop.transition.rotate ? prop.transition.rotate : 0;
								var rX = prop.transition.rotateX ? prop.transition.rotateX : 0;
								var rY = prop.transition.rotateY ? prop.transition.rotateY : 0;

								// Reversing rotation degrees if slider is moving backwards

								if( pn == 'prev' ){
									r = -r;
									rX = -rX;
									rY = -rY;
								}

								TweenLite.fromTo(nextTile[0],prop.transition.duration/1000,{
									rotation : r,
									rotationX : rX,
									rotationY : rY,
									scale : ls.g.scale2D
								},{
									delay : curTileDelay / 1000,
									top : 0,
									left : 0,
									opacity : O2,
									rotation : 0,
									rotationX : 0,
									rotationY : 0,
									scale : 1,
									ease : lsConvertEasing( prop.transition.easing )
								});

								// IMPROVEMENT v5.0.0 Smart crossfading for semi-transparent PNG and different size JPG backgrounds

								if(
									crossfade == true && (
										nextBG.length < 1 || (
											nextBG.length > 0 && (
												nextBG.attr('src').toLowerCase().indexOf('png') != -1 || (
													nextBG.width() < ls.g.sliderWidth() || nextBG.height() < ls.g.sliderHeight()
												)
											)
										)
									)
								){
									TweenLite.to(curTile[0],prop.transition.duration/1000,{
										delay : curTileDelay / 1000,
										opacity : 0,
										ease : lsConvertEasing( prop.transition.easing )
									});
								}

								if( ( prop.transition.type == 'slide' || carousel == true ) && prop.name.toLowerCase().indexOf('mirror') == -1 ){

									var r2 = 0;

									if( r != 0 ){
										r2 = -r;
									}

									TweenLite.to(curTile[0],prop.transition.duration/1000,{
										delay : curTileDelay / 1000,
										top : T2,
										left : L2,
										rotation : r2,
										scale : ls.g.scale2D,
										opacity: O1,
										ease : lsConvertEasing( prop.transition.easing )
									});
								}
							}

							// Appending the background images of current and next layers into the tiles on both of 2d & 3d transitions
							// BUGFIX v5.0.0 added Math.floor to prevent '1px bug' under Safari and Firefox

							if( curBG.length ){
								if( type == '3d' || ( type == '2d' && ( crossfade == true || prop.transition.type == 'slide' || carousel == true ) ) ){
									curTile.append($('<img>').attr('src', curBG.attr('src')).css({
										width : curBG[0].style.width,
										height : curBG[0].style.height,
										marginLeft : parseFloat(curBG.css('margin-left')) - parseFloat(tile.position().left),
										marginTop : parseFloat(curBG.css('margin-top')) - parseFloat(tile.position().top)
									}));
								}else if( ls.g.curTiles.children().length == 0 ){
									ls.g.curTiles.append($('<img>').attr('src', curBG.attr('src')).css({
										width : curBG[0].style.width,
										height : curBG[0].style.height,
										marginLeft : parseFloat(curBG.css('margin-left')),
										marginTop : parseFloat(curBG.css('margin-top'))
									}));

								}
							}

							if( nextBG.length ){
								nextTile.append( $('<img>').attr('src', nextBG.attr('src')).css({
									width : nextBG[0].style.width,
									height : nextBG[0].style.height,
									marginLeft : parseFloat(nextBG.css('margin-left')) - parseFloat(tile.position().left),
									marginTop : parseFloat(nextBG.css('margin-top')) - parseFloat(tile.position().top)
								}));
							}
						}

						// Storing current and next layer elements in a local variable (needed by setTimeout functions in some cases)

						var curLayer = ls.g.curLayer;
						var nextLayer = ls.g.nextLayer;

						// Hiding the background image of the current and next layers (immediately)

						setTimeout(function(){
							curLayer.find('.ls-bg').css({
								visibility : 'hidden'
							});
						},50);

						nextLayer.find('.ls-bg').css({
							visibility : 'hidden'
						});
						ls.g.ltContainer.removeClass('ls-overflow-hidden');

						// Sliding out the sublayers of the current layer
						// (immediately, delay out and duration out properties are not applied to the sublayers during the new layer transitions)

						curSubLayers(sublayersDurationOut);

						// BUGFIX v5.2.0 prevents background flickering in some cases

						if( sublayersDurationOut === 0 ){
							sublayersDurationOut = 10;
						}

						// Hiding current layer after its sublayers animated out

						setTimeout(function(){
							curLayer.css({
								width: 0
							});
						}, sublayersDurationOut );

						// Calculating next layer delay

						var nextLayerTimeShift = parseInt(nextLayer.data('timeshift')) ? parseInt(nextLayer.data('timeshift')) : 0;
						var nextLayerDelay = ls.g.totalDuration + nextLayerTimeShift > 0 ? ls.g.totalDuration + nextLayerTimeShift : 0;

						// Showing next layer and sliding sublayers of the next layer in after the current layer transition ended

						setTimeout(function(){
							if( ls.g.resize == true ){
								ls.g.ltContainer.empty();
								curLayer.removeClass('ls-active');
								ls.makeResponsive( nextLayer, function(){
									ls.g.resize = false;
								});
							}

							// Sliding in / fading in the sublayers of the next layer

							nextSubLayers();

							// NEW FEATURE v4.6.0 Hiding background if the next layer has png BG or has no BG
							// BUGFIX v4.6.1 Changed some properties to prevent flickering

							if( nextLayer.find('.ls-bg').length < 1 || ( nextLayer.find('.ls-bg').length > 0 && nextLayer.find('.ls-bg').attr('src').toLowerCase().indexOf('png') != -1 ) ){

								ls.g.ltContainer.delay(350).fadeOut(300,function(){
									$(this).empty().show();
								});
							}

							// Displaying the next layer (immediately)

							nextLayer.css({
								width : ls.g.sliderWidth(),
								height : ls.g.sliderHeight()
							});
						}, nextLayerDelay );

						// BUGFIX v5.0.1 Added a minimal value of ls.g.totalDuration
						// CHANGED in v5.1.0 due to a fading issue in carousel transition

						if( ls.g.totalDuration < 300 ){
							ls.g.totalDuration = 1000;
						}

						// Changing visibility to visible of the background image of the next layer and overflow to hidden of .ls-lt-container after the transition and calling callback function

						setTimeout(function(){
							ls.g.ltContainer.addClass('ls-overflow-hidden');

							if( nextLayer.find('.ls-bg').length ){

								nextLayer.find('.ls-bg').css({
									display : 'none',
									visibility : 'visible'
								});
								if( ls.g.ie78 ){
									nextLayer.find('.ls-bg').css('display','block');
									setTimeout(function(){
										curLayerCallback();
									},500);
								}else{
									nextLayer.find('.ls-bg').fadeIn(500, function(){
										curLayerCallback();
									});
								}
							}else{
								curLayerCallback();
							}

						}, ls.g.totalDuration );
					};



			/* Selecting and running the transition */

					// NEW FEATURE v5.2.0 Starts the slider only if it is in the viewport

					var startInViewport = function(){

						ls.g.nextLayer.find(' > *[class*="ls-l"]').each(function(){

							$(this).css({
								visibility : 'hidden'
							});
						});

						ls.g.sliderTop = $(el).offset().top;

						$(window).load(function(){
							setTimeout(function(){

								ls.g.sliderTop = $(el).offset().top;
							}, 20);
						});

						var isSliderInViewport = function(){
							if( $(window).scrollTop() + $(window).height() - ( ls.g.sliderHeight() / 2 ) > ls.g.sliderTop ){
								ls.g.firstSlideAnimated = true;
								if( ls.g.originalAutoStart === true ){
									//ls.g.autoSlideshow = true;
								 	ls.o.autoStart = true;
								 	ls.start();
								}
								nextSubLayers();
							}
						}

						$(window).scroll(function(){
							if( !ls.g.firstSlideAnimated ){
								isSliderInViewport();
							}
						});

						isSliderInViewport();
					};

					var tType = ( ( ls.g.nextLayer.data('transition3d') || ls.g.nextLayer.data('transition2d') ) && ls.t ) || ( ( ls.g.nextLayer.data('customtransition3d') || ls.g.nextLayer.data('customtransition2d') ) && ls.ct ) ? 'new' : 'old';

					if( !ls.g.nextLayer.data('transitiontype') ){
						ls.transitionType( ls.g.nextLayer );
					}

					if( ls.g.nextLayer.data('transitiontype') === 'new' ){
						tType = 'new';
					}

					if( ls.o.slideTransition ){
						tType = 'forced';
					}

					if( ls.o.animateFirstSlide && !ls.g.firstSlideAnimated ){

						// BUGFIX v3.5 there is no need to animate 'current' layer if the following conditions are true
						//			   this fixes the sublayer animation direction bug

						if( ls.g.layersNum == 1 ){
							var curDelay = 0;

							// IMPROVEMENT v4.1.0 Calling cbAnimStop(); function if only one layer is in the slider

							ls.o.cbAnimStop(ls.g);

						}else{
							var nextLayerTimeShift = parseInt(ls.g.nextLayer.data('timeshift')) ? parseInt(ls.g.nextLayer.data('timeshift')) : 0;
							var d = tType == 'new' ? 0 : curDuration;
							ls.g.t5 = setTimeout(function(){
								curLayerCallback();
							}, d + Math.abs(nextLayerTimeShift) );
						}

						// curDelay must be 0!

						ls.g.totalDuration = true;

						// Animating SUBLAYERS of the first layer

						if( ls.o.startInViewport === true ){

							startInViewport();
						}else{

							ls.g.firstSlideAnimated = true;
							nextSubLayers();
						}

						// Displaying the first layer (immediately)

						ls.g.nextLayer.css({
							width : ls.g.sliderWidth(),
							height : ls.g.sliderHeight()
						});

						if( !ls.g.ie78 ){
							ls.g.nextLayer.find('.ls-bg').css({
								display : 'none'
							}).fadeIn(ls.o.sliderFadeInDuration);
						}

						ls.g.isLoading = false;
					}else{

						switch(tType){

							// Old transitions (sliding layers)

							case 'old':

								ls.g.totalDuration = false;

								// BUGFIX v4.5.0 Removing elements from ls-lt-container is necessary

								if( ls.g.ltContainer ){
									ls.g.ltContainer.empty();
								}

								// Animating CURRENT LAYER and its SUBLAYERS

								curLayer();
								curSubLayers();

								// Animating NEXT LAYER and its SUBLAYERS

								nextLayer();
								nextSubLayers();
							break;

							// NEW FEATURE v4.0 2D & 3D Layer Transitions

							case 'new':

								if( typeof LSCustomTransition != 'undefined' ){
									selectCustomTransition();
								}else{
									selectTransition();
								}
							break;

							case 'forced':
								slideTransition( ls.o.slideTransition.type, ls.o.slideTransition.obj );
							break;
						}
					}
		};

		ls.transitionType = function( el ){

			var ttype =  el.data('ls') ||
								( 	!el.data('ls') &&
									!el.data('slidedelay') &&
									!el.data('slidedirection') &&
									!el.data('slideoutdirection') &&
									!el.data('delayin') &&
									!el.data('delayout') &&
									!el.data('durationin') &&
									!el.data('durationout') &&
									!el.data('showuntil') &&
									!el.data('easingin') &&
									!el.data('easingout') &&
									!el.data('scalein') &&
									!el.data('scaleout') &&
									!el.data('rotatein') &&
									!el.data('rotateout')
								) ? 'new' : 'old';
			el.data('transitiontype', ttype);
		};

		ls.sublayerShowUntil = function( sublayer ){

			if( !sublayer.data('transitiontype') ){
				ls.transitionType( sublayer );
			}

			// BUGFIX v5.1.0 Removing ls-videohack class before starting transition

			sublayer.removeClass('ls-videohack');

			var prevOrNext = ls.g.curLayer;

			if( ls.g.prevNext != 'prev' && ls.g.nextLayer ){
				prevOrNext = ls.g.nextLayer;
			}

			var chooseDirection = prevOrNext.data('slidedirection') ? prevOrNext.data('slidedirection') : ls.o.slideDirection;

			// Setting the direction of sliding

			var slideDirection = ls.g.slideDirections[ls.g.prevNext][chooseDirection];

			var curSubSlideDir = sublayer.data('slidedirection') ? sublayer.data('slidedirection') : slideDirection;
			var lml, lmt;

			switch(curSubSlideDir){
				case 'left':
					lml = -ls.g.sliderWidth();
					lmt = 0;
					break;
				case 'right':
					lml = ls.g.sliderWidth();
					lmt = 0;
					break;
				case 'top':
					lmt = -ls.g.sliderHeight();
					lml = 0;
					break;
				case 'bottom':
					lmt = ls.g.sliderHeight();
					lml = 0;
					break;
				case 'fade':
					lmt = 0;
					lml = 0;
					break;
			}

			// NEW FEATURE v1.6 added slideoutdirection to sublayers
			// NEW FEATURES 5.0.0 added axis-free transitions with offsetx and offsety properties

			if( sublayer.data('transitiontype') === 'new' ){
				var curSubSlideOutDir = 'new';
			}else{
				var curSubSlideOutDir = sublayer.data('slideoutdirection') ? sublayer.data('slideoutdirection') : false;
			}

			switch(curSubSlideOutDir){
				case 'left':
					lml = ls.g.sliderWidth();
					lmt = 0;
					break;
				case 'right':
					lml = -ls.g.sliderWidth();
					lmt = 0;
					break;
				case 'top':
					lmt = ls.g.sliderHeight();
					lml = 0;
					break;
				case 'bottom':
					lmt = -ls.g.sliderHeight();
					lml = 0;
					break;
				case 'fade':
					lmt = 0;
					lml = 0;
					break;
				case 'new':
					if( sublayer.data('offsetxout') ){
						if( sublayer.data('offsetxout') === 'left' ){
							lml = ls.g.sliderWidth();
						}else if( sublayer.data('offsetxout') === 'right' ){
							lml = -ls.g.sliderWidth();
						}else{
							lml = -parseInt( sublayer.data('offsetxout') );
						}
					}else{
						lml = -ls.lt.offsetXOut;
					}
					if( sublayer.data('offsetyout') ){
						if( sublayer.data('offsetyout') === 'top' ){
							lmt = ls.g.sliderHeight();
						}else if( sublayer.data('offsetyout') === 'bottom' ){
							lmt = -ls.g.sliderHeight();
						}else{
							lmt = -parseInt( sublayer.data('offsetyout') );
						}
					}else{
						lmt = -ls.lt.offsetYOut;
					}
					break;
			}

			// NEW FEATURE v4.5.0 Rotating & Scaling sublayers
			// BUGFIX v4.5.5 changing the default value from 0 to 'none' (because of old jQuery, 1.7.2)
			// NEW FEATURES v5.0.0 Added SkewX, SkewY, ScaleX, ScaleY, RotateX & RotateY transitions

			var curSubRotate = curSubRotateX = curSubRotateY = curSubScale = curSubSkewX = curSubSkewY = curSubScaleX = curSubScaleY = 'none';
//			if( !ls.g.ie78 && ls.g.enableCSS3 ){
				curSubRotate = sublayer.data('rotateout') ? sublayer.data('rotateout') : ls.lt.rotateOut;
				curSubRotateX = sublayer.data('rotatexout') ? sublayer.data('rotatexout') : ls.lt.rotateXOut;
				curSubRotateY = sublayer.data('rotateyout') ? sublayer.data('rotateyout') : ls.lt.rotateYOut;
				curSubScale = sublayer.data('scaleout') ? sublayer.data('scaleout') : ls.lt.scaleOut;
				curSubSkewX = sublayer.data('skewxout') ? sublayer.data('skewxout') : ls.lt.skewXOut;
				curSubSkewY = sublayer.data('skewyout') ? sublayer.data('skewyout') : ls.lt.skewYOut;
				if( curSubScale === 1 ){
					curSubScaleX = sublayer.data('scalexout') ? sublayer.data('scalexout') : ls.lt.scaleXOut;
					curSubScaleY = sublayer.data('scaleyout') ? sublayer.data('scaleyout') : ls.lt.scaleYOut;
				}else{
					curSubScaleX = curSubScaleY = curSubScale;
				}
				var too = sublayer.data('transformoriginout') ? sublayer.data('transformoriginout').split(' ') : ls.lt.transformOriginOut;

				for(var t =0;t<too.length;t++){
					if( too[t].indexOf('%') === -1 && too[t].indexOf('left') !== -1 && too[t].indexOf('right') !== -1 && too[t].indexOf('top') !== -1 && too[t].indexOf('bottom') !== -1 ){
						too[t] = '' + parseInt( too[t] ) * ls.g.ratio + 'px';
					}
				}
				var curSubTransformOrigin = too.join(' ');
				var curSubPerspective = sublayer.data('perspectiveout') ? sublayer.data('perspectiveout') : ls.lt.perspectiveOut;

//			}

			// IMPROVEMENT v4.0 Distance (P.level): -1

			var endLeft = parseInt( sublayer.css('left') );
			var endTop = parseInt( sublayer.css('top') );

			var curSubPLevel = parseInt( sublayer.attr('class').split('ls-l')[1] );

			var wh = sublayer.outerWidth() > sublayer.outerHeight() ? sublayer.outerWidth() : sublayer.outerHeight();
			var modX = parseInt( curSubRotate ) === 0 ? sublayer.outerWidth() : wh;
			var modY = parseInt( curSubRotate ) === 0 ? sublayer.outerHeight() : wh;

			if( ( curSubPLevel === -1 && curSubSlideOutDir !== 'new' ) || ( sublayer.data('offsetxout') === 'left' || sublayer.data('offsetxout') === 'right' ) ){
				if( lml < 0 ){
					lml = - ( ls.g.sliderWidth() - endLeft + ( curSubScaleX / 2 - .5 ) * modX + 100  );
				}else if( lml > 0 ){
					lml = endLeft + ( curSubScaleX / 2 + .5 ) * modX + 100;
				}
			}else{
				lml = lml * ls.g.ratio;
			}

			if( ( curSubPLevel === -1 && curSubSlideOutDir !== 'new' ) || ( sublayer.data('offsetyout') === 'top' || sublayer.data('offsetyout') === 'bottom' ) ){
				if( lmt < 0 ){
					lmt = - ( ls.g.sliderHeight() - endTop + ( curSubScaleY / 2 - .5 ) * modY + 100  );
				}else if( lmt > 0 ){
					lmt = endTop + ( curSubScaleY / 2 + .5 ) * modY + 100;
				}
			}else{
				lmt = lmt * ls.g.ratio;
			}

			if( curSubPLevel === -1 || curSubSlideOutDir === 'new' ){
				var curSubPar = 1;
			}else{
				var curSubParMod = ls.g.curLayer.data('parallaxout') ? parseInt(ls.g.curLayer.data('parallaxout')) : ls.o.parallaxOut;
				var curSubPar = curSubPLevel * curSubParMod;
			}

//			var curSubDelay = parseInt( sublayer.data('showuntil') );

			if( sublayer.data('transitiontype') === 'new' ){
				var duO = ls.lt.durationOut;
				var eO = ls.lt.easingOut;
			}else{
				var duO = ls.o.durationOut;
				var eO = ls.o.easingOut;
			}

			var curSubTime = sublayer.data('durationout') ? parseInt(sublayer.data('durationout')) : duO;

			// BUGFIX v5.2.0 duration cannot be 0

			if( curSubTime === 0 ){ curSubTime = 1 }
			var curSubEasing = sublayer.data('easingout') ? sublayer.data('easingout') : eO;

			var css = {
				visibility : 'hidden'
			};

			var transition = {
				rotation : curSubRotate,
				rotationX : curSubRotateX,
				rotationY : curSubRotateY,
				skewX : curSubSkewX,
				skewY : curSubSkewY,
				scaleX : curSubScaleX,
				scaleY : curSubScaleY,
				x : -lml * curSubPar,
				y : -lmt * curSubPar,
				ease : lsConvertEasing( curSubEasing ),
				onComplete : function(){
					sublayer.css( css );
				}
			};

			if( curSubSlideOutDir == 'fade' || ( !curSubSlideOutDir && curSubSlideDir == 'fade' ) || ( sublayer.data('fadeout') !== 'false' && sublayer.data('transitiontype') === 'new' ) ){
				transition['opacity'] = 0;
				css['opacity'] = sublayer.data( 'originalOpacity' );
			}

			TweenLite.set( sublayer[0],{
				transformPerspective : curSubPerspective,
				transformOrigin : curSubTransformOrigin
			});

			TweenLite.to(sublayer[0],curSubTime/1000,transition);

			// sublayer.stop(true,false).animate( transition, curSubTime, curSubEasing,function(){
			// 	sublayer.css( css );
			// });
		};

		// v3.6 Improved Debug Mode

// 		ls.debug = function(){

// 			ls.d = {
// 				history : $('<div>'),
// 				// adds a H1 (title)
// 				aT : function(content){
// 					$('<h1>'+content+'</h1>').appendTo( ls.d.history );
// 				},
// 				// adds an empty UL
// 				aeU : function(){
// 					$('<ul>').appendTo( ls.d.history );
// 				},
// 				// adds an UL with a LI
// 				aU : function(content){
// 					$('<ul><li>'+content+'</li></ul>').appendTo( ls.d.history );
// 				},
// 				// adds a LI into the last UL
// 				aL : function(content){
// 					$('<li>'+content+'</li>').appendTo( ls.d.history.find('ul:last') );
// 				},
// 				// adds an UL into the last LI of the last UL
// 				aUU : function(content){
// 					$('<ul>').appendTo( ls.d.history.find('ul:last li:last') );
// 				},
// 				// adds a Function to the first LI inside the last UL
// 				aF : function(elem){
// 					ls.d.history.find('ul:last li:last').hover(
// 						function(){
// 							elem.css({
// 								border: '2px solid red',
// 								marginTop : parseInt( elem.css('margin-top') ) - 2,
// 								marginLeft : parseInt( elem.css('margin-left') ) - 2
// 							});
// 						},
// 						function(){
// 							elem.css({
// 								border: '0px',
// 								marginTop : parseInt( elem.css('margin-top') ) + 2,
// 								marginLeft : parseInt( elem.css('margin-left') ) + 2
// 							});
// 						}
// 					);
// 				},
// 				show : function(){
// 					if( !$('body').find('.ls-debug-console').length ){

// 						if( !ls.d.putData ){

// 							// Init code

// 							ls.d.aT('Init code');
// 							ls.d.aeU();

// 							for( var prop in ls.o ){
// 								ls.d.aL(prop+': <strong>' + ls.o[prop] + '</strong>');
// 							}

// //							ls.d.aL('sliderOriginalWidth: <strong>' + ls.g.sliderOriginalWidth + '</strong>');
// //							ls.d.aL('sliderOriginalHeight: <strong>' + ls.g.sliderOriginalHeight + '</strong>');

// 							// Slides, layers data

// 							ls.d.aT('LayerSlider Content');
// 							ls.d.aU('Number of slides found: <strong>' + $(el).find('.ls-slide').length + '</strong>');

// 							$(el).find('.ls-inner .ls-slide, .ls-inner *[class*="ls-l"]').each(function(){

// 								if( $(this).hasClass('ls-slide') ){
// 									ls.d.aU('<strong>SLIDE ' + ( $(this).index() + 1 ) + '</strong>');
// 									ls.d.aUU();
// 									ls.d.aL('<strong>SLIDE ' + ( $(this).index() + 1 ) + ' properties:</strong><br><br>');
// 								}else{
// 									ls.d.aU('&nbsp;&nbsp;&nbsp;&nbsp;Layer ( '+$(this).prop('tagName')+' )');
// 									ls.d.aF($(this));
// 									ls.d.aUU();
// 									ls.d.aL('<strong>'+$(this).prop('tagName')+' layer properties:</strong><br><br>');
// 									ls.d.aL('distance / class: <strong>'+$(this).attr('class')+'</strong>');
// 								}

// 								$.each( $(this).data(),function(name, val) {
// 									ls.d.aL( name +': <strong>' + val + '</strong>');
// 								});
// 							});

// 							ls.d.putData = true;
// 						}

// 						var dc = $('<div>').addClass('ls-debug-console').css({
// 							position: 'fixed',
// 							zIndex: '10000000000',
// 							top: '10px',
// 							right: '10px',
// 							width: '300px',
// 							padding: '20px',
// 							background: 'black',
// 							'border-radius': '10px',
// 							height: $(window).height() - 60,
// 							opacity: 0,
// 							marginRight: 150
// 						}).appendTo( $('body') ).css({
// 							marginRight: 0,
// 							opacity: .9
// 						}).click(function(e){
// 							if(e.shiftKey && e.altKey){
// 								$(this).remove();
// 							}
// 						});
// 						var ds = $('<div>').css({
// 							width: '100%',
// 							height: '100%',
// 							overflow: 'auto'
// 						}).appendTo( dc );
// 						var dd = $('<div>').css({
// 							width: '100%'
// 						}).appendTo( ds ).append( ls.d.history );
// 					}
// 				},
// 				hide : function(){
// 					$('body').find('.ls-debug-console').remove();
// 				}
// 			};

// 			$(el).click(function(e){
// 				if(e.shiftKey && e.altKey){
// 					ls.d.show();
// 				}
// 			});
// 		};

		// initializing
		ls.load();
	};

	var lsConvertEasing = function( e ){

		var t;

		if( e.toLowerCase().indexOf('swing') !== -1 || e.toLowerCase().indexOf('linear') !== -1 ){
			t = Linear.easeNone;
		}else if( e.toLowerCase().indexOf('easeinout') !== -1 ){
			var ee = e.toLowerCase().split('easeinout')[1];
			t = window[ee.charAt(0).toUpperCase() + ee.slice(1)].easeInOut;
		}else if( e.toLowerCase().indexOf('easeout') !== -1 ){
			var ee = e.toLowerCase().split('easeout')[1];
			t = window[ee.charAt(0).toUpperCase() + ee.slice(1)].easeOut;
		}else if( e.toLowerCase().indexOf('easein') !== -1 ){
			var ee = e.toLowerCase().split('easein')[1];
			t = window[ee.charAt(0).toUpperCase() + ee.slice(1)].easeIn;
		}

		return t;
	};

	var lsConvertTransition = function( t, e, type, undef ){

		if( typeof e === 'undefined' ){
			var e = 'easeInOutQuart';
		}
		var tt = {};

		if( t.rotate !== undef ){
			tt.rotation = t.rotate;
		}
		if( t.rotateY !== undef ){
			tt.rotationY = t.rotateY;
		}
		if( t.rotateX !== undef ){
			tt.rotationX = t.rotateX;
		}
		if( type === 'after' ){
			tt.scaleX = tt.scaleY = tt.scaleZ = 1;
		}else if( t.scale3d !== undef ){
			tt.scaleX = tt.scaleY = tt.scaleZ = t.scale3d;
		}

		if( t.delay ){
			tt.delay = type === 'after' ? t.delay/1000 : t.delay;
		}

		tt.ease = lsConvertEasing( e );

		return tt;
	};

	// Support3D checks the CSS3 3D capability of the browser (based on the idea of Modernizr.js)

	var lsSupport3D = function( el ) {

		var testEl = $('<div>'),
			s3d1 = false,
			s3d2 = false,
			properties = ['perspective', 'OPerspective', 'msPerspective', 'MozPerspective', 'WebkitPerspective'];
			transform = ['transformStyle','OTransformStyle','msTransformStyle','MozTransformStyle','WebkitTransformStyle'];

		for (var i = properties.length - 1; i >= 0; i--){
			s3d1 = s3d1 ? s3d1 : testEl[0].style[properties[i]] != undefined;
		};

		// preserve 3D test

		for (var i = transform.length - 1; i >= 0; i--){
			testEl.css( 'transform-style', 'preserve-3d' );
			s3d2 = s3d2 ? s3d2 : testEl[0].style[transform[i]] == 'preserve-3d';
		};

		// If browser has perspective capability and it is webkit, we must check it with this solution because Chrome can give false positive result if GPU acceleration is disabled

        if (s3d1 && testEl[0].style[properties[4]] != undefined){
			testEl.attr('id','ls-test3d').appendTo( el );
            s3d1 = testEl[0].offsetHeight === 3 && testEl[0].offsetLeft === 9;
			testEl.remove();
        }

        return (s3d1 && s3d2);
	};

	// Order array function

	var lsOrderArray = function(x,y,dir) {
		var i = [];
		if(dir=='forward'){
			for( var a=0; a<x;a++){
				for( var b=0; b<y; b++){
					i.push(a+b*x);
				}
			}
		}else{
			for( var a=x-1; a>-1;a--){
				for( var b=y-1; b>-1; b--){
					i.push(a+b*x);
				}
			}
		}
		return i;
	};

	// CountProp counts the properties in an object

	var lsCountProp = function(obj) {
	    var count = 0;

	    for(var prop in obj) {
	        if(obj.hasOwnProperty(prop)){
	            ++count;
			}
	    }
	    return count;
	};

	// We need the browser function (removed from jQuery 1.9)

	var lsBrowser = function(){

		uaMatch = function( ua ) {
			ua = ua.toLowerCase();

			var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
				/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
				/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
				/(msie) ([\w.]+)/.exec( ua ) ||
				ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
				[];

			return {
				browser: match[ 1 ] || "",
				version: match[ 2 ] || "0"
			};
		};

		var matched = uaMatch( navigator.userAgent ), browser = {};

		if ( matched.browser ) {
			browser[ matched.browser ] = true;
			browser.version = matched.version;
		}

		if ( browser.chrome ) {
			browser.webkit = true;
		} else if ( browser.webkit ) {
			browser.safari = true;
		}

		return browser;
	};

	// BUGFIX v5.4.0 Missed declaration

	var lsPrefixes = function(obj, method){

		var pfx = ['webkit', 'khtml', 'moz', 'ms', 'o', ''];
		var p = 0, m, t;
		while (p < pfx.length && !obj[m]) {
			m = method;
			if (pfx[p] == '') {
				m = m.substr(0,1).toLowerCase() + m.substr(1);
			}
			m = pfx[p] + m;
			t = typeof obj[m];
			if (t != 'undefined') {
				pfx = [pfx[p]];
				return (t == 'function' ? obj[m]() : obj[m]);
			}
			p++;
		}
	};

	// Global parameters (Do not change these settings!)

	layerSlider.global = {

		version				: '5.6.0',

		isMobile			: function(){
								if( navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/webOS/i) || navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i) || navigator.userAgent.match(/iPod/i) || navigator.userAgent.match(/BlackBerry/i) || navigator.userAgent.match(/Windows Phone/i) ){
									return true;
								}else{
									return false;
								}
							},
		isHideOn3D			: function(el){
								if( el.css('padding-bottom') == 'auto' || el.css('padding-bottom') == 'none' || el.css('padding-bottom') == 0 || el.css('padding-bottom') == '0px' ){
									return true;
								}else{
									return false;
								}
							},

		ie78				: lsBrowser().msie && lsBrowser().version < 9 ? true : false,
		originalAutoStart	: false,
		paused				: false,
		pausedByVideo		: false,
		autoSlideshow		: false,
		isAnimating			: false,
		layersNum			: null,
		prevNext			: 'next',
		slideTimer			: null,
		sliderWidth			: null,
		sliderHeight		: null,
		numYouTubeCurslide	: 0,
		slideDirections		: {
								prev : {
									left	: 'right',
									right	: 'left',
									top		: 'bottom',
									bottom	: 'top'
								},
								next : {
									left	: 'left',
									right	: 'right',
									top		: 'top',
									bottom	: 'bottom'
								}
							},

		// Default delay time, fadeout and fadein durations of videoPreview images

		v					: {
								d	: 500,
								fo	: 750,
								fi	: 500
							}
	};

	// Layer Transition Defaults

	layerSlider.layerTransitions = {

		offsetXIn			: 80,
		offsetYIn			: 0,
		durationIn			: 1000,
		delayIn				: 0,
		easingIn			: 'easeInOutQuint',
		fadeIn				: true,
		rotateIn			: 0,
		rotateXIn			: 0,
		rotateYIn			: 0,
		scaleIn				: 1,
		scaleXIn			: 1,
		scaleYIn			: 1,
		skewXIn				: 0,
		skewYIn				: 0,
		transformOriginIn	: ['50%','50%','0'],
		perspectiveIn 		: 500,

		offsetXOut			: -80,
		offsetYOut			: 0,
		durationOut			: 400,
		showUntil			: 0,
		easingOut			: 'easeInOutQuint',
		fadeOut				: true,
		rotateOut			: 0,
		rotateXOut			: 0,
		rotateYOut			: 0,
		scaleOut			: 1,
		scaleXOut			: 1,
		scaleYOut			: 1,
		skewXOut			: 0,
		skewYOut			: 0,
		transformOriginOut	: ['50%','50%','0'],
		perspectiveOut 		: 500
	};

	layerSlider.slideTransitions = {

		slideDelay			: 4000							// Time before the next slide will be loading.
	};

	// Global settings (can be modified)

	layerSlider.options = {

		// Layout

		responsive			: true,
		responsiveUnder		: 0,
		layersContainer		: 0,
		fullScreen			: false,					// NEW FEATURE 6.0.0
		prependTo			: '',						// NEW FEATURE 5.5.0

		// Slideshow

		autoStart			: true,
		startInViewport		: true,						// NEW FEATURE v5.2.0
		pauseOnHover		: true,
		firstSlide			: 1,
		animateFirstSlide	: true,
		sliderFadeInDuration: 350,						// NEW FEATURE v5.2.0
		loops				: 0,
		forceLoopNum		: true,
		twoWaySlideshow		: false,
		randomSlideshow		: false,

		// Appearance

		skin				: 'v5',
		skinsPath			: '/layerslider/skins/',
		globalBGColor		: 'transparent',
		globalBGImage		: false,

		// Navigation Area

		navPrevNext			: true,
		navStartStop		: true,
		navButtons			: true,
		keybNav				: true,
		touchNav			: true,
		hoverPrevNext		: true,
		hoverBottomNav		: false,
		showBarTimer		: false,
		showCircleTimer		: true,

		// Thumbnail navigation

		thumbnailNavigation	: 'hover',
		tnContainerWidth	: '60%',
		tnWidth				: 100,
		tnHeight			: 60,
		tnActiveOpacity		: 35,
		tnInactiveOpacity	: 100,

		// Videos

		autoPlayVideos		: true,
		autoPauseSlideshow	: 'auto',
		youtubePreview		: 'maxresdefault.jpg',

		// Preload

		imgPreload			: true,
		lazyLoad 			: true,

		// YourLogo

		yourLogo			: false,
		yourLogoStyle		: 'left: -10px; top: -10px;',
		yourLogoLink		: false,
		yourLogoTarget		: '_self',

		// Optimize for IE7 and IE8

		optimizeForMobile	: true,
		optimizeForIE78		: true,

		// NEW FEATURES 5.2.0 Mobile features

		hideOnMobile		: false,
		hideUnder			: 0,
		hideOver			: 1000000,

		staticImage			: '', // will be available in 6.0.0

		// API functions

		cbInit				: function(element){},
		cbStart				: function(data){},
		cbStop				: function(data){},
		cbPause				: function(data){},
		cbAnimStart			: function(data){},
		cbAnimStop			: function(data){},
		cbPrev				: function(data){},
		cbNext				: function(data){},

		// !!! IMPORTANT !!! The following properties are deprecated from version 5.0.0 DO NOT USE THEM.
		// The slider will recognize these properties in the init code or if you add these properties into the style attribute of the layer
		// but we recommend you to use to new html5 data attribute (data-ls) with the new properties

		slideDelay			: 4000,
		slideDirection		: 'right',
		parallaxIn			: .45,
		parallaxOut			: .45,
		durationIn			: 1000,
		durationOut			: 1000,
		easingIn			: 'easeInOutQuint',
		easingOut			: 'easeInOutQuint',
		delayIn				: 0,
		delayOut			: 0
	};

})(jQuery);
;
!function(i){"use strict";"function"==typeof define&&define.amd?define(["jquery"],i):"undefined"!=typeof exports?module.exports=i(require("jquery")):i(jQuery)}(function(i){"use strict";var e=window.Slick||{};(e=function(){var e=0;return function(t,o){var s,n=this;n.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:i(t),appendDots:i(t),arrows:!0,asNavFor:null,prevArrow:'<button class="slick-prev" aria-label="Previous" type="button">Previous</button>',nextArrow:'<button class="slick-next" aria-label="Next" type="button">Next</button>',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(e,t){return i('<button type="button" />').text(t+1)},dots:!1,dotsClass:"slick-dots",draggable:!0,easing:"linear",edgeFriction:.35,fade:!1,focusOnSelect:!1,focusOnChange:!1,infinite:!0,initialSlide:0,lazyLoad:"ondemand",mobileFirst:!1,pauseOnHover:!0,pauseOnFocus:!0,pauseOnDotsHover:!1,respondTo:"window",responsive:null,rows:1,rtl:!1,slide:"",slidesPerRow:1,slidesToShow:1,slidesToScroll:1,speed:500,swipe:!0,swipeToSlide:!1,touchMove:!0,touchThreshold:5,useCSS:!0,useTransform:!0,variableWidth:!1,vertical:!1,verticalSwiping:!1,waitForAnimate:!0,zIndex:1e3},n.initials={animating:!1,dragging:!1,autoPlayTimer:null,currentDirection:0,currentLeft:null,currentSlide:0,direction:1,$dots:null,listWidth:null,listHeight:null,loadIndex:0,$nextArrow:null,$prevArrow:null,scrolling:!1,slideCount:null,slideWidth:null,$slideTrack:null,$slides:null,sliding:!1,slideOffset:0,swipeLeft:null,swiping:!1,$list:null,touchObject:{},transformsEnabled:!1,unslicked:!1},i.extend(n,n.initials),n.activeBreakpoint=null,n.animType=null,n.animProp=null,n.breakpoints=[],n.breakpointSettings=[],n.cssTransitions=!1,n.focussed=!1,n.interrupted=!1,n.hidden="hidden",n.paused=!0,n.positionProp=null,n.respondTo=null,n.rowCount=1,n.shouldClick=!0,n.$slider=i(t),n.$slidesCache=null,n.transformType=null,n.transitionType=null,n.visibilityChange="visibilitychange",n.windowWidth=0,n.windowTimer=null,s=i(t).data("slick")||{},n.options=i.extend({},n.defaults,o,s),n.currentSlide=n.options.initialSlide,n.originalSettings=n.options,void 0!==document.mozHidden?(n.hidden="mozHidden",n.visibilityChange="mozvisibilitychange"):void 0!==document.webkitHidden&&(n.hidden="webkitHidden",n.visibilityChange="webkitvisibilitychange"),n.autoPlay=i.proxy(n.autoPlay,n),n.autoPlayClear=i.proxy(n.autoPlayClear,n),n.autoPlayIterator=i.proxy(n.autoPlayIterator,n),n.changeSlide=i.proxy(n.changeSlide,n),n.clickHandler=i.proxy(n.clickHandler,n),n.selectHandler=i.proxy(n.selectHandler,n),n.setPosition=i.proxy(n.setPosition,n),n.swipeHandler=i.proxy(n.swipeHandler,n),n.dragHandler=i.proxy(n.dragHandler,n),n.keyHandler=i.proxy(n.keyHandler,n),n.instanceUid=e++,n.htmlExpr=/^(?:\s*(<[\w\W]+>)[^>]*)$/,n.registerBreakpoints(),n.init(!0)}}()).prototype.activateADA=function(){this.$slideTrack.find(".slick-active").attr({"aria-hidden":"false"}).find("a, input, button, select").attr({tabindex:"0"})},e.prototype.addSlide=e.prototype.slickAdd=function(e,t,o){var s=this;if("boolean"==typeof t)o=t,t=null;else if(t<0||t>=s.slideCount)return!1;s.unload(),"number"==typeof t?0===t&&0===s.$slides.length?i(e).appendTo(s.$slideTrack):o?i(e).insertBefore(s.$slides.eq(t)):i(e).insertAfter(s.$slides.eq(t)):!0===o?i(e).prependTo(s.$slideTrack):i(e).appendTo(s.$slideTrack),s.$slides=s.$slideTrack.children(this.options.slide),s.$slideTrack.children(this.options.slide).detach(),s.$slideTrack.append(s.$slides),s.$slides.each(function(e,t){i(t).attr("data-slick-index",e)}),s.$slidesCache=s.$slides,s.reinit()},e.prototype.animateHeight=function(){var i=this;if(1===i.options.slidesToShow&&!0===i.options.adaptiveHeight&&!1===i.options.vertical){var e=i.$slides.eq(i.currentSlide).outerHeight(!0);i.$list.animate({height:e},i.options.speed)}},e.prototype.animateSlide=function(e,t){var o={},s=this;s.animateHeight(),!0===s.options.rtl&&!1===s.options.vertical&&(e=-e),!1===s.transformsEnabled?!1===s.options.vertical?s.$slideTrack.animate({left:e},s.options.speed,s.options.easing,t):s.$slideTrack.animate({top:e},s.options.speed,s.options.easing,t):!1===s.cssTransitions?(!0===s.options.rtl&&(s.currentLeft=-s.currentLeft),i({animStart:s.currentLeft}).animate({animStart:e},{duration:s.options.speed,easing:s.options.easing,step:function(i){i=Math.ceil(i),!1===s.options.vertical?(o[s.animType]="translate("+i+"px, 0px)",s.$slideTrack.css(o)):(o[s.animType]="translate(0px,"+i+"px)",s.$slideTrack.css(o))},complete:function(){t&&t.call()}})):(s.applyTransition(),e=Math.ceil(e),!1===s.options.vertical?o[s.animType]="translate3d("+e+"px, 0px, 0px)":o[s.animType]="translate3d(0px,"+e+"px, 0px)",s.$slideTrack.css(o),t&&setTimeout(function(){s.disableTransition(),t.call()},s.options.speed))},e.prototype.getNavTarget=function(){var e=this,t=e.options.asNavFor;return t&&null!==t&&(t=i(t).not(e.$slider)),t},e.prototype.asNavFor=function(e){var t=this.getNavTarget();null!==t&&"object"==typeof t&&t.each(function(){var t=i(this).slick("getSlick");t.unslicked||t.slideHandler(e,!0)})},e.prototype.applyTransition=function(i){var e=this,t={};!1===e.options.fade?t[e.transitionType]=e.transformType+" "+e.options.speed+"ms "+e.options.cssEase:t[e.transitionType]="opacity "+e.options.speed+"ms "+e.options.cssEase,!1===e.options.fade?e.$slideTrack.css(t):e.$slides.eq(i).css(t)},e.prototype.autoPlay=function(){var i=this;i.autoPlayClear(),i.slideCount>i.options.slidesToShow&&(i.autoPlayTimer=setInterval(i.autoPlayIterator,i.options.autoplaySpeed))},e.prototype.autoPlayClear=function(){var i=this;i.autoPlayTimer&&clearInterval(i.autoPlayTimer)},e.prototype.autoPlayIterator=function(){var i=this,e=i.currentSlide+i.options.slidesToScroll;i.paused||i.interrupted||i.focussed||(!1===i.options.infinite&&(1===i.direction&&i.currentSlide+1===i.slideCount-1?i.direction=0:0===i.direction&&(e=i.currentSlide-i.options.slidesToScroll,i.currentSlide-1==0&&(i.direction=1))),i.slideHandler(e))},e.prototype.buildArrows=function(){var e=this;!0===e.options.arrows&&(e.$prevArrow=i(e.options.prevArrow).addClass("slick-arrow"),e.$nextArrow=i(e.options.nextArrow).addClass("slick-arrow"),e.slideCount>e.options.slidesToShow?(e.$prevArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"),e.$nextArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"),e.htmlExpr.test(e.options.prevArrow)&&e.$prevArrow.prependTo(e.options.appendArrows),e.htmlExpr.test(e.options.nextArrow)&&e.$nextArrow.appendTo(e.options.appendArrows),!0!==e.options.infinite&&e.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true")):e.$prevArrow.add(e.$nextArrow).addClass("slick-hidden").attr({"aria-disabled":"true",tabindex:"-1"}))},e.prototype.buildDots=function(){var e,t,o=this;if(!0===o.options.dots){for(o.$slider.addClass("slick-dotted"),t=i("<ul />").addClass(o.options.dotsClass),e=0;e<=o.getDotCount();e+=1)t.append(i("<li />").append(o.options.customPaging.call(this,o,e)));o.$dots=t.appendTo(o.options.appendDots),o.$dots.find("li").first().addClass("slick-active")}},e.prototype.buildOut=function(){var e=this;e.$slides=e.$slider.children(e.options.slide+":not(.slick-cloned)").addClass("slick-slide"),e.slideCount=e.$slides.length,e.$slides.each(function(e,t){i(t).attr("data-slick-index",e).data("originalStyling",i(t).attr("style")||"")}),e.$slider.addClass("slick-slider"),e.$slideTrack=0===e.slideCount?i('<div class="slick-track"/>').appendTo(e.$slider):e.$slides.wrapAll('<div class="slick-track"/>').parent(),e.$list=e.$slideTrack.wrap('<div class="slick-list"/>').parent(),e.$slideTrack.css("opacity",0),!0!==e.options.centerMode&&!0!==e.options.swipeToSlide||(e.options.slidesToScroll=1),i("img[data-lazy]",e.$slider).not("[src]").addClass("slick-loading"),e.setupInfinite(),e.buildArrows(),e.buildDots(),e.updateDots(),e.setSlideClasses("number"==typeof e.currentSlide?e.currentSlide:0),!0===e.options.draggable&&e.$list.addClass("draggable")},e.prototype.buildRows=function(){var i,e,t,o,s,n,r,l=this;if(o=document.createDocumentFragment(),n=l.$slider.children(),l.options.rows>1){for(r=l.options.slidesPerRow*l.options.rows,s=Math.ceil(n.length/r),i=0;i<s;i++){var d=document.createElement("div");for(e=0;e<l.options.rows;e++){var a=document.createElement("div");for(t=0;t<l.options.slidesPerRow;t++){var c=i*r+(e*l.options.slidesPerRow+t);n.get(c)&&a.appendChild(n.get(c))}d.appendChild(a)}o.appendChild(d)}l.$slider.empty().append(o),l.$slider.children().children().children().css({width:100/l.options.slidesPerRow+"%",display:"inline-block"})}},e.prototype.checkResponsive=function(e,t){var o,s,n,r=this,l=!1,d=r.$slider.width(),a=window.innerWidth||i(window).width();if("window"===r.respondTo?n=a:"slider"===r.respondTo?n=d:"min"===r.respondTo&&(n=Math.min(a,d)),r.options.responsive&&r.options.responsive.length&&null!==r.options.responsive){s=null;for(o in r.breakpoints)r.breakpoints.hasOwnProperty(o)&&(!1===r.originalSettings.mobileFirst?n<r.breakpoints[o]&&(s=r.breakpoints[o]):n>r.breakpoints[o]&&(s=r.breakpoints[o]));null!==s?null!==r.activeBreakpoint?(s!==r.activeBreakpoint||t)&&(r.activeBreakpoint=s,"unslick"===r.breakpointSettings[s]?r.unslick(s):(r.options=i.extend({},r.originalSettings,r.breakpointSettings[s]),!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e)),l=s):(r.activeBreakpoint=s,"unslick"===r.breakpointSettings[s]?r.unslick(s):(r.options=i.extend({},r.originalSettings,r.breakpointSettings[s]),!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e)),l=s):null!==r.activeBreakpoint&&(r.activeBreakpoint=null,r.options=r.originalSettings,!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e),l=s),e||!1===l||r.$slider.trigger("breakpoint",[r,l])}},e.prototype.changeSlide=function(e,t){var o,s,n,r=this,l=i(e.currentTarget);switch(l.is("a")&&e.preventDefault(),l.is("li")||(l=l.closest("li")),n=r.slideCount%r.options.slidesToScroll!=0,o=n?0:(r.slideCount-r.currentSlide)%r.options.slidesToScroll,e.data.message){case"previous":s=0===o?r.options.slidesToScroll:r.options.slidesToShow-o,r.slideCount>r.options.slidesToShow&&r.slideHandler(r.currentSlide-s,!1,t);break;case"next":s=0===o?r.options.slidesToScroll:o,r.slideCount>r.options.slidesToShow&&r.slideHandler(r.currentSlide+s,!1,t);break;case"index":var d=0===e.data.index?0:e.data.index||l.index()*r.options.slidesToScroll;r.slideHandler(r.checkNavigable(d),!1,t),l.children().trigger("focus");break;default:return}},e.prototype.checkNavigable=function(i){var e,t;if(e=this.getNavigableIndexes(),t=0,i>e[e.length-1])i=e[e.length-1];else for(var o in e){if(i<e[o]){i=t;break}t=e[o]}return i},e.prototype.cleanUpEvents=function(){var e=this;e.options.dots&&null!==e.$dots&&(i("li",e.$dots).off("click.slick",e.changeSlide).off("mouseenter.slick",i.proxy(e.interrupt,e,!0)).off("mouseleave.slick",i.proxy(e.interrupt,e,!1)),!0===e.options.accessibility&&e.$dots.off("keydown.slick",e.keyHandler)),e.$slider.off("focus.slick blur.slick"),!0===e.options.arrows&&e.slideCount>e.options.slidesToShow&&(e.$prevArrow&&e.$prevArrow.off("click.slick",e.changeSlide),e.$nextArrow&&e.$nextArrow.off("click.slick",e.changeSlide),!0===e.options.accessibility&&(e.$prevArrow&&e.$prevArrow.off("keydown.slick",e.keyHandler),e.$nextArrow&&e.$nextArrow.off("keydown.slick",e.keyHandler))),e.$list.off("touchstart.slick mousedown.slick",e.swipeHandler),e.$list.off("touchmove.slick mousemove.slick",e.swipeHandler),e.$list.off("touchend.slick mouseup.slick",e.swipeHandler),e.$list.off("touchcancel.slick mouseleave.slick",e.swipeHandler),e.$list.off("click.slick",e.clickHandler),i(document).off(e.visibilityChange,e.visibility),e.cleanUpSlideEvents(),!0===e.options.accessibility&&e.$list.off("keydown.slick",e.keyHandler),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().off("click.slick",e.selectHandler),i(window).off("orientationchange.slick.slick-"+e.instanceUid,e.orientationChange),i(window).off("resize.slick.slick-"+e.instanceUid,e.resize),i("[draggable!=true]",e.$slideTrack).off("dragstart",e.preventDefault),i(window).off("load.slick.slick-"+e.instanceUid,e.setPosition)},e.prototype.cleanUpSlideEvents=function(){var e=this;e.$list.off("mouseenter.slick",i.proxy(e.interrupt,e,!0)),e.$list.off("mouseleave.slick",i.proxy(e.interrupt,e,!1))},e.prototype.cleanUpRows=function(){var i,e=this;e.options.rows>1&&((i=e.$slides.children().children()).removeAttr("style"),e.$slider.empty().append(i))},e.prototype.clickHandler=function(i){!1===this.shouldClick&&(i.stopImmediatePropagation(),i.stopPropagation(),i.preventDefault())},e.prototype.destroy=function(e){var t=this;t.autoPlayClear(),t.touchObject={},t.cleanUpEvents(),i(".slick-cloned",t.$slider).detach(),t.$dots&&t.$dots.remove(),t.$prevArrow&&t.$prevArrow.length&&(t.$prevArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display",""),t.htmlExpr.test(t.options.prevArrow)&&t.$prevArrow.remove()),t.$nextArrow&&t.$nextArrow.length&&(t.$nextArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display",""),t.htmlExpr.test(t.options.nextArrow)&&t.$nextArrow.remove()),t.$slides&&(t.$slides.removeClass("slick-slide slick-active slick-center slick-visible slick-current").removeAttr("aria-hidden").removeAttr("data-slick-index").each(function(){i(this).attr("style",i(this).data("originalStyling"))}),t.$slideTrack.children(this.options.slide).detach(),t.$slideTrack.detach(),t.$list.detach(),t.$slider.append(t.$slides)),t.cleanUpRows(),t.$slider.removeClass("slick-slider"),t.$slider.removeClass("slick-initialized"),t.$slider.removeClass("slick-dotted"),t.unslicked=!0,e||t.$slider.trigger("destroy",[t])},e.prototype.disableTransition=function(i){var e=this,t={};t[e.transitionType]="",!1===e.options.fade?e.$slideTrack.css(t):e.$slides.eq(i).css(t)},e.prototype.fadeSlide=function(i,e){var t=this;!1===t.cssTransitions?(t.$slides.eq(i).css({zIndex:t.options.zIndex}),t.$slides.eq(i).animate({opacity:1},t.options.speed,t.options.easing,e)):(t.applyTransition(i),t.$slides.eq(i).css({opacity:1,zIndex:t.options.zIndex}),e&&setTimeout(function(){t.disableTransition(i),e.call()},t.options.speed))},e.prototype.fadeSlideOut=function(i){var e=this;!1===e.cssTransitions?e.$slides.eq(i).animate({opacity:0,zIndex:e.options.zIndex-2},e.options.speed,e.options.easing):(e.applyTransition(i),e.$slides.eq(i).css({opacity:0,zIndex:e.options.zIndex-2}))},e.prototype.filterSlides=e.prototype.slickFilter=function(i){var e=this;null!==i&&(e.$slidesCache=e.$slides,e.unload(),e.$slideTrack.children(this.options.slide).detach(),e.$slidesCache.filter(i).appendTo(e.$slideTrack),e.reinit())},e.prototype.focusHandler=function(){var e=this;e.$slider.off("focus.slick blur.slick").on("focus.slick blur.slick","*",function(t){t.stopImmediatePropagation();var o=i(this);setTimeout(function(){e.options.pauseOnFocus&&(e.focussed=o.is(":focus"),e.autoPlay())},0)})},e.prototype.getCurrent=e.prototype.slickCurrentSlide=function(){return this.currentSlide},e.prototype.getDotCount=function(){var i=this,e=0,t=0,o=0;if(!0===i.options.infinite)if(i.slideCount<=i.options.slidesToShow)++o;else for(;e<i.slideCount;)++o,e=t+i.options.slidesToScroll,t+=i.options.slidesToScroll<=i.options.slidesToShow?i.options.slidesToScroll:i.options.slidesToShow;else if(!0===i.options.centerMode)o=i.slideCount;else if(i.options.asNavFor)for(;e<i.slideCount;)++o,e=t+i.options.slidesToScroll,t+=i.options.slidesToScroll<=i.options.slidesToShow?i.options.slidesToScroll:i.options.slidesToShow;else o=1+Math.ceil((i.slideCount-i.options.slidesToShow)/i.options.slidesToScroll);return o-1},e.prototype.getLeft=function(i){var e,t,o,s,n=this,r=0;return n.slideOffset=0,t=n.$slides.first().outerHeight(!0),!0===n.options.infinite?(n.slideCount>n.options.slidesToShow&&(n.slideOffset=n.slideWidth*n.options.slidesToShow*-1,s=-1,!0===n.options.vertical&&!0===n.options.centerMode&&(2===n.options.slidesToShow?s=-1.5:1===n.options.slidesToShow&&(s=-2)),r=t*n.options.slidesToShow*s),n.slideCount%n.options.slidesToScroll!=0&&i+n.options.slidesToScroll>n.slideCount&&n.slideCount>n.options.slidesToShow&&(i>n.slideCount?(n.slideOffset=(n.options.slidesToShow-(i-n.slideCount))*n.slideWidth*-1,r=(n.options.slidesToShow-(i-n.slideCount))*t*-1):(n.slideOffset=n.slideCount%n.options.slidesToScroll*n.slideWidth*-1,r=n.slideCount%n.options.slidesToScroll*t*-1))):i+n.options.slidesToShow>n.slideCount&&(n.slideOffset=(i+n.options.slidesToShow-n.slideCount)*n.slideWidth,r=(i+n.options.slidesToShow-n.slideCount)*t),n.slideCount<=n.options.slidesToShow&&(n.slideOffset=0,r=0),!0===n.options.centerMode&&n.slideCount<=n.options.slidesToShow?n.slideOffset=n.slideWidth*Math.floor(n.options.slidesToShow)/2-n.slideWidth*n.slideCount/2:!0===n.options.centerMode&&!0===n.options.infinite?n.slideOffset+=n.slideWidth*Math.floor(n.options.slidesToShow/2)-n.slideWidth:!0===n.options.centerMode&&(n.slideOffset=0,n.slideOffset+=n.slideWidth*Math.floor(n.options.slidesToShow/2)),e=!1===n.options.vertical?i*n.slideWidth*-1+n.slideOffset:i*t*-1+r,!0===n.options.variableWidth&&(o=n.slideCount<=n.options.slidesToShow||!1===n.options.infinite?n.$slideTrack.children(".slick-slide").eq(i):n.$slideTrack.children(".slick-slide").eq(i+n.options.slidesToShow),e=!0===n.options.rtl?o[0]?-1*(n.$slideTrack.width()-o[0].offsetLeft-o.width()):0:o[0]?-1*o[0].offsetLeft:0,!0===n.options.centerMode&&(o=n.slideCount<=n.options.slidesToShow||!1===n.options.infinite?n.$slideTrack.children(".slick-slide").eq(i):n.$slideTrack.children(".slick-slide").eq(i+n.options.slidesToShow+1),e=!0===n.options.rtl?o[0]?-1*(n.$slideTrack.width()-o[0].offsetLeft-o.width()):0:o[0]?-1*o[0].offsetLeft:0,e+=(n.$list.width()-o.outerWidth())/2)),e},e.prototype.getOption=e.prototype.slickGetOption=function(i){return this.options[i]},e.prototype.getNavigableIndexes=function(){var i,e=this,t=0,o=0,s=[];for(!1===e.options.infinite?i=e.slideCount:(t=-1*e.options.slidesToScroll,o=-1*e.options.slidesToScroll,i=2*e.slideCount);t<i;)s.push(t),t=o+e.options.slidesToScroll,o+=e.options.slidesToScroll<=e.options.slidesToShow?e.options.slidesToScroll:e.options.slidesToShow;return s},e.prototype.getSlick=function(){return this},e.prototype.getSlideCount=function(){var e,t,o=this;return t=!0===o.options.centerMode?o.slideWidth*Math.floor(o.options.slidesToShow/2):0,!0===o.options.swipeToSlide?(o.$slideTrack.find(".slick-slide").each(function(s,n){if(n.offsetLeft-t+i(n).outerWidth()/2>-1*o.swipeLeft)return e=n,!1}),Math.abs(i(e).attr("data-slick-index")-o.currentSlide)||1):o.options.slidesToScroll},e.prototype.goTo=e.prototype.slickGoTo=function(i,e){this.changeSlide({data:{message:"index",index:parseInt(i)}},e)},e.prototype.init=function(e){var t=this;i(t.$slider).hasClass("slick-initialized")||(i(t.$slider).addClass("slick-initialized"),t.buildRows(),t.buildOut(),t.setProps(),t.startLoad(),t.loadSlider(),t.initializeEvents(),t.updateArrows(),t.updateDots(),t.checkResponsive(!0),t.focusHandler()),e&&t.$slider.trigger("init",[t]),!0===t.options.accessibility&&t.initADA(),t.options.autoplay&&(t.paused=!1,t.autoPlay())},e.prototype.initADA=function(){var e=this,t=Math.ceil(e.slideCount/e.options.slidesToShow),o=e.getNavigableIndexes().filter(function(i){return i>=0&&i<e.slideCount});e.$slides.add(e.$slideTrack.find(".slick-cloned")).attr({"aria-hidden":"true",tabindex:"-1"}).find("a, input, button, select").attr({tabindex:"-1"}),null!==e.$dots&&(e.$slides.not(e.$slideTrack.find(".slick-cloned")).each(function(t){var s=o.indexOf(t);i(this).attr({role:"tabpanel",id:"slick-slide"+e.instanceUid+t,tabindex:-1}),-1!==s&&i(this).attr({"aria-describedby":"slick-slide-control"+e.instanceUid+s})}),e.$dots.attr("role","tablist").find("li").each(function(s){var n=o[s];i(this).attr({role:"presentation"}),i(this).find("button").first().attr({role:"tab",id:"slick-slide-control"+e.instanceUid+s,"aria-controls":"slick-slide"+e.instanceUid+n,"aria-label":s+1+" of "+t,"aria-selected":null,tabindex:"-1"})}).eq(e.currentSlide).find("button").attr({"aria-selected":"true",tabindex:"0"}).end());for(var s=e.currentSlide,n=s+e.options.slidesToShow;s<n;s++)e.$slides.eq(s).attr("tabindex",0);e.activateADA()},e.prototype.initArrowEvents=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.off("click.slick").on("click.slick",{message:"previous"},i.changeSlide),i.$nextArrow.off("click.slick").on("click.slick",{message:"next"},i.changeSlide),!0===i.options.accessibility&&(i.$prevArrow.on("keydown.slick",i.keyHandler),i.$nextArrow.on("keydown.slick",i.keyHandler)))},e.prototype.initDotEvents=function(){var e=this;!0===e.options.dots&&(i("li",e.$dots).on("click.slick",{message:"index"},e.changeSlide),!0===e.options.accessibility&&e.$dots.on("keydown.slick",e.keyHandler)),!0===e.options.dots&&!0===e.options.pauseOnDotsHover&&i("li",e.$dots).on("mouseenter.slick",i.proxy(e.interrupt,e,!0)).on("mouseleave.slick",i.proxy(e.interrupt,e,!1))},e.prototype.initSlideEvents=function(){var e=this;e.options.pauseOnHover&&(e.$list.on("mouseenter.slick",i.proxy(e.interrupt,e,!0)),e.$list.on("mouseleave.slick",i.proxy(e.interrupt,e,!1)))},e.prototype.initializeEvents=function(){var e=this;e.initArrowEvents(),e.initDotEvents(),e.initSlideEvents(),e.$list.on("touchstart.slick mousedown.slick",{action:"start"},e.swipeHandler),e.$list.on("touchmove.slick mousemove.slick",{action:"move"},e.swipeHandler),e.$list.on("touchend.slick mouseup.slick",{action:"end"},e.swipeHandler),e.$list.on("touchcancel.slick mouseleave.slick",{action:"end"},e.swipeHandler),e.$list.on("click.slick",e.clickHandler),i(document).on(e.visibilityChange,i.proxy(e.visibility,e)),!0===e.options.accessibility&&e.$list.on("keydown.slick",e.keyHandler),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().on("click.slick",e.selectHandler),i(window).on("orientationchange.slick.slick-"+e.instanceUid,i.proxy(e.orientationChange,e)),i(window).on("resize.slick.slick-"+e.instanceUid,i.proxy(e.resize,e)),i("[draggable!=true]",e.$slideTrack).on("dragstart",e.preventDefault),i(window).on("load.slick.slick-"+e.instanceUid,e.setPosition),i(e.setPosition)},e.prototype.initUI=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.show(),i.$nextArrow.show()),!0===i.options.dots&&i.slideCount>i.options.slidesToShow&&i.$dots.show()},e.prototype.keyHandler=function(i){var e=this;i.target.tagName.match("TEXTAREA|INPUT|SELECT")||(37===i.keyCode&&!0===e.options.accessibility?e.changeSlide({data:{message:!0===e.options.rtl?"next":"previous"}}):39===i.keyCode&&!0===e.options.accessibility&&e.changeSlide({data:{message:!0===e.options.rtl?"previous":"next"}}))},e.prototype.lazyLoad=function(){function e(e){i("img[data-lazy]",e).each(function(){var e=i(this),t=i(this).attr("data-lazy"),o=i(this).attr("data-srcset"),s=i(this).attr("data-sizes")||n.$slider.attr("data-sizes"),r=document.createElement("img");r.onload=function(){e.animate({opacity:0},100,function(){o&&(e.attr("srcset",o),s&&e.attr("sizes",s)),e.attr("src",t).animate({opacity:1},200,function(){e.removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading")}),n.$slider.trigger("lazyLoaded",[n,e,t])})},r.onerror=function(){e.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"),n.$slider.trigger("lazyLoadError",[n,e,t])},r.src=t})}var t,o,s,n=this;if(!0===n.options.centerMode?!0===n.options.infinite?s=(o=n.currentSlide+(n.options.slidesToShow/2+1))+n.options.slidesToShow+2:(o=Math.max(0,n.currentSlide-(n.options.slidesToShow/2+1)),s=n.options.slidesToShow/2+1+2+n.currentSlide):(o=n.options.infinite?n.options.slidesToShow+n.currentSlide:n.currentSlide,s=Math.ceil(o+n.options.slidesToShow),!0===n.options.fade&&(o>0&&o--,s<=n.slideCount&&s++)),t=n.$slider.find(".slick-slide").slice(o,s),"anticipated"===n.options.lazyLoad)for(var r=o-1,l=s,d=n.$slider.find(".slick-slide"),a=0;a<n.options.slidesToScroll;a++)r<0&&(r=n.slideCount-1),t=(t=t.add(d.eq(r))).add(d.eq(l)),r--,l++;e(t),n.slideCount<=n.options.slidesToShow?e(n.$slider.find(".slick-slide")):n.currentSlide>=n.slideCount-n.options.slidesToShow?e(n.$slider.find(".slick-cloned").slice(0,n.options.slidesToShow)):0===n.currentSlide&&e(n.$slider.find(".slick-cloned").slice(-1*n.options.slidesToShow))},e.prototype.loadSlider=function(){var i=this;i.setPosition(),i.$slideTrack.css({opacity:1}),i.$slider.removeClass("slick-loading"),i.initUI(),"progressive"===i.options.lazyLoad&&i.progressiveLazyLoad()},e.prototype.next=e.prototype.slickNext=function(){this.changeSlide({data:{message:"next"}})},e.prototype.orientationChange=function(){var i=this;i.checkResponsive(),i.setPosition()},e.prototype.pause=e.prototype.slickPause=function(){var i=this;i.autoPlayClear(),i.paused=!0},e.prototype.play=e.prototype.slickPlay=function(){var i=this;i.autoPlay(),i.options.autoplay=!0,i.paused=!1,i.focussed=!1,i.interrupted=!1},e.prototype.postSlide=function(e){var t=this;t.unslicked||(t.$slider.trigger("afterChange",[t,e]),t.animating=!1,t.slideCount>t.options.slidesToShow&&t.setPosition(),t.swipeLeft=null,t.options.autoplay&&t.autoPlay(),!0===t.options.accessibility&&(t.initADA(),t.options.focusOnChange&&i(t.$slides.get(t.currentSlide)).attr("tabindex",0).focus()))},e.prototype.prev=e.prototype.slickPrev=function(){this.changeSlide({data:{message:"previous"}})},e.prototype.preventDefault=function(i){i.preventDefault()},e.prototype.progressiveLazyLoad=function(e){e=e||1;var t,o,s,n,r,l=this,d=i("img[data-lazy]",l.$slider);d.length?(t=d.first(),o=t.attr("data-lazy"),s=t.attr("data-srcset"),n=t.attr("data-sizes")||l.$slider.attr("data-sizes"),(r=document.createElement("img")).onload=function(){s&&(t.attr("srcset",s),n&&t.attr("sizes",n)),t.attr("src",o).removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading"),!0===l.options.adaptiveHeight&&l.setPosition(),l.$slider.trigger("lazyLoaded",[l,t,o]),l.progressiveLazyLoad()},r.onerror=function(){e<3?setTimeout(function(){l.progressiveLazyLoad(e+1)},500):(t.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"),l.$slider.trigger("lazyLoadError",[l,t,o]),l.progressiveLazyLoad())},r.src=o):l.$slider.trigger("allImagesLoaded",[l])},e.prototype.refresh=function(e){var t,o,s=this;o=s.slideCount-s.options.slidesToShow,!s.options.infinite&&s.currentSlide>o&&(s.currentSlide=o),s.slideCount<=s.options.slidesToShow&&(s.currentSlide=0),t=s.currentSlide,s.destroy(!0),i.extend(s,s.initials,{currentSlide:t}),s.init(),e||s.changeSlide({data:{message:"index",index:t}},!1)},e.prototype.registerBreakpoints=function(){var e,t,o,s=this,n=s.options.responsive||null;if("array"===i.type(n)&&n.length){s.respondTo=s.options.respondTo||"window";for(e in n)if(o=s.breakpoints.length-1,n.hasOwnProperty(e)){for(t=n[e].breakpoint;o>=0;)s.breakpoints[o]&&s.breakpoints[o]===t&&s.breakpoints.splice(o,1),o--;s.breakpoints.push(t),s.breakpointSettings[t]=n[e].settings}s.breakpoints.sort(function(i,e){return s.options.mobileFirst?i-e:e-i})}},e.prototype.reinit=function(){var e=this;e.$slides=e.$slideTrack.children(e.options.slide).addClass("slick-slide"),e.slideCount=e.$slides.length,e.currentSlide>=e.slideCount&&0!==e.currentSlide&&(e.currentSlide=e.currentSlide-e.options.slidesToScroll),e.slideCount<=e.options.slidesToShow&&(e.currentSlide=0),e.registerBreakpoints(),e.setProps(),e.setupInfinite(),e.buildArrows(),e.updateArrows(),e.initArrowEvents(),e.buildDots(),e.updateDots(),e.initDotEvents(),e.cleanUpSlideEvents(),e.initSlideEvents(),e.checkResponsive(!1,!0),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().on("click.slick",e.selectHandler),e.setSlideClasses("number"==typeof e.currentSlide?e.currentSlide:0),e.setPosition(),e.focusHandler(),e.paused=!e.options.autoplay,e.autoPlay(),e.$slider.trigger("reInit",[e])},e.prototype.resize=function(){var e=this;i(window).width()!==e.windowWidth&&(clearTimeout(e.windowDelay),e.windowDelay=window.setTimeout(function(){e.windowWidth=i(window).width(),e.checkResponsive(),e.unslicked||e.setPosition()},50))},e.prototype.removeSlide=e.prototype.slickRemove=function(i,e,t){var o=this;if(i="boolean"==typeof i?!0===(e=i)?0:o.slideCount-1:!0===e?--i:i,o.slideCount<1||i<0||i>o.slideCount-1)return!1;o.unload(),!0===t?o.$slideTrack.children().remove():o.$slideTrack.children(this.options.slide).eq(i).remove(),o.$slides=o.$slideTrack.children(this.options.slide),o.$slideTrack.children(this.options.slide).detach(),o.$slideTrack.append(o.$slides),o.$slidesCache=o.$slides,o.reinit()},e.prototype.setCSS=function(i){var e,t,o=this,s={};!0===o.options.rtl&&(i=-i),e="left"==o.positionProp?Math.ceil(i)+"px":"0px",t="top"==o.positionProp?Math.ceil(i)+"px":"0px",s[o.positionProp]=i,!1===o.transformsEnabled?o.$slideTrack.css(s):(s={},!1===o.cssTransitions?(s[o.animType]="translate("+e+", "+t+")",o.$slideTrack.css(s)):(s[o.animType]="translate3d("+e+", "+t+", 0px)",o.$slideTrack.css(s)))},e.prototype.setDimensions=function(){var i=this;!1===i.options.vertical?!0===i.options.centerMode&&i.$list.css({padding:"0px "+i.options.centerPadding}):(i.$list.height(i.$slides.first().outerHeight(!0)*i.options.slidesToShow),!0===i.options.centerMode&&i.$list.css({padding:i.options.centerPadding+" 0px"})),i.listWidth=i.$list.width(),i.listHeight=i.$list.height(),!1===i.options.vertical&&!1===i.options.variableWidth?(i.slideWidth=Math.ceil(i.listWidth/i.options.slidesToShow),i.$slideTrack.width(Math.ceil(i.slideWidth*i.$slideTrack.children(".slick-slide").length))):!0===i.options.variableWidth?i.$slideTrack.width(5e3*i.slideCount):(i.slideWidth=Math.ceil(i.listWidth),i.$slideTrack.height(Math.ceil(i.$slides.first().outerHeight(!0)*i.$slideTrack.children(".slick-slide").length)));var e=i.$slides.first().outerWidth(!0)-i.$slides.first().width();!1===i.options.variableWidth&&i.$slideTrack.children(".slick-slide").width(i.slideWidth-e)},e.prototype.setFade=function(){var e,t=this;t.$slides.each(function(o,s){e=t.slideWidth*o*-1,!0===t.options.rtl?i(s).css({position:"relative",right:e,top:0,zIndex:t.options.zIndex-2,opacity:0}):i(s).css({position:"relative",left:e,top:0,zIndex:t.options.zIndex-2,opacity:0})}),t.$slides.eq(t.currentSlide).css({zIndex:t.options.zIndex-1,opacity:1})},e.prototype.setHeight=function(){var i=this;if(1===i.options.slidesToShow&&!0===i.options.adaptiveHeight&&!1===i.options.vertical){var e=i.$slides.eq(i.currentSlide).outerHeight(!0);i.$list.css("height",e)}},e.prototype.setOption=e.prototype.slickSetOption=function(){var e,t,o,s,n,r=this,l=!1;if("object"===i.type(arguments[0])?(o=arguments[0],l=arguments[1],n="multiple"):"string"===i.type(arguments[0])&&(o=arguments[0],s=arguments[1],l=arguments[2],"responsive"===arguments[0]&&"array"===i.type(arguments[1])?n="responsive":void 0!==arguments[1]&&(n="single")),"single"===n)r.options[o]=s;else if("multiple"===n)i.each(o,function(i,e){r.options[i]=e});else if("responsive"===n)for(t in s)if("array"!==i.type(r.options.responsive))r.options.responsive=[s[t]];else{for(e=r.options.responsive.length-1;e>=0;)r.options.responsive[e].breakpoint===s[t].breakpoint&&r.options.responsive.splice(e,1),e--;r.options.responsive.push(s[t])}l&&(r.unload(),r.reinit())},e.prototype.setPosition=function(){var i=this;i.setDimensions(),i.setHeight(),!1===i.options.fade?i.setCSS(i.getLeft(i.currentSlide)):i.setFade(),i.$slider.trigger("setPosition",[i])},e.prototype.setProps=function(){var i=this,e=document.body.style;i.positionProp=!0===i.options.vertical?"top":"left","top"===i.positionProp?i.$slider.addClass("slick-vertical"):i.$slider.removeClass("slick-vertical"),void 0===e.WebkitTransition&&void 0===e.MozTransition&&void 0===e.msTransition||!0===i.options.useCSS&&(i.cssTransitions=!0),i.options.fade&&("number"==typeof i.options.zIndex?i.options.zIndex<3&&(i.options.zIndex=3):i.options.zIndex=i.defaults.zIndex),void 0!==e.OTransform&&(i.animType="OTransform",i.transformType="-o-transform",i.transitionType="OTransition",void 0===e.perspectiveProperty&&void 0===e.webkitPerspective&&(i.animType=!1)),void 0!==e.MozTransform&&(i.animType="MozTransform",i.transformType="-moz-transform",i.transitionType="MozTransition",void 0===e.perspectiveProperty&&void 0===e.MozPerspective&&(i.animType=!1)),void 0!==e.webkitTransform&&(i.animType="webkitTransform",i.transformType="-webkit-transform",i.transitionType="webkitTransition",void 0===e.perspectiveProperty&&void 0===e.webkitPerspective&&(i.animType=!1)),void 0!==e.msTransform&&(i.animType="msTransform",i.transformType="-ms-transform",i.transitionType="msTransition",void 0===e.msTransform&&(i.animType=!1)),void 0!==e.transform&&!1!==i.animType&&(i.animType="transform",i.transformType="transform",i.transitionType="transition"),i.transformsEnabled=i.options.useTransform&&null!==i.animType&&!1!==i.animType},e.prototype.setSlideClasses=function(i){var e,t,o,s,n=this;if(t=n.$slider.find(".slick-slide").removeClass("slick-active slick-center slick-current").attr("aria-hidden","true"),n.$slides.eq(i).addClass("slick-current"),!0===n.options.centerMode){var r=n.options.slidesToShow%2==0?1:0;e=Math.floor(n.options.slidesToShow/2),!0===n.options.infinite&&(i>=e&&i<=n.slideCount-1-e?n.$slides.slice(i-e+r,i+e+1).addClass("slick-active").attr("aria-hidden","false"):(o=n.options.slidesToShow+i,t.slice(o-e+1+r,o+e+2).addClass("slick-active").attr("aria-hidden","false")),0===i?t.eq(t.length-1-n.options.slidesToShow).addClass("slick-center"):i===n.slideCount-1&&t.eq(n.options.slidesToShow).addClass("slick-center")),n.$slides.eq(i).addClass("slick-center")}else i>=0&&i<=n.slideCount-n.options.slidesToShow?n.$slides.slice(i,i+n.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false"):t.length<=n.options.slidesToShow?t.addClass("slick-active").attr("aria-hidden","false"):(s=n.slideCount%n.options.slidesToShow,o=!0===n.options.infinite?n.options.slidesToShow+i:i,n.options.slidesToShow==n.options.slidesToScroll&&n.slideCount-i<n.options.slidesToShow?t.slice(o-(n.options.slidesToShow-s),o+s).addClass("slick-active").attr("aria-hidden","false"):t.slice(o,o+n.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false"));"ondemand"!==n.options.lazyLoad&&"anticipated"!==n.options.lazyLoad||n.lazyLoad()},e.prototype.setupInfinite=function(){var e,t,o,s=this;if(!0===s.options.fade&&(s.options.centerMode=!1),!0===s.options.infinite&&!1===s.options.fade&&(t=null,s.slideCount>s.options.slidesToShow)){for(o=!0===s.options.centerMode?s.options.slidesToShow+1:s.options.slidesToShow,e=s.slideCount;e>s.slideCount-o;e-=1)t=e-1,i(s.$slides[t]).clone(!0).attr("id","").attr("data-slick-index",t-s.slideCount).prependTo(s.$slideTrack).addClass("slick-cloned");for(e=0;e<o+s.slideCount;e+=1)t=e,i(s.$slides[t]).clone(!0).attr("id","").attr("data-slick-index",t+s.slideCount).appendTo(s.$slideTrack).addClass("slick-cloned");s.$slideTrack.find(".slick-cloned").find("[id]").each(function(){i(this).attr("id","")})}},e.prototype.interrupt=function(i){var e=this;i||e.autoPlay(),e.interrupted=i},e.prototype.selectHandler=function(e){var t=this,o=i(e.target).is(".slick-slide")?i(e.target):i(e.target).parents(".slick-slide"),s=parseInt(o.attr("data-slick-index"));s||(s=0),t.slideCount<=t.options.slidesToShow?t.slideHandler(s,!1,!0):t.slideHandler(s)},e.prototype.slideHandler=function(i,e,t){var o,s,n,r,l,d=null,a=this;if(e=e||!1,!(!0===a.animating&&!0===a.options.waitForAnimate||!0===a.options.fade&&a.currentSlide===i))if(!1===e&&a.asNavFor(i),o=i,d=a.getLeft(o),r=a.getLeft(a.currentSlide),a.currentLeft=null===a.swipeLeft?r:a.swipeLeft,!1===a.options.infinite&&!1===a.options.centerMode&&(i<0||i>a.getDotCount()*a.options.slidesToScroll))!1===a.options.fade&&(o=a.currentSlide,!0!==t?a.animateSlide(r,function(){a.postSlide(o)}):a.postSlide(o));else if(!1===a.options.infinite&&!0===a.options.centerMode&&(i<0||i>a.slideCount-a.options.slidesToScroll))!1===a.options.fade&&(o=a.currentSlide,!0!==t?a.animateSlide(r,function(){a.postSlide(o)}):a.postSlide(o));else{if(a.options.autoplay&&clearInterval(a.autoPlayTimer),s=o<0?a.slideCount%a.options.slidesToScroll!=0?a.slideCount-a.slideCount%a.options.slidesToScroll:a.slideCount+o:o>=a.slideCount?a.slideCount%a.options.slidesToScroll!=0?0:o-a.slideCount:o,a.animating=!0,a.$slider.trigger("beforeChange",[a,a.currentSlide,s]),n=a.currentSlide,a.currentSlide=s,a.setSlideClasses(a.currentSlide),a.options.asNavFor&&(l=(l=a.getNavTarget()).slick("getSlick")).slideCount<=l.options.slidesToShow&&l.setSlideClasses(a.currentSlide),a.updateDots(),a.updateArrows(),!0===a.options.fade)return!0!==t?(a.fadeSlideOut(n),a.fadeSlide(s,function(){a.postSlide(s)})):a.postSlide(s),void a.animateHeight();!0!==t?a.animateSlide(d,function(){a.postSlide(s)}):a.postSlide(s)}},e.prototype.startLoad=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.hide(),i.$nextArrow.hide()),!0===i.options.dots&&i.slideCount>i.options.slidesToShow&&i.$dots.hide(),i.$slider.addClass("slick-loading")},e.prototype.swipeDirection=function(){var i,e,t,o,s=this;return i=s.touchObject.startX-s.touchObject.curX,e=s.touchObject.startY-s.touchObject.curY,t=Math.atan2(e,i),(o=Math.round(180*t/Math.PI))<0&&(o=360-Math.abs(o)),o<=45&&o>=0?!1===s.options.rtl?"left":"right":o<=360&&o>=315?!1===s.options.rtl?"left":"right":o>=135&&o<=225?!1===s.options.rtl?"right":"left":!0===s.options.verticalSwiping?o>=35&&o<=135?"down":"up":"vertical"},e.prototype.swipeEnd=function(i){var e,t,o=this;if(o.dragging=!1,o.swiping=!1,o.scrolling)return o.scrolling=!1,!1;if(o.interrupted=!1,o.shouldClick=!(o.touchObject.swipeLength>10),void 0===o.touchObject.curX)return!1;if(!0===o.touchObject.edgeHit&&o.$slider.trigger("edge",[o,o.swipeDirection()]),o.touchObject.swipeLength>=o.touchObject.minSwipe){switch(t=o.swipeDirection()){case"left":case"down":e=o.options.swipeToSlide?o.checkNavigable(o.currentSlide+o.getSlideCount()):o.currentSlide+o.getSlideCount(),o.currentDirection=0;break;case"right":case"up":e=o.options.swipeToSlide?o.checkNavigable(o.currentSlide-o.getSlideCount()):o.currentSlide-o.getSlideCount(),o.currentDirection=1}"vertical"!=t&&(o.slideHandler(e),o.touchObject={},o.$slider.trigger("swipe",[o,t]))}else o.touchObject.startX!==o.touchObject.curX&&(o.slideHandler(o.currentSlide),o.touchObject={})},e.prototype.swipeHandler=function(i){var e=this;if(!(!1===e.options.swipe||"ontouchend"in document&&!1===e.options.swipe||!1===e.options.draggable&&-1!==i.type.indexOf("mouse")))switch(e.touchObject.fingerCount=i.originalEvent&&void 0!==i.originalEvent.touches?i.originalEvent.touches.length:1,e.touchObject.minSwipe=e.listWidth/e.options.touchThreshold,!0===e.options.verticalSwiping&&(e.touchObject.minSwipe=e.listHeight/e.options.touchThreshold),i.data.action){case"start":e.swipeStart(i);break;case"move":e.swipeMove(i);break;case"end":e.swipeEnd(i)}},e.prototype.swipeMove=function(i){var e,t,o,s,n,r,l=this;return n=void 0!==i.originalEvent?i.originalEvent.touches:null,!(!l.dragging||l.scrolling||n&&1!==n.length)&&(e=l.getLeft(l.currentSlide),l.touchObject.curX=void 0!==n?n[0].pageX:i.clientX,l.touchObject.curY=void 0!==n?n[0].pageY:i.clientY,l.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(l.touchObject.curX-l.touchObject.startX,2))),r=Math.round(Math.sqrt(Math.pow(l.touchObject.curY-l.touchObject.startY,2))),!l.options.verticalSwiping&&!l.swiping&&r>4?(l.scrolling=!0,!1):(!0===l.options.verticalSwiping&&(l.touchObject.swipeLength=r),t=l.swipeDirection(),void 0!==i.originalEvent&&l.touchObject.swipeLength>4&&(l.swiping=!0,i.preventDefault()),s=(!1===l.options.rtl?1:-1)*(l.touchObject.curX>l.touchObject.startX?1:-1),!0===l.options.verticalSwiping&&(s=l.touchObject.curY>l.touchObject.startY?1:-1),o=l.touchObject.swipeLength,l.touchObject.edgeHit=!1,!1===l.options.infinite&&(0===l.currentSlide&&"right"===t||l.currentSlide>=l.getDotCount()&&"left"===t)&&(o=l.touchObject.swipeLength*l.options.edgeFriction,l.touchObject.edgeHit=!0),!1===l.options.vertical?l.swipeLeft=e+o*s:l.swipeLeft=e+o*(l.$list.height()/l.listWidth)*s,!0===l.options.verticalSwiping&&(l.swipeLeft=e+o*s),!0!==l.options.fade&&!1!==l.options.touchMove&&(!0===l.animating?(l.swipeLeft=null,!1):void l.setCSS(l.swipeLeft))))},e.prototype.swipeStart=function(i){var e,t=this;if(t.interrupted=!0,1!==t.touchObject.fingerCount||t.slideCount<=t.options.slidesToShow)return t.touchObject={},!1;void 0!==i.originalEvent&&void 0!==i.originalEvent.touches&&(e=i.originalEvent.touches[0]),t.touchObject.startX=t.touchObject.curX=void 0!==e?e.pageX:i.clientX,t.touchObject.startY=t.touchObject.curY=void 0!==e?e.pageY:i.clientY,t.dragging=!0},e.prototype.unfilterSlides=e.prototype.slickUnfilter=function(){var i=this;null!==i.$slidesCache&&(i.unload(),i.$slideTrack.children(this.options.slide).detach(),i.$slidesCache.appendTo(i.$slideTrack),i.reinit())},e.prototype.unload=function(){var e=this;i(".slick-cloned",e.$slider).remove(),e.$dots&&e.$dots.remove(),e.$prevArrow&&e.htmlExpr.test(e.options.prevArrow)&&e.$prevArrow.remove(),e.$nextArrow&&e.htmlExpr.test(e.options.nextArrow)&&e.$nextArrow.remove(),e.$slides.removeClass("slick-slide slick-active slick-visible slick-current").attr("aria-hidden","true").css("width","")},e.prototype.unslick=function(i){var e=this;e.$slider.trigger("unslick",[e,i]),e.destroy()},e.prototype.updateArrows=function(){var i=this;Math.floor(i.options.slidesToShow/2),!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&!i.options.infinite&&(i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false"),i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false"),0===i.currentSlide?(i.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false")):i.currentSlide>=i.slideCount-i.options.slidesToShow&&!1===i.options.centerMode?(i.$nextArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false")):i.currentSlide>=i.slideCount-1&&!0===i.options.centerMode&&(i.$nextArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false")))},e.prototype.updateDots=function(){var i=this;null!==i.$dots&&(i.$dots.find("li").removeClass("slick-active").end(),i.$dots.find("li").eq(Math.floor(i.currentSlide/i.options.slidesToScroll)).addClass("slick-active"))},e.prototype.visibility=function(){var i=this;i.options.autoplay&&(document[i.hidden]?i.interrupted=!0:i.interrupted=!1)},i.fn.slick=function(){var i,t,o=this,s=arguments[0],n=Array.prototype.slice.call(arguments,1),r=o.length;for(i=0;i<r;i++)if("object"==typeof s||void 0===s?o[i].slick=new e(o[i],s):t=o[i].slick[s].apply(o[i].slick,n),void 0!==t)return t;return o}});
;
/*!
 * jquery.customSelect() - v0.5.1
 * http://adam.co/lab/jquery/customselect/
 * 2014-03-19
 *
 * Copyright 2013 Adam Coulombe
 * @license http://www.opensource.org/licenses/mit-license.html MIT License
 * @license http://www.gnu.org/licenses/gpl.html GPL2 License 
 */

(function ($) {
    'use strict';

    $.fn.extend({
        customSelect: function (options) {
            // filter out <= IE6
            if (typeof document.body.style.maxHeight === 'undefined') {
                return this;
            }
            var defaults = {
                customClass: 'customSelect',
                mapClass: true,
                mapStyle: true
            },
            options = $.extend(defaults, options),
            prefix = options.customClass,
            changed = function ($select, customSelectSpan) {
                var currentSelected = $select.find(':selected'),
                customSelectSpanInner = customSelectSpan.children(':first'),
                html = currentSelected.html() || '&nbsp;';

                customSelectSpanInner.html(html);

                if (currentSelected.attr('disabled')) {
                    customSelectSpan.addClass(getClass('DisabledOption'));
                } else {
                    customSelectSpan.removeClass(getClass('DisabledOption'));
                }

                setTimeout(function () {
                    customSelectSpan.removeClass(getClass('Open'));
                    $(document).off('mouseup.customSelect');
                }, 60);
            },
            getClass = function (suffix) {
                return prefix + suffix;
            };

            return this.each(function () {
                var $select = $(this),
                    customSelectInnerSpan = $('<span />').addClass(getClass('Inner')),
                    customSelectSpan = $('<span />');

                $select.after(customSelectSpan.append(customSelectInnerSpan));

                customSelectSpan.addClass(prefix);

                if (options.mapClass) {
                    customSelectSpan.addClass($select.attr('class'));
                }
                if (options.mapStyle) {
                    customSelectSpan.attr('style', $select.attr('style'));
                }

                $select
                    .addClass('hasCustomSelect')
                    .on('render.customSelect', function () {
                        changed($select, customSelectSpan);
                        $select.css('width', '');
                        var selectBoxWidth = parseInt($select.outerWidth(), 10) -
                                (parseInt(customSelectSpan.outerWidth(), 10) -
                                    parseInt(customSelectSpan.width(), 10));

                        // Set to inline-block before calculating outerHeight
                        customSelectSpan.css({
                            display: 'inline-block'
                        });

                        var selectBoxHeight = customSelectSpan.outerHeight();

                        if ($select.attr('disabled')) {
                            customSelectSpan.addClass(getClass('Disabled'));
                        } else {
                            customSelectSpan.removeClass(getClass('Disabled'));
                        }

                        customSelectInnerSpan.css({
                            width: selectBoxWidth,
                            display: 'inline-block'
                        });

                        $select.css({
                            '-webkit-appearance': 'menulist-button',
                            width: customSelectSpan.outerWidth(),
                            position: 'absolute',
                            opacity: 0,
                            height: selectBoxHeight,
                            fontSize: customSelectSpan.css('font-size')
                        });
                    })
                    .on('change.customSelect', function () {
                        customSelectSpan.addClass(getClass('Changed'));
                        changed($select, customSelectSpan);
                    })
                    .on('keyup.customSelect', function (e) {
                        if (!customSelectSpan.hasClass(getClass('Open'))) {
                            $select.trigger('blur.customSelect');
                            $select.trigger('focus.customSelect');
                        } else {
                            if (e.which == 13 || e.which == 27) {
                                changed($select, customSelectSpan);
                            }
                        }
                    })
                    .on('mousedown.customSelect', function () {
                        customSelectSpan.removeClass(getClass('Changed'));
                    })
                    .on('mouseup.customSelect', function (e) {

                        if (!customSelectSpan.hasClass(getClass('Open'))) {
                            // if FF and there are other selects open, just apply focus
                            if ($('.' + getClass('Open')).not(customSelectSpan).length > 0 && typeof InstallTrigger !== 'undefined') {
                                $select.trigger('focus.customSelect');
                            } else {
                                customSelectSpan.addClass(getClass('Open'));
                                e.stopPropagation();
                                $(document).one('mouseup.customSelect', function (e) {
                                    if (e.target != $select.get(0) && $.inArray(e.target, $select.find('*').get()) < 0) {
                                        $select.trigger('blur.customSelect');
                                    } else {
                                        changed($select, customSelectSpan);
                                    }
                                });
                            }
                        }
                    })
                    .on('focus.customSelect', function () {
                        customSelectSpan.removeClass(getClass('Changed')).addClass(getClass('Focus'));
                    })
                    .on('blur.customSelect', function () {
                        customSelectSpan.removeClass(getClass('Focus') + ' ' + getClass('Open'));
                    })
                    .on('mouseenter.customSelect', function () {
                        customSelectSpan.addClass(getClass('Hover'));
                    })
                    .on('mouseleave.customSelect', function () {
                        customSelectSpan.removeClass(getClass('Hover'));
                    })
                    .trigger('render.customSelect');
            });
        }
    });
})(jQuery);;
/**
* jquery.matchHeight.js master
* http://brm.io/jquery-match-height/
* License: MIT
*/

; (function ($) {
    /*
    *  internal
    */

    var _previousResizeWidth = -1,
        _updateTimeout = -1;

    /*
    *  _parse
    *  value parse utility function
    */

    var _parse = function (value) {
        // parse value and convert NaN to 0
        return parseFloat(value) || 0;
    };

    /*
    *  _rows
    *  utility function returns array of jQuery selections representing each row
    *  (as displayed after float wrapping applied by browser)
    */

    var _rows = function (elements) {
        var tolerance = 1,
            $elements = $(elements),
            lastTop = null,
            rows = [];

        // group elements by their top position
        $elements.each(function () {
            var $that = $(this),
                top = $that.offset().top - _parse($that.css('margin-top')),
                lastRow = rows.length > 0 ? rows[rows.length - 1] : null;

            if (lastRow === null) {
                // first item on the row, so just push it
                rows.push($that);
            } else {
                // if the row top is the same, add to the row group
                if (Math.floor(Math.abs(lastTop - top)) <= tolerance) {
                    rows[rows.length - 1] = lastRow.add($that);
                } else {
                    // otherwise start a new row group
                    rows.push($that);
                }
            }

            // keep track of the last row top
            lastTop = top;
        });

        return rows;
    };

    /*
    *  _parseOptions
    *  handle plugin options
    */

    var _parseOptions = function (options) {
        var opts = {
            byRow: true,
            property: 'height',
            target: null,
            remove: false
        };

        if (typeof options === 'object') {
            return $.extend(opts, options);
        }

        if (typeof options === 'boolean') {
            opts.byRow = options;
        } else if (options === 'remove') {
            opts.remove = true;
        }

        return opts;
    };

    /*
    *  matchHeight
    *  plugin definition
    */

    var matchHeight = $.fn.matchHeight = function (options) {
        var opts = _parseOptions(options);

        // handle remove
        if (opts.remove) {
            var that = this;

            // remove fixed height from all selected elements
            this.css(opts.property, '');

            // remove selected elements from all groups
            $.each(matchHeight._groups, function (key, group) {
                group.elements = group.elements.not(that);
            });

            // TODO: cleanup empty groups

            return this;
        }

        if (this.length <= 1 && !opts.target) {
            return this;
        }

        // keep track of this group so we can re-apply later on load and resize events
        matchHeight._groups.push({
            elements: this,
            options: opts
        });

        // match each element's height to the tallest element in the selection
        matchHeight._apply(this, opts);

        return this;
    };

    /*
    *  plugin global options
    */

    matchHeight._groups = [];
    matchHeight._throttle = 80;
    matchHeight._maintainScroll = false;
    matchHeight._beforeUpdate = null;
    matchHeight._afterUpdate = null;
    matchHeight._rows = _rows;

    /*
    *  matchHeight._apply
    *  apply matchHeight to given elements
    */

    matchHeight._apply = function (elements, options) {
        var opts = _parseOptions(options),
            $elements = $(elements),
            rows = [$elements];

        // take note of scroll position
        var scrollTop = $(window).scrollTop(),
            htmlHeight = $('html').outerHeight(true);

        // get hidden parents
        var $hiddenParents = $elements.parents().filter(':hidden');

        // cache the original inline style
        $hiddenParents.each(function () {
            var $that = $(this);
            $that.data('style-cache', $that.attr('style'));
        });

        // temporarily must force hidden parents visible
        $hiddenParents.css('display', 'block');

        // get rows if using byRow, otherwise assume one row
        if (opts.byRow && !opts.target) {

            // must first force an arbitrary equal height so floating elements break evenly
            $elements.each(function () {
                var $that = $(this),
                    display = $that.css('display');

                // temporarily force a usable display value
                if (display !== 'inline-block' && display !== 'inline-flex') {
                    display = 'block';
                }

                // cache the original inline style
                $that.data('style-cache', $that.attr('style'));

                $that.css({
                    'display': display,
                    'padding-top': '0',
                    'padding-bottom': '0',
                    'margin-top': '0',
                    'margin-bottom': '0',
                    'border-top-width': '0',
                    'border-bottom-width': '0',
                    'height': '100px'
                });
            });

            // get the array of rows (based on element top position)
            rows = _rows($elements);

            // revert original inline styles
            $elements.each(function () {
                var $that = $(this);
                $that.attr('style', $that.data('style-cache') || '');
            });
        }

        $.each(rows, function (key, row) {
            var $row = $(row),
                targetHeight = 0;

            if (!opts.target) {
                // skip apply to rows with only one item
                if (opts.byRow && $row.length <= 1) {
                    $row.css(opts.property, '');
                    return;
                }

                // iterate the row and find the max height
                $row.each(function () {
                    var $that = $(this),
                        display = $that.css('display');

                    // temporarily force a usable display value
                    if (display !== 'inline-block' && display !== 'inline-flex') {
                        display = 'block';
                    }

                    // ensure we get the correct actual height (and not a previously set height value)
                    var css = { 'display': display };
                    css[opts.property] = '';
                    $that.css(css);

                    // find the max height (including padding, but not margin)
                    if ($that.outerHeight(false) > targetHeight) {
                        targetHeight = $that.outerHeight(false);
                    }

                    // revert display block
                    $that.css('display', '');
                });
            } else {
                // if target set, use the height of the target element
                targetHeight = opts.target.outerHeight(false);
            }

            // iterate the row and apply the height to all elements
            $row.each(function () {
                var $that = $(this),
                    verticalPadding = 0;

                // don't apply to a target
                if (opts.target && $that.is(opts.target)) {
                    return;
                }

                // handle padding and border correctly (required when not using border-box)
                if ($that.css('box-sizing') !== 'border-box') {
                    verticalPadding += _parse($that.css('border-top-width')) + _parse($that.css('border-bottom-width'));
                    verticalPadding += _parse($that.css('padding-top')) + _parse($that.css('padding-bottom'));
                }

                // set the height (accounting for padding and border)
                $that.css(opts.property, (targetHeight - verticalPadding) + 'px');
            });
        });

        // revert hidden parents
        $hiddenParents.each(function () {
            var $that = $(this);
            $that.attr('style', $that.data('style-cache') || null);
        });

        // restore scroll position if enabled
        if (matchHeight._maintainScroll) {
            $(window).scrollTop((scrollTop / htmlHeight) * $('html').outerHeight(true));
        }

        return this;
    };

    /*
    *  matchHeight._applyDataApi
    *  applies matchHeight to all elements with a data-match-height attribute
    */

    matchHeight._applyDataApi = function () {
        var groups = {};

        // generate groups by their groupId set by elements using data-match-height
        $('[data-match-height], [data-mh]').each(function () {
            var $this = $(this),
                groupId = $this.attr('data-mh') || $this.attr('data-match-height');

            if (groupId in groups) {
                groups[groupId] = groups[groupId].add($this);
            } else {
                groups[groupId] = $this;
            }
        });

        // apply matchHeight to each group
        $.each(groups, function () {
            this.matchHeight(true);
        });
    };

    /*
    *  matchHeight._update
    *  updates matchHeight on all current groups with their correct options
    */

    var _update = function (event) {
        if (matchHeight._beforeUpdate) {
            matchHeight._beforeUpdate(event, matchHeight._groups);
        }

        $.each(matchHeight._groups, function () {
            matchHeight._apply(this.elements, this.options);
        });

        if (matchHeight._afterUpdate) {
            matchHeight._afterUpdate(event, matchHeight._groups);
        }
    };

    matchHeight._update = function (throttle, event) {
        // prevent update if fired from a resize event
        // where the viewport width hasn't actually changed
        // fixes an event looping bug in IE8
        if (event && event.type === 'resize') {
            var windowWidth = $(window).width();
            if (windowWidth === _previousResizeWidth) {
                return;
            }
            _previousResizeWidth = windowWidth;
        }

        // throttle updates
        if (!throttle) {
            _update(event);
        } else if (_updateTimeout === -1) {
            _updateTimeout = setTimeout(function () {
                _update(event);
                _updateTimeout = -1;
            }, matchHeight._throttle);
        }
    };

    /*
    *  bind events
    */

    // apply on DOM ready event
    $(matchHeight._applyDataApi);

    // update heights on load and resize events
    $(window).bind('load', function (event) {
        matchHeight._update(false, event);
    });

    // throttled update heights on resize events
    $(window).bind('resize orientationchange', function (event) {
        matchHeight._update(true, event);
    });

})(jQuery);;
/*!
 * headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it
 * Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js
 * License: MIT
 */

!function(a,b){"use strict";function c(a){this.callback=a,this.ticking=!1}function d(b){return b&&"undefined"!=typeof a&&(b===a||b.nodeType)}function e(a){if(arguments.length<=0)throw new Error("Missing arguments in extend function");var b,c,f=a||{};for(c=1;c<arguments.length;c++){var g=arguments[c]||{};for(b in g)f[b]="object"!=typeof f[b]||d(f[b])?f[b]||g[b]:e(f[b],g[b])}return f}function f(a){return a===Object(a)?a:{down:a,up:a}}function g(a,b){b=e(b,g.options),this.lastKnownScrollY=0,this.elem=a,this.debouncer=new c(this.update.bind(this)),this.tolerance=f(b.tolerance),this.classes=b.classes,this.offset=b.offset,this.scroller=b.scroller,this.initialised=!1,this.onPin=b.onPin,this.onUnpin=b.onUnpin,this.onTop=b.onTop,this.onNotTop=b.onNotTop}var h={bind:!!function(){}.bind,classList:"classList"in b.documentElement,rAF:!!(a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame)};a.requestAnimationFrame=a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame,c.prototype={constructor:c,update:function(){this.callback&&this.callback(),this.ticking=!1},requestTick:function(){this.ticking||(requestAnimationFrame(this.rafCallback||(this.rafCallback=this.update.bind(this))),this.ticking=!0)},handleEvent:function(){this.requestTick()}},g.prototype={constructor:g,init:function(){return g.cutsTheMustard?(this.elem.classList.add(this.classes.initial),setTimeout(this.attachEvent.bind(this),100),this):void 0},destroy:function(){var a=this.classes;this.initialised=!1,this.elem.classList.remove(a.unpinned,a.pinned,a.top,a.initial),this.scroller.removeEventListener("scroll",this.debouncer,!1)},attachEvent:function(){this.initialised||(this.lastKnownScrollY=this.getScrollY(),this.initialised=!0,this.scroller.addEventListener("scroll",this.debouncer,!1),this.debouncer.handleEvent())},unpin:function(){var a=this.elem.classList,b=this.classes;(a.contains(b.pinned)||!a.contains(b.unpinned))&&(a.add(b.unpinned),a.remove(b.pinned),this.onUnpin&&this.onUnpin.call(this))},pin:function(){var a=this.elem.classList,b=this.classes;a.contains(b.unpinned)&&(a.remove(b.unpinned),a.add(b.pinned),this.onPin&&this.onPin.call(this))},top:function(){var a=this.elem.classList,b=this.classes;a.contains(b.top)||(a.add(b.top),a.remove(b.notTop),this.onTop&&this.onTop.call(this))},notTop:function(){var a=this.elem.classList,b=this.classes;a.contains(b.notTop)||(a.add(b.notTop),a.remove(b.top),this.onNotTop&&this.onNotTop.call(this))},getScrollY:function(){return void 0!==this.scroller.pageYOffset?this.scroller.pageYOffset:void 0!==this.scroller.scrollTop?this.scroller.scrollTop:(b.documentElement||b.body.parentNode||b.body).scrollTop},getViewportHeight:function(){return a.innerHeight||b.documentElement.clientHeight||b.body.clientHeight},getDocumentHeight:function(){var a=b.body,c=b.documentElement;return Math.max(a.scrollHeight,c.scrollHeight,a.offsetHeight,c.offsetHeight,a.clientHeight,c.clientHeight)},getElementHeight:function(a){return Math.max(a.scrollHeight,a.offsetHeight,a.clientHeight)},getScrollerHeight:function(){return this.scroller===a||this.scroller===b.body?this.getDocumentHeight():this.getElementHeight(this.scroller)},isOutOfBounds:function(a){var b=0>a,c=a+this.getViewportHeight()>this.getScrollerHeight();return b||c},toleranceExceeded:function(a,b){return Math.abs(a-this.lastKnownScrollY)>=this.tolerance[b]},shouldUnpin:function(a,b){var c=a>this.lastKnownScrollY,d=a>=this.offset;return c&&d&&b},shouldPin:function(a,b){var c=a<this.lastKnownScrollY,d=a<=this.offset;return c&&b||d},update:function(){var a=this.getScrollY(),b=a>this.lastKnownScrollY?"down":"up",c=this.toleranceExceeded(a,b);this.isOutOfBounds(a)||(a<=this.offset?this.top():this.notTop(),this.shouldUnpin(a,c)?this.unpin():this.shouldPin(a,c)&&this.pin(),this.lastKnownScrollY=a)}},g.options={tolerance:{up:0,down:0},offset:0,scroller:a,classes:{pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",initial:"headroom"}},g.cutsTheMustard="undefined"!=typeof h&&h.rAF&&h.bind&&h.classList,a.Headroom=g}(window,document);;
/*!
 * headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it
 * Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js
 * License: MIT
 */

!function(a){a&&(a.fn.headroom=function(b){return this.each(function(){var c=a(this),d=c.data("headroom"),e="object"==typeof b&&b;e=a.extend(!0,{},Headroom.options,e),d||(d=new Headroom(this,e),d.init(),c.data("headroom",d)),"string"==typeof b&&d[b]()})},a("[data-headroom]").each(function(){var b=a(this);b.headroom(b.data())}))}(window.Zepto||window.jQuery);;
// Slidebars 0.10.2 (http://plugins.adchsm.me/slidebars/) written by Adam Smith (http://www.adchsm.me/) released under MIT License (http://plugins.adchsm.me/slidebars/license.txt)
!function(t){t.slidebars=function(s){function e(){!c.disableOver||"number"==typeof c.disableOver&&c.disableOver>=T?(y=!0,t("html").addClass("sb-init"),c.hideControlClasses&&k.removeClass("sb-hide"),i()):"number"==typeof c.disableOver&&c.disableOver<T&&(y=!1,t("html").removeClass("sb-init"),c.hideControlClasses&&k.addClass("sb-hide"),g.css("minHeight",""),(C||w)&&a())}function i(){g.css("minHeight",""),g.css("minHeight",t("html").height()+"px"),m&&m.hasClass("sb-width-custom")&&m.css("width",m.attr("data-sb-width")),p&&p.hasClass("sb-width-custom")&&p.css("width",p.attr("data-sb-width")),m&&(m.hasClass("sb-style-push")||m.hasClass("sb-style-overlay"))&&m.css("marginLeft","-"+m.css("width")),p&&(p.hasClass("sb-style-push")||p.hasClass("sb-style-overlay"))&&p.css("marginRight","-"+p.css("width")),c.scrollLock&&t("html").addClass("sb-scroll-lock")}function n(t,s,e){var n;if(n=t.hasClass("sb-style-push")?g.add(t).add(O):t.hasClass("sb-style-overlay")?t:g.add(O),"translate"===x)n.css("transform","translate("+s+")");else if("side"===x)"-"===s[0]&&(s=s.substr(1)),"0px"!==s&&n.css(e,"0px"),setTimeout(function(){n.css(e,s)},1);else if("jQuery"===x){"-"===s[0]&&(s=s.substr(1));var o={};o[e]=s,n.stop().animate(o,400)}setTimeout(function(){"0px"===s&&(n.removeAttr("style"),i())},400)}function o(s){function e(){y&&"left"===s&&m?(t("html").addClass("sb-active sb-active-left"),m.addClass("sb-active"),n(m,m.css("width"),"left"),setTimeout(function(){C=!0},400)):y&&"right"===s&&p&&(t("html").addClass("sb-active sb-active-right"),p.addClass("sb-active"),n(p,"-"+p.css("width"),"right"),setTimeout(function(){w=!0},400))}"left"===s&&m&&w||"right"===s&&p&&C?(a(),setTimeout(e,400)):e()}function a(s){(C||w)&&(C&&(n(m,"0px","left"),C=!1),w&&(n(p,"0px","right"),w=!1),setTimeout(function(){t("html").removeClass("sb-active sb-active-left sb-active-right"),m&&m.removeClass("sb-active"),p&&p.removeClass("sb-active"),"undefined"!=typeof s&&(window.location=s)},400))}function l(t){"left"===t&&m&&(C?a():o("left")),"right"===t&&p&&(w?a():o("right"))}function r(t,s){t.stopPropagation(),t.preventDefault(),"touchend"===t.type&&s.off("click")}var c=t.extend({siteClose:!0,scrollLock:!1,disableOver:!1,hideControlClasses:!1},s),h=document.createElement("div").style,d=!1,f=!1;(""===h.MozTransition||""===h.WebkitTransition||""===h.OTransition||""===h.transition)&&(d=!0),(""===h.MozTransform||""===h.WebkitTransform||""===h.OTransform||""===h.transform)&&(f=!0);var u=navigator.userAgent,b=!1,v=!1;/Android/.test(u)?b=u.substr(u.indexOf("Android")+8,3):/(iPhone|iPod|iPad)/.test(u)&&(v=u.substr(u.indexOf("OS ")+3,3).replace("_",".")),(b&&3>b||v&&5>v)&&t("html").addClass("sb-static");var g=t("#sb-site, .sb-site-container");if(t(".sb-left").length)var m=t(".sb-left"),C=!1;if(t(".sb-right").length)var p=t(".sb-right"),w=!1;var y=!1,T=t(window).width(),k=t(".sb-toggle-left, .sb-toggle-right, .sb-open-left, .sb-open-right, .sb-close"),O=t(".sb-slide");e(),t(window).resize(function(){var s=t(window).width();T!==s&&(T=s,e(),C&&o("left"),w&&o("right"))});var x;d&&f?(x="translate",b&&4.4>b&&(x="side")):x="jQuery",this.slidebars={open:o,close:a,toggle:l,init:function(){return y},active:function(t){return"left"===t&&m?C:"right"===t&&p?w:void 0},destroy:function(t){"left"===t&&m&&(C&&a(),setTimeout(function(){m.remove(),m=!1},400)),"right"===t&&p&&(w&&a(),setTimeout(function(){p.remove(),p=!1},400))}},t(".sb-toggle-left").on("touchend click",function(s){r(s,t(this)),l("left")}),t(".sb-toggle-right").on("touchend click",function(s){r(s,t(this)),l("right")}),t(".sb-open-left").on("touchend click",function(s){r(s,t(this)),o("left")}),t(".sb-open-right").on("touchend click",function(s){r(s,t(this)),o("right")}),t(".sb-close").on("touchend click",function(s){if(t(this).is("a")||t(this).children().is("a")){if("click"===s.type){s.preventDefault();var e=t(this).is("a")?t(this).attr("href"):t(this).find("a").attr("href");a(e)}}else r(s,t(this)),a()}),g.on("touchend click",function(s){c.siteClose&&(C||w)&&(r(s,t(this)),a())})}}(jQuery);;
/**
 * @license
 * Video.js 5.8.8 <http://videojs.com/>
 * Copyright Brightcove, Inc. <https://www.brightcove.com/>
 * Available under Apache License Version 2.0
 * <https://github.com/videojs/video.js/blob/master/LICENSE>
 *
 * Includes vtt.js <https://github.com/mozilla/vtt.js>
 * Available under Apache License Version 2.0
 * <https://github.com/mozilla/vtt.js/blob/master/LICENSE>
 */

(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.videojs = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
(function (global){
var topLevel = typeof global !== 'undefined' ? global :
    typeof window !== 'undefined' ? window : {}
var minDoc = _dereq_('min-document');

if (typeof document !== 'undefined') {
    module.exports = document;
} else {
    var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];

    if (!doccy) {
        doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;
    }

    module.exports = doccy;
}

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9nbG9iYWwvZG9jdW1lbnQuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgdG9wTGV2ZWwgPSB0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbCA6XG4gICAgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB7fVxudmFyIG1pbkRvYyA9IHJlcXVpcmUoJ21pbi1kb2N1bWVudCcpO1xuXG5pZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZG9jdW1lbnQ7XG59IGVsc2Uge1xuICAgIHZhciBkb2NjeSA9IHRvcExldmVsWydfX0dMT0JBTF9ET0NVTUVOVF9DQUNIRUA0J107XG5cbiAgICBpZiAoIWRvY2N5KSB7XG4gICAgICAgIGRvY2N5ID0gdG9wTGV2ZWxbJ19fR0xPQkFMX0RPQ1VNRU5UX0NBQ0hFQDQnXSA9IG1pbkRvYztcbiAgICB9XG5cbiAgICBtb2R1bGUuZXhwb3J0cyA9IGRvY2N5O1xufVxuIl19
},{"min-document":3}],2:[function(_dereq_,module,exports){
(function (global){
if (typeof window !== "undefined") {
    module.exports = window;
} else if (typeof global !== "undefined") {
    module.exports = global;
} else if (typeof self !== "undefined"){
    module.exports = self;
} else {
    module.exports = {};
}

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9nbG9iYWwvd2luZG93LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHdpbmRvdztcbn0gZWxzZSBpZiAodHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZ2xvYmFsO1xufSBlbHNlIGlmICh0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIil7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBzZWxmO1xufSBlbHNlIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHt9O1xufVxuIl19
},{}],3:[function(_dereq_,module,exports){

},{}],4:[function(_dereq_,module,exports){
var getNative = _dereq_('../internal/getNative');

/* Native method references for those with the same name as other `lodash` methods. */
var nativeNow = getNative(Date, 'now');

/**
 * Gets the number of milliseconds that have elapsed since the Unix epoch
 * (1 January 1970 00:00:00 UTC).
 *
 * @static
 * @memberOf _
 * @category Date
 * @example
 *
 * _.defer(function(stamp) {
 *   console.log(_.now() - stamp);
 * }, _.now());
 * // => logs the number of milliseconds it took for the deferred function to be invoked
 */
var now = nativeNow || function() {
  return new Date().getTime();
};

module.exports = now;

},{"../internal/getNative":20}],5:[function(_dereq_,module,exports){
var isObject = _dereq_('../lang/isObject'),
    now = _dereq_('../date/now');

/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';

/* Native method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;

/**
 * Creates a debounced function that delays invoking `func` until after `wait`
 * milliseconds have elapsed since the last time the debounced function was
 * invoked. The debounced function comes with a `cancel` method to cancel
 * delayed invocations. Provide an options object to indicate that `func`
 * should be invoked on the leading and/or trailing edge of the `wait` timeout.
 * Subsequent calls to the debounced function return the result of the last
 * `func` invocation.
 *
 * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
 * on the trailing edge of the timeout only if the the debounced function is
 * invoked more than once during the `wait` timeout.
 *
 * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
 * for details over the differences between `_.debounce` and `_.throttle`.
 *
 * @static
 * @memberOf _
 * @category Function
 * @param {Function} func The function to debounce.
 * @param {number} [wait=0] The number of milliseconds to delay.
 * @param {Object} [options] The options object.
 * @param {boolean} [options.leading=false] Specify invoking on the leading
 *  edge of the timeout.
 * @param {number} [options.maxWait] The maximum time `func` is allowed to be
 *  delayed before it's invoked.
 * @param {boolean} [options.trailing=true] Specify invoking on the trailing
 *  edge of the timeout.
 * @returns {Function} Returns the new debounced function.
 * @example
 *
 * // avoid costly calculations while the window size is in flux
 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
 *
 * // invoke `sendMail` when the click event is fired, debouncing subsequent calls
 * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
 *   'leading': true,
 *   'trailing': false
 * }));
 *
 * // ensure `batchLog` is invoked once after 1 second of debounced calls
 * var source = new EventSource('/stream');
 * jQuery(source).on('message', _.debounce(batchLog, 250, {
 *   'maxWait': 1000
 * }));
 *
 * // cancel a debounced call
 * var todoChanges = _.debounce(batchLog, 1000);
 * Object.observe(models.todo, todoChanges);
 *
 * Object.observe(models, function(changes) {
 *   if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) {
 *     todoChanges.cancel();
 *   }
 * }, ['delete']);
 *
 * // ...at some point `models.todo` is changed
 * models.todo.completed = true;
 *
 * // ...before 1 second has passed `models.todo` is deleted
 * // which cancels the debounced `todoChanges` call
 * delete models.todo;
 */
function debounce(func, wait, options) {
  var args,
      maxTimeoutId,
      result,
      stamp,
      thisArg,
      timeoutId,
      trailingCall,
      lastCalled = 0,
      maxWait = false,
      trailing = true;

  if (typeof func != 'function') {
    throw new TypeError(FUNC_ERROR_TEXT);
  }
  wait = wait < 0 ? 0 : (+wait || 0);
  if (options === true) {
    var leading = true;
    trailing = false;
  } else if (isObject(options)) {
    leading = !!options.leading;
    maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);
    trailing = 'trailing' in options ? !!options.trailing : trailing;
  }

  function cancel() {
    if (timeoutId) {
      clearTimeout(timeoutId);
    }
    if (maxTimeoutId) {
      clearTimeout(maxTimeoutId);
    }
    lastCalled = 0;
    maxTimeoutId = timeoutId = trailingCall = undefined;
  }

  function complete(isCalled, id) {
    if (id) {
      clearTimeout(id);
    }
    maxTimeoutId = timeoutId = trailingCall = undefined;
    if (isCalled) {
      lastCalled = now();
      result = func.apply(thisArg, args);
      if (!timeoutId && !maxTimeoutId) {
        args = thisArg = undefined;
      }
    }
  }

  function delayed() {
    var remaining = wait - (now() - stamp);
    if (remaining <= 0 || remaining > wait) {
      complete(trailingCall, maxTimeoutId);
    } else {
      timeoutId = setTimeout(delayed, remaining);
    }
  }

  function maxDelayed() {
    complete(trailing, timeoutId);
  }

  function debounced() {
    args = arguments;
    stamp = now();
    thisArg = this;
    trailingCall = trailing && (timeoutId || !leading);

    if (maxWait === false) {
      var leadingCall = leading && !timeoutId;
    } else {
      if (!maxTimeoutId && !leading) {
        lastCalled = stamp;
      }
      var remaining = maxWait - (stamp - lastCalled),
          isCalled = remaining <= 0 || remaining > maxWait;

      if (isCalled) {
        if (maxTimeoutId) {
          maxTimeoutId = clearTimeout(maxTimeoutId);
        }
        lastCalled = stamp;
        result = func.apply(thisArg, args);
      }
      else if (!maxTimeoutId) {
        maxTimeoutId = setTimeout(maxDelayed, remaining);
      }
    }
    if (isCalled && timeoutId) {
      timeoutId = clearTimeout(timeoutId);
    }
    else if (!timeoutId && wait !== maxWait) {
      timeoutId = setTimeout(delayed, wait);
    }
    if (leadingCall) {
      isCalled = true;
      result = func.apply(thisArg, args);
    }
    if (isCalled && !timeoutId && !maxTimeoutId) {
      args = thisArg = undefined;
    }
    return result;
  }
  debounced.cancel = cancel;
  return debounced;
}

module.exports = debounce;

},{"../date/now":4,"../lang/isObject":33}],6:[function(_dereq_,module,exports){
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';

/* Native method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;

/**
 * Creates a function that invokes `func` with the `this` binding of the
 * created function and arguments from `start` and beyond provided as an array.
 *
 * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).
 *
 * @static
 * @memberOf _
 * @category Function
 * @param {Function} func The function to apply a rest parameter to.
 * @param {number} [start=func.length-1] The start position of the rest parameter.
 * @returns {Function} Returns the new function.
 * @example
 *
 * var say = _.restParam(function(what, names) {
 *   return what + ' ' + _.initial(names).join(', ') +
 *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
 * });
 *
 * say('hello', 'fred', 'barney', 'pebbles');
 * // => 'hello fred, barney, & pebbles'
 */
function restParam(func, start) {
  if (typeof func != 'function') {
    throw new TypeError(FUNC_ERROR_TEXT);
  }
  start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
  return function() {
    var args = arguments,
        index = -1,
        length = nativeMax(args.length - start, 0),
        rest = Array(length);

    while (++index < length) {
      rest[index] = args[start + index];
    }
    switch (start) {
      case 0: return func.call(this, rest);
      case 1: return func.call(this, args[0], rest);
      case 2: return func.call(this, args[0], args[1], rest);
    }
    var otherArgs = Array(start + 1);
    index = -1;
    while (++index < start) {
      otherArgs[index] = args[index];
    }
    otherArgs[start] = rest;
    return func.apply(this, otherArgs);
  };
}

module.exports = restParam;

},{}],7:[function(_dereq_,module,exports){
var debounce = _dereq_('./debounce'),
    isObject = _dereq_('../lang/isObject');

/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';

/**
 * Creates a throttled function that only invokes `func` at most once per
 * every `wait` milliseconds. The throttled function comes with a `cancel`
 * method to cancel delayed invocations. Provide an options object to indicate
 * that `func` should be invoked on the leading and/or trailing edge of the
 * `wait` timeout. Subsequent calls to the throttled function return the
 * result of the last `func` call.
 *
 * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
 * on the trailing edge of the timeout only if the the throttled function is
 * invoked more than once during the `wait` timeout.
 *
 * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
 * for details over the differences between `_.throttle` and `_.debounce`.
 *
 * @static
 * @memberOf _
 * @category Function
 * @param {Function} func The function to throttle.
 * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
 * @param {Object} [options] The options object.
 * @param {boolean} [options.leading=true] Specify invoking on the leading
 *  edge of the timeout.
 * @param {boolean} [options.trailing=true] Specify invoking on the trailing
 *  edge of the timeout.
 * @returns {Function} Returns the new throttled function.
 * @example
 *
 * // avoid excessively updating the position while scrolling
 * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
 *
 * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes
 * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
 *   'trailing': false
 * }));
 *
 * // cancel a trailing throttled call
 * jQuery(window).on('popstate', throttled.cancel);
 */
function throttle(func, wait, options) {
  var leading = true,
      trailing = true;

  if (typeof func != 'function') {
    throw new TypeError(FUNC_ERROR_TEXT);
  }
  if (options === false) {
    leading = false;
  } else if (isObject(options)) {
    leading = 'leading' in options ? !!options.leading : leading;
    trailing = 'trailing' in options ? !!options.trailing : trailing;
  }
  return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing });
}

module.exports = throttle;

},{"../lang/isObject":33,"./debounce":5}],8:[function(_dereq_,module,exports){
/**
 * Copies the values of `source` to `array`.
 *
 * @private
 * @param {Array} source The array to copy values from.
 * @param {Array} [array=[]] The array to copy values to.
 * @returns {Array} Returns `array`.
 */
function arrayCopy(source, array) {
  var index = -1,
      length = source.length;

  array || (array = Array(length));
  while (++index < length) {
    array[index] = source[index];
  }
  return array;
}

module.exports = arrayCopy;

},{}],9:[function(_dereq_,module,exports){
/**
 * A specialized version of `_.forEach` for arrays without support for callback
 * shorthands and `this` binding.
 *
 * @private
 * @param {Array} array The array to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns `array`.
 */
function arrayEach(array, iteratee) {
  var index = -1,
      length = array.length;

  while (++index < length) {
    if (iteratee(array[index], index, array) === false) {
      break;
    }
  }
  return array;
}

module.exports = arrayEach;

},{}],10:[function(_dereq_,module,exports){
/**
 * Copies properties of `source` to `object`.
 *
 * @private
 * @param {Object} source The object to copy properties from.
 * @param {Array} props The property names to copy.
 * @param {Object} [object={}] The object to copy properties to.
 * @returns {Object} Returns `object`.
 */
function baseCopy(source, props, object) {
  object || (object = {});

  var index = -1,
      length = props.length;

  while (++index < length) {
    var key = props[index];
    object[key] = source[key];
  }
  return object;
}

module.exports = baseCopy;

},{}],11:[function(_dereq_,module,exports){
var createBaseFor = _dereq_('./createBaseFor');

/**
 * The base implementation of `baseForIn` and `baseForOwn` which iterates
 * over `object` properties returned by `keysFunc` invoking `iteratee` for
 * each property. Iteratee functions may exit iteration early by explicitly
 * returning `false`.
 *
 * @private
 * @param {Object} object The object to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @param {Function} keysFunc The function to get the keys of `object`.
 * @returns {Object} Returns `object`.
 */
var baseFor = createBaseFor();

module.exports = baseFor;

},{"./createBaseFor":18}],12:[function(_dereq_,module,exports){
var baseFor = _dereq_('./baseFor'),
    keysIn = _dereq_('../object/keysIn');

/**
 * The base implementation of `_.forIn` without support for callback
 * shorthands and `this` binding.
 *
 * @private
 * @param {Object} object The object to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Object} Returns `object`.
 */
function baseForIn(object, iteratee) {
  return baseFor(object, iteratee, keysIn);
}

module.exports = baseForIn;

},{"../object/keysIn":39,"./baseFor":11}],13:[function(_dereq_,module,exports){
var arrayEach = _dereq_('./arrayEach'),
    baseMergeDeep = _dereq_('./baseMergeDeep'),
    isArray = _dereq_('../lang/isArray'),
    isArrayLike = _dereq_('./isArrayLike'),
    isObject = _dereq_('../lang/isObject'),
    isObjectLike = _dereq_('./isObjectLike'),
    isTypedArray = _dereq_('../lang/isTypedArray'),
    keys = _dereq_('../object/keys');

/**
 * The base implementation of `_.merge` without support for argument juggling,
 * multiple sources, and `this` binding `customizer` functions.
 *
 * @private
 * @param {Object} object The destination object.
 * @param {Object} source The source object.
 * @param {Function} [customizer] The function to customize merged values.
 * @param {Array} [stackA=[]] Tracks traversed source objects.
 * @param {Array} [stackB=[]] Associates values with source counterparts.
 * @returns {Object} Returns `object`.
 */
function baseMerge(object, source, customizer, stackA, stackB) {
  if (!isObject(object)) {
    return object;
  }
  var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
      props = isSrcArr ? undefined : keys(source);

  arrayEach(props || source, function(srcValue, key) {
    if (props) {
      key = srcValue;
      srcValue = source[key];
    }
    if (isObjectLike(srcValue)) {
      stackA || (stackA = []);
      stackB || (stackB = []);
      baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
    }
    else {
      var value = object[key],
          result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
          isCommon = result === undefined;

      if (isCommon) {
        result = srcValue;
      }
      if ((result !== undefined || (isSrcArr && !(key in object))) &&
          (isCommon || (result === result ? (result !== value) : (value === value)))) {
        object[key] = result;
      }
    }
  });
  return object;
}

module.exports = baseMerge;

},{"../lang/isArray":30,"../lang/isObject":33,"../lang/isTypedArray":36,"../object/keys":38,"./arrayEach":9,"./baseMergeDeep":14,"./isArrayLike":21,"./isObjectLike":26}],14:[function(_dereq_,module,exports){
var arrayCopy = _dereq_('./arrayCopy'),
    isArguments = _dereq_('../lang/isArguments'),
    isArray = _dereq_('../lang/isArray'),
    isArrayLike = _dereq_('./isArrayLike'),
    isPlainObject = _dereq_('../lang/isPlainObject'),
    isTypedArray = _dereq_('../lang/isTypedArray'),
    toPlainObject = _dereq_('../lang/toPlainObject');

/**
 * A specialized version of `baseMerge` for arrays and objects which performs
 * deep merges and tracks traversed objects enabling objects with circular
 * references to be merged.
 *
 * @private
 * @param {Object} object The destination object.
 * @param {Object} source The source object.
 * @param {string} key The key of the value to merge.
 * @param {Function} mergeFunc The function to merge values.
 * @param {Function} [customizer] The function to customize merged values.
 * @param {Array} [stackA=[]] Tracks traversed source objects.
 * @param {Array} [stackB=[]] Associates values with source counterparts.
 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
 */
function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {
  var length = stackA.length,
      srcValue = source[key];

  while (length--) {
    if (stackA[length] == srcValue) {
      object[key] = stackB[length];
      return;
    }
  }
  var value = object[key],
      result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
      isCommon = result === undefined;

  if (isCommon) {
    result = srcValue;
    if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) {
      result = isArray(value)
        ? value
        : (isArrayLike(value) ? arrayCopy(value) : []);
    }
    else if (isPlainObject(srcValue) || isArguments(srcValue)) {
      result = isArguments(value)
        ? toPlainObject(value)
        : (isPlainObject(value) ? value : {});
    }
    else {
      isCommon = false;
    }
  }
  // Add the source value to the stack of traversed objects and associate
  // it with its merged value.
  stackA.push(srcValue);
  stackB.push(result);

  if (isCommon) {
    // Recursively merge objects and arrays (susceptible to call stack limits).
    object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
  } else if (result === result ? (result !== value) : (value === value)) {
    object[key] = result;
  }
}

module.exports = baseMergeDeep;

},{"../lang/isArguments":29,"../lang/isArray":30,"../lang/isPlainObject":34,"../lang/isTypedArray":36,"../lang/toPlainObject":37,"./arrayCopy":8,"./isArrayLike":21}],15:[function(_dereq_,module,exports){
var toObject = _dereq_('./toObject');

/**
 * The base implementation of `_.property` without support for deep paths.
 *
 * @private
 * @param {string} key The key of the property to get.
 * @returns {Function} Returns the new function.
 */
function baseProperty(key) {
  return function(object) {
    return object == null ? undefined : toObject(object)[key];
  };
}

module.exports = baseProperty;

},{"./toObject":28}],16:[function(_dereq_,module,exports){
var identity = _dereq_('../utility/identity');

/**
 * A specialized version of `baseCallback` which only supports `this` binding
 * and specifying the number of arguments to provide to `func`.
 *
 * @private
 * @param {Function} func The function to bind.
 * @param {*} thisArg The `this` binding of `func`.
 * @param {number} [argCount] The number of arguments to provide to `func`.
 * @returns {Function} Returns the callback.
 */
function bindCallback(func, thisArg, argCount) {
  if (typeof func != 'function') {
    return identity;
  }
  if (thisArg === undefined) {
    return func;
  }
  switch (argCount) {
    case 1: return function(value) {
      return func.call(thisArg, value);
    };
    case 3: return function(value, index, collection) {
      return func.call(thisArg, value, index, collection);
    };
    case 4: return function(accumulator, value, index, collection) {
      return func.call(thisArg, accumulator, value, index, collection);
    };
    case 5: return function(value, other, key, object, source) {
      return func.call(thisArg, value, other, key, object, source);
    };
  }
  return function() {
    return func.apply(thisArg, arguments);
  };
}

module.exports = bindCallback;

},{"../utility/identity":42}],17:[function(_dereq_,module,exports){
var bindCallback = _dereq_('./bindCallback'),
    isIterateeCall = _dereq_('./isIterateeCall'),
    restParam = _dereq_('../function/restParam');

/**
 * Creates a `_.assign`, `_.defaults`, or `_.merge` function.
 *
 * @private
 * @param {Function} assigner The function to assign values.
 * @returns {Function} Returns the new assigner function.
 */
function createAssigner(assigner) {
  return restParam(function(object, sources) {
    var index = -1,
        length = object == null ? 0 : sources.length,
        customizer = length > 2 ? sources[length - 2] : undefined,
        guard = length > 2 ? sources[2] : undefined,
        thisArg = length > 1 ? sources[length - 1] : undefined;

    if (typeof customizer == 'function') {
      customizer = bindCallback(customizer, thisArg, 5);
      length -= 2;
    } else {
      customizer = typeof thisArg == 'function' ? thisArg : undefined;
      length -= (customizer ? 1 : 0);
    }
    if (guard && isIterateeCall(sources[0], sources[1], guard)) {
      customizer = length < 3 ? undefined : customizer;
      length = 1;
    }
    while (++index < length) {
      var source = sources[index];
      if (source) {
        assigner(object, source, customizer);
      }
    }
    return object;
  });
}

module.exports = createAssigner;

},{"../function/restParam":6,"./bindCallback":16,"./isIterateeCall":24}],18:[function(_dereq_,module,exports){
var toObject = _dereq_('./toObject');

/**
 * Creates a base function for `_.forIn` or `_.forInRight`.
 *
 * @private
 * @param {boolean} [fromRight] Specify iterating from right to left.
 * @returns {Function} Returns the new base function.
 */
function createBaseFor(fromRight) {
  return function(object, iteratee, keysFunc) {
    var iterable = toObject(object),
        props = keysFunc(object),
        length = props.length,
        index = fromRight ? length : -1;

    while ((fromRight ? index-- : ++index < length)) {
      var key = props[index];
      if (iteratee(iterable[key], key, iterable) === false) {
        break;
      }
    }
    return object;
  };
}

module.exports = createBaseFor;

},{"./toObject":28}],19:[function(_dereq_,module,exports){
var baseProperty = _dereq_('./baseProperty');

/**
 * Gets the "length" property value of `object`.
 *
 * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
 * that affects Safari on at least iOS 8.1-8.3 ARM64.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {*} Returns the "length" value.
 */
var getLength = baseProperty('length');

module.exports = getLength;

},{"./baseProperty":15}],20:[function(_dereq_,module,exports){
var isNative = _dereq_('../lang/isNative');

/**
 * Gets the native function at `key` of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {string} key The key of the method to get.
 * @returns {*} Returns the function if it's native, else `undefined`.
 */
function getNative(object, key) {
  var value = object == null ? undefined : object[key];
  return isNative(value) ? value : undefined;
}

module.exports = getNative;

},{"../lang/isNative":32}],21:[function(_dereq_,module,exports){
var getLength = _dereq_('./getLength'),
    isLength = _dereq_('./isLength');

/**
 * Checks if `value` is array-like.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
 */
function isArrayLike(value) {
  return value != null && isLength(getLength(value));
}

module.exports = isArrayLike;

},{"./getLength":19,"./isLength":25}],22:[function(_dereq_,module,exports){
/**
 * Checks if `value` is a host object in IE < 9.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
 */
var isHostObject = (function() {
  try {
    Object({ 'toString': 0 } + '');
  } catch(e) {
    return function() { return false; };
  }
  return function(value) {
    // IE < 9 presents many host objects as `Object` objects that can coerce
    // to strings despite having improperly defined `toString` methods.
    return typeof value.toString != 'function' && typeof (value + '') == 'string';
  };
}());

module.exports = isHostObject;

},{}],23:[function(_dereq_,module,exports){
/** Used to detect unsigned integer values. */
var reIsUint = /^\d+$/;

/**
 * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
 * of an array-like value.
 */
var MAX_SAFE_INTEGER = 9007199254740991;

/**
 * Checks if `value` is a valid array-like index.
 *
 * @private
 * @param {*} value The value to check.
 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
 */
function isIndex(value, length) {
  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
  length = length == null ? MAX_SAFE_INTEGER : length;
  return value > -1 && value % 1 == 0 && value < length;
}

module.exports = isIndex;

},{}],24:[function(_dereq_,module,exports){
var isArrayLike = _dereq_('./isArrayLike'),
    isIndex = _dereq_('./isIndex'),
    isObject = _dereq_('../lang/isObject');

/**
 * Checks if the provided arguments are from an iteratee call.
 *
 * @private
 * @param {*} value The potential iteratee value argument.
 * @param {*} index The potential iteratee index or key argument.
 * @param {*} object The potential iteratee object argument.
 * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
 */
function isIterateeCall(value, index, object) {
  if (!isObject(object)) {
    return false;
  }
  var type = typeof index;
  if (type == 'number'
      ? (isArrayLike(object) && isIndex(index, object.length))
      : (type == 'string' && index in object)) {
    var other = object[index];
    return value === value ? (value === other) : (other !== other);
  }
  return false;
}

module.exports = isIterateeCall;

},{"../lang/isObject":33,"./isArrayLike":21,"./isIndex":23}],25:[function(_dereq_,module,exports){
/**
 * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
 * of an array-like value.
 */
var MAX_SAFE_INTEGER = 9007199254740991;

/**
 * Checks if `value` is a valid array-like length.
 *
 * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
 */
function isLength(value) {
  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
}

module.exports = isLength;

},{}],26:[function(_dereq_,module,exports){
/**
 * Checks if `value` is object-like.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
 */
function isObjectLike(value) {
  return !!value && typeof value == 'object';
}

module.exports = isObjectLike;

},{}],27:[function(_dereq_,module,exports){
var isArguments = _dereq_('../lang/isArguments'),
    isArray = _dereq_('../lang/isArray'),
    isIndex = _dereq_('./isIndex'),
    isLength = _dereq_('./isLength'),
    isString = _dereq_('../lang/isString'),
    keysIn = _dereq_('../object/keysIn');

/** Used for native method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * A fallback implementation of `Object.keys` which creates an array of the
 * own enumerable property names of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 */
function shimKeys(object) {
  var props = keysIn(object),
      propsLength = props.length,
      length = propsLength && object.length;

  var allowIndexes = !!length && isLength(length) &&
    (isArray(object) || isArguments(object) || isString(object));

  var index = -1,
      result = [];

  while (++index < propsLength) {
    var key = props[index];
    if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
      result.push(key);
    }
  }
  return result;
}

module.exports = shimKeys;

},{"../lang/isArguments":29,"../lang/isArray":30,"../lang/isString":35,"../object/keysIn":39,"./isIndex":23,"./isLength":25}],28:[function(_dereq_,module,exports){
var isObject = _dereq_('../lang/isObject'),
    isString = _dereq_('../lang/isString'),
    support = _dereq_('../support');

/**
 * Converts `value` to an object if it's not one.
 *
 * @private
 * @param {*} value The value to process.
 * @returns {Object} Returns the object.
 */
function toObject(value) {
  if (support.unindexedChars && isString(value)) {
    var index = -1,
        length = value.length,
        result = Object(value);

    while (++index < length) {
      result[index] = value.charAt(index);
    }
    return result;
  }
  return isObject(value) ? value : Object(value);
}

module.exports = toObject;

},{"../lang/isObject":33,"../lang/isString":35,"../support":41}],29:[function(_dereq_,module,exports){
var isArrayLike = _dereq_('../internal/isArrayLike'),
    isObjectLike = _dereq_('../internal/isObjectLike');

/** Used for native method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/** Native method references. */
var propertyIsEnumerable = objectProto.propertyIsEnumerable;

/**
 * Checks if `value` is classified as an `arguments` object.
 *
 * @static
 * @memberOf _
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
 * @example
 *
 * _.isArguments(function() { return arguments; }());
 * // => true
 *
 * _.isArguments([1, 2, 3]);
 * // => false
 */
function isArguments(value) {
  return isObjectLike(value) && isArrayLike(value) &&
    hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
}

module.exports = isArguments;

},{"../internal/isArrayLike":21,"../internal/isObjectLike":26}],30:[function(_dereq_,module,exports){
var getNative = _dereq_('../internal/getNative'),
    isLength = _dereq_('../internal/isLength'),
    isObjectLike = _dereq_('../internal/isObjectLike');

/** `Object#toString` result references. */
var arrayTag = '[object Array]';

/** Used for native method references. */
var objectProto = Object.prototype;

/**
 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
 * of values.
 */
var objToString = objectProto.toString;

/* Native method references for those with the same name as other `lodash` methods. */
var nativeIsArray = getNative(Array, 'isArray');

/**
 * Checks if `value` is classified as an `Array` object.
 *
 * @static
 * @memberOf _
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
 * @example
 *
 * _.isArray([1, 2, 3]);
 * // => true
 *
 * _.isArray(function() { return arguments; }());
 * // => false
 */
var isArray = nativeIsArray || function(value) {
  return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
};

module.exports = isArray;

},{"../internal/getNative":20,"../internal/isLength":25,"../internal/isObjectLike":26}],31:[function(_dereq_,module,exports){
var isObject = _dereq_('./isObject');

/** `Object#toString` result references. */
var funcTag = '[object Function]';

/** Used for native method references. */
var objectProto = Object.prototype;

/**
 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
 * of values.
 */
var objToString = objectProto.toString;

/**
 * Checks if `value` is classified as a `Function` object.
 *
 * @static
 * @memberOf _
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
 * @example
 *
 * _.isFunction(_);
 * // => true
 *
 * _.isFunction(/abc/);
 * // => false
 */
function isFunction(value) {
  // The use of `Object#toString` avoids issues with the `typeof` operator
  // in older versions of Chrome and Safari which return 'function' for regexes
  // and Safari 8 which returns 'object' for typed array constructors.
  return isObject(value) && objToString.call(value) == funcTag;
}

module.exports = isFunction;

},{"./isObject":33}],32:[function(_dereq_,module,exports){
var isFunction = _dereq_('./isFunction'),
    isHostObject = _dereq_('../internal/isHostObject'),
    isObjectLike = _dereq_('../internal/isObjectLike');

/** Used to detect host constructors (Safari > 5). */
var reIsHostCtor = /^\[object .+?Constructor\]$/;

/** Used for native method references. */
var objectProto = Object.prototype;

/** Used to resolve the decompiled source of functions. */
var fnToString = Function.prototype.toString;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/** Used to detect if a method is native. */
var reIsNative = RegExp('^' +
  fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);

/**
 * Checks if `value` is a native function.
 *
 * @static
 * @memberOf _
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
 * @example
 *
 * _.isNative(Array.prototype.push);
 * // => true
 *
 * _.isNative(_);
 * // => false
 */
function isNative(value) {
  if (value == null) {
    return false;
  }
  if (isFunction(value)) {
    return reIsNative.test(fnToString.call(value));
  }
  return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
}

module.exports = isNative;

},{"../internal/isHostObject":22,"../internal/isObjectLike":26,"./isFunction":31}],33:[function(_dereq_,module,exports){
/**
 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
 *
 * @static
 * @memberOf _
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
 * @example
 *
 * _.isObject({});
 * // => true
 *
 * _.isObject([1, 2, 3]);
 * // => true
 *
 * _.isObject(1);
 * // => false
 */
function isObject(value) {
  // Avoid a V8 JIT bug in Chrome 19-20.
  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
  var type = typeof value;
  return !!value && (type == 'object' || type == 'function');
}

module.exports = isObject;

},{}],34:[function(_dereq_,module,exports){
var baseForIn = _dereq_('../internal/baseForIn'),
    isArguments = _dereq_('./isArguments'),
    isHostObject = _dereq_('../internal/isHostObject'),
    isObjectLike = _dereq_('../internal/isObjectLike'),
    support = _dereq_('../support');

/** `Object#toString` result references. */
var objectTag = '[object Object]';

/** Used for native method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
 * of values.
 */
var objToString = objectProto.toString;

/**
 * Checks if `value` is a plain object, that is, an object created by the
 * `Object` constructor or one with a `[[Prototype]]` of `null`.
 *
 * **Note:** This method assumes objects created by the `Object` constructor
 * have no inherited enumerable properties.
 *
 * @static
 * @memberOf _
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 * }
 *
 * _.isPlainObject(new Foo);
 * // => false
 *
 * _.isPlainObject([1, 2, 3]);
 * // => false
 *
 * _.isPlainObject({ 'x': 0, 'y': 0 });
 * // => true
 *
 * _.isPlainObject(Object.create(null));
 * // => true
 */
function isPlainObject(value) {
  var Ctor;

  // Exit early for non `Object` objects.
  if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) ||
      (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
    return false;
  }
  // IE < 9 iterates inherited properties before own properties. If the first
  // iterated property is an object's own property then there are no inherited
  // enumerable properties.
  var result;
  if (support.ownLast) {
    baseForIn(value, function(subValue, key, object) {
      result = hasOwnProperty.call(object, key);
      return false;
    });
    return result !== false;
  }
  // In most environments an object's own properties are iterated before
  // its inherited properties. If the last iterated property is an object's
  // own property then there are no inherited enumerable properties.
  baseForIn(value, function(subValue, key) {
    result = key;
  });
  return result === undefined || hasOwnProperty.call(value, result);
}

module.exports = isPlainObject;

},{"../internal/baseForIn":12,"../internal/isHostObject":22,"../internal/isObjectLike":26,"../support":41,"./isArguments":29}],35:[function(_dereq_,module,exports){
var isObjectLike = _dereq_('../internal/isObjectLike');

/** `Object#toString` result references. */
var stringTag = '[object String]';

/** Used for native method references. */
var objectProto = Object.prototype;

/**
 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
 * of values.
 */
var objToString = objectProto.toString;

/**
 * Checks if `value` is classified as a `String` primitive or object.
 *
 * @static
 * @memberOf _
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
 * @example
 *
 * _.isString('abc');
 * // => true
 *
 * _.isString(1);
 * // => false
 */
function isString(value) {
  return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
}

module.exports = isString;

},{"../internal/isObjectLike":26}],36:[function(_dereq_,module,exports){
var isLength = _dereq_('../internal/isLength'),
    isObjectLike = _dereq_('../internal/isObjectLike');

/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
    arrayTag = '[object Array]',
    boolTag = '[object Boolean]',
    dateTag = '[object Date]',
    errorTag = '[object Error]',
    funcTag = '[object Function]',
    mapTag = '[object Map]',
    numberTag = '[object Number]',
    objectTag = '[object Object]',
    regexpTag = '[object RegExp]',
    setTag = '[object Set]',
    stringTag = '[object String]',
    weakMapTag = '[object WeakMap]';

var arrayBufferTag = '[object ArrayBuffer]',
    float32Tag = '[object Float32Array]',
    float64Tag = '[object Float64Array]',
    int8Tag = '[object Int8Array]',
    int16Tag = '[object Int16Array]',
    int32Tag = '[object Int32Array]',
    uint8Tag = '[object Uint8Array]',
    uint8ClampedTag = '[object Uint8ClampedArray]',
    uint16Tag = '[object Uint16Array]',
    uint32Tag = '[object Uint32Array]';

/** Used to identify `toStringTag` values of typed arrays. */
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;

/** Used for native method references. */
var objectProto = Object.prototype;

/**
 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
 * of values.
 */
var objToString = objectProto.toString;

/**
 * Checks if `value` is classified as a typed array.
 *
 * @static
 * @memberOf _
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
 * @example
 *
 * _.isTypedArray(new Uint8Array);
 * // => true
 *
 * _.isTypedArray([]);
 * // => false
 */
function isTypedArray(value) {
  return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
}

module.exports = isTypedArray;

},{"../internal/isLength":25,"../internal/isObjectLike":26}],37:[function(_dereq_,module,exports){
var baseCopy = _dereq_('../internal/baseCopy'),
    keysIn = _dereq_('../object/keysIn');

/**
 * Converts `value` to a plain object flattening inherited enumerable
 * properties of `value` to own properties of the plain object.
 *
 * @static
 * @memberOf _
 * @category Lang
 * @param {*} value The value to convert.
 * @returns {Object} Returns the converted plain object.
 * @example
 *
 * function Foo() {
 *   this.b = 2;
 * }
 *
 * Foo.prototype.c = 3;
 *
 * _.assign({ 'a': 1 }, new Foo);
 * // => { 'a': 1, 'b': 2 }
 *
 * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
 * // => { 'a': 1, 'b': 2, 'c': 3 }
 */
function toPlainObject(value) {
  return baseCopy(value, keysIn(value));
}

module.exports = toPlainObject;

},{"../internal/baseCopy":10,"../object/keysIn":39}],38:[function(_dereq_,module,exports){
var getNative = _dereq_('../internal/getNative'),
    isArrayLike = _dereq_('../internal/isArrayLike'),
    isObject = _dereq_('../lang/isObject'),
    shimKeys = _dereq_('../internal/shimKeys'),
    support = _dereq_('../support');

/* Native method references for those with the same name as other `lodash` methods. */
var nativeKeys = getNative(Object, 'keys');

/**
 * Creates an array of the own enumerable property names of `object`.
 *
 * **Note:** Non-object values are coerced to objects. See the
 * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
 * for more details.
 *
 * @static
 * @memberOf _
 * @category Object
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 *   this.b = 2;
 * }
 *
 * Foo.prototype.c = 3;
 *
 * _.keys(new Foo);
 * // => ['a', 'b'] (iteration order is not guaranteed)
 *
 * _.keys('hi');
 * // => ['0', '1']
 */
var keys = !nativeKeys ? shimKeys : function(object) {
  var Ctor = object == null ? undefined : object.constructor;
  if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
      (typeof object == 'function' ? support.enumPrototypes : isArrayLike(object))) {
    return shimKeys(object);
  }
  return isObject(object) ? nativeKeys(object) : [];
};

module.exports = keys;

},{"../internal/getNative":20,"../internal/isArrayLike":21,"../internal/shimKeys":27,"../lang/isObject":33,"../support":41}],39:[function(_dereq_,module,exports){
var arrayEach = _dereq_('../internal/arrayEach'),
    isArguments = _dereq_('../lang/isArguments'),
    isArray = _dereq_('../lang/isArray'),
    isFunction = _dereq_('../lang/isFunction'),
    isIndex = _dereq_('../internal/isIndex'),
    isLength = _dereq_('../internal/isLength'),
    isObject = _dereq_('../lang/isObject'),
    isString = _dereq_('../lang/isString'),
    support = _dereq_('../support');

/** `Object#toString` result references. */
var arrayTag = '[object Array]',
    boolTag = '[object Boolean]',
    dateTag = '[object Date]',
    errorTag = '[object Error]',
    funcTag = '[object Function]',
    numberTag = '[object Number]',
    objectTag = '[object Object]',
    regexpTag = '[object RegExp]',
    stringTag = '[object String]';

/** Used to fix the JScript `[[DontEnum]]` bug. */
var shadowProps = [
  'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
  'toLocaleString', 'toString', 'valueOf'
];

/** Used for native method references. */
var errorProto = Error.prototype,
    objectProto = Object.prototype,
    stringProto = String.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
 * of values.
 */
var objToString = objectProto.toString;

/** Used to avoid iterating over non-enumerable properties in IE < 9. */
var nonEnumProps = {};
nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true };
nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true };
nonEnumProps[objectTag] = { 'constructor': true };

arrayEach(shadowProps, function(key) {
  for (var tag in nonEnumProps) {
    if (hasOwnProperty.call(nonEnumProps, tag)) {
      var props = nonEnumProps[tag];
      props[key] = hasOwnProperty.call(props, key);
    }
  }
});

/**
 * Creates an array of the own and inherited enumerable property names of `object`.
 *
 * **Note:** Non-object values are coerced to objects.
 *
 * @static
 * @memberOf _
 * @category Object
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 *   this.b = 2;
 * }
 *
 * Foo.prototype.c = 3;
 *
 * _.keysIn(new Foo);
 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
 */
function keysIn(object) {
  if (object == null) {
    return [];
  }
  if (!isObject(object)) {
    object = Object(object);
  }
  var length = object.length;

  length = (length && isLength(length) &&
    (isArray(object) || isArguments(object) || isString(object)) && length) || 0;

  var Ctor = object.constructor,
      index = -1,
      proto = (isFunction(Ctor) && Ctor.prototype) || objectProto,
      isProto = proto === object,
      result = Array(length),
      skipIndexes = length > 0,
      skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error),
      skipProto = support.enumPrototypes && isFunction(object);

  while (++index < length) {
    result[index] = (index + '');
  }
  // lodash skips the `constructor` property when it infers it's iterating
  // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]`
  // attribute of an existing property and the `constructor` property of a
  // prototype defaults to non-enumerable.
  for (var key in object) {
    if (!(skipProto && key == 'prototype') &&
        !(skipErrorProps && (key == 'message' || key == 'name')) &&
        !(skipIndexes && isIndex(key, length)) &&
        !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
      result.push(key);
    }
  }
  if (support.nonEnumShadows && object !== objectProto) {
    var tag = object === stringProto ? stringTag : (object === errorProto ? errorTag : objToString.call(object)),
        nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag];

    if (tag == objectTag) {
      proto = objectProto;
    }
    length = shadowProps.length;
    while (length--) {
      key = shadowProps[length];
      var nonEnum = nonEnums[key];
      if (!(isProto && nonEnum) &&
          (nonEnum ? hasOwnProperty.call(object, key) : object[key] !== proto[key])) {
        result.push(key);
      }
    }
  }
  return result;
}

module.exports = keysIn;

},{"../internal/arrayEach":9,"../internal/isIndex":23,"../internal/isLength":25,"../lang/isArguments":29,"../lang/isArray":30,"../lang/isFunction":31,"../lang/isObject":33,"../lang/isString":35,"../support":41}],40:[function(_dereq_,module,exports){
var baseMerge = _dereq_('../internal/baseMerge'),
    createAssigner = _dereq_('../internal/createAssigner');

/**
 * Recursively merges own enumerable properties of the source object(s), that
 * don't resolve to `undefined` into the destination object. Subsequent sources
 * overwrite property assignments of previous sources. If `customizer` is
 * provided it's invoked to produce the merged values of the destination and
 * source properties. If `customizer` returns `undefined` merging is handled
 * by the method instead. The `customizer` is bound to `thisArg` and invoked
 * with five arguments: (objectValue, sourceValue, key, object, source).
 *
 * @static
 * @memberOf _
 * @category Object
 * @param {Object} object The destination object.
 * @param {...Object} [sources] The source objects.
 * @param {Function} [customizer] The function to customize assigned values.
 * @param {*} [thisArg] The `this` binding of `customizer`.
 * @returns {Object} Returns `object`.
 * @example
 *
 * var users = {
 *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
 * };
 *
 * var ages = {
 *   'data': [{ 'age': 36 }, { 'age': 40 }]
 * };
 *
 * _.merge(users, ages);
 * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
 *
 * // using a customizer callback
 * var object = {
 *   'fruits': ['apple'],
 *   'vegetables': ['beet']
 * };
 *
 * var other = {
 *   'fruits': ['banana'],
 *   'vegetables': ['carrot']
 * };
 *
 * _.merge(object, other, function(a, b) {
 *   if (_.isArray(a)) {
 *     return a.concat(b);
 *   }
 * });
 * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
 */
var merge = createAssigner(baseMerge);

module.exports = merge;

},{"../internal/baseMerge":13,"../internal/createAssigner":17}],41:[function(_dereq_,module,exports){
/** Used for native method references. */
var arrayProto = Array.prototype,
    errorProto = Error.prototype,
    objectProto = Object.prototype;

/** Native method references. */
var propertyIsEnumerable = objectProto.propertyIsEnumerable,
    splice = arrayProto.splice;

/**
 * An object environment feature flags.
 *
 * @static
 * @memberOf _
 * @type Object
 */
var support = {};

(function(x) {
  var Ctor = function() { this.x = x; },
      object = { '0': x, 'length': x },
      props = [];

  Ctor.prototype = { 'valueOf': x, 'y': x };
  for (var key in new Ctor) { props.push(key); }

  /**
   * Detect if `name` or `message` properties of `Error.prototype` are
   * enumerable by default (IE < 9, Safari < 5.1).
   *
   * @memberOf _.support
   * @type boolean
   */
  support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') ||
    propertyIsEnumerable.call(errorProto, 'name');

  /**
   * Detect if `prototype` properties are enumerable by default.
   *
   * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
   * (if the prototype or a property on the prototype has been set)
   * incorrectly set the `[[Enumerable]]` value of a function's `prototype`
   * property to `true`.
   *
   * @memberOf _.support
   * @type boolean
   */
  support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype');

  /**
   * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
   *
   * In IE < 9 an object's own properties, shadowing non-enumerable ones,
   * are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug).
   *
   * @memberOf _.support
   * @type boolean
   */
  support.nonEnumShadows = !/valueOf/.test(props);

  /**
   * Detect if own properties are iterated after inherited properties (IE < 9).
   *
   * @memberOf _.support
   * @type boolean
   */
  support.ownLast = props[0] != 'x';

  /**
   * Detect if `Array#shift` and `Array#splice` augment array-like objects
   * correctly.
   *
   * Firefox < 10, compatibility modes of IE 8, and IE < 9 have buggy Array
   * `shift()` and `splice()` functions that fail to remove the last element,
   * `value[0]`, of array-like objects even though the "length" property is
   * set to `0`. The `shift()` method is buggy in compatibility modes of IE 8,
   * while `splice()` is buggy regardless of mode in IE < 9.
   *
   * @memberOf _.support
   * @type boolean
   */
  support.spliceObjects = (splice.call(object, 0, 1), !object[0]);

  /**
   * Detect lack of support for accessing string characters by index.
   *
   * IE < 8 can't access characters by index. IE 8 can only access characters
   * by index on string literals, not string objects.
   *
   * @memberOf _.support
   * @type boolean
   */
  support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
}(1, 0));

module.exports = support;

},{}],42:[function(_dereq_,module,exports){
/**
 * This method returns the first argument provided to it.
 *
 * @static
 * @memberOf _
 * @category Utility
 * @param {*} value Any value.
 * @returns {*} Returns `value`.
 * @example
 *
 * var object = { 'user': 'fred' };
 *
 * _.identity(object) === object;
 * // => true
 */
function identity(value) {
  return value;
}

module.exports = identity;

},{}],43:[function(_dereq_,module,exports){
'use strict';

var keys = _dereq_('object-keys');

module.exports = function hasSymbols() {
	if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }
	if (typeof Symbol.iterator === 'symbol') { return true; }

	var obj = {};
	var sym = Symbol('test');
	if (typeof sym === 'string') { return false; }

	// temp disabled per https://github.com/ljharb/object.assign/issues/17
	// if (sym instanceof Symbol) { return false; }
	// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4
	// if (!(Object(sym) instanceof Symbol)) { return false; }

	var symVal = 42;
	obj[sym] = symVal;
	for (sym in obj) { return false; }
	if (keys(obj).length !== 0) { return false; }
	if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }

	if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }

	var syms = Object.getOwnPropertySymbols(obj);
	if (syms.length !== 1 || syms[0] !== sym) { return false; }

	if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }

	if (typeof Object.getOwnPropertyDescriptor === 'function') {
		var descriptor = Object.getOwnPropertyDescriptor(obj, sym);
		if (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }
	}

	return true;
};

},{"object-keys":50}],44:[function(_dereq_,module,exports){
'use strict';

// modified from https://github.com/es-shims/es6-shim
var keys = _dereq_('object-keys');
var bind = _dereq_('function-bind');
var canBeObject = function (obj) {
	return typeof obj !== 'undefined' && obj !== null;
};
var hasSymbols = _dereq_('./hasSymbols')();
var toObject = Object;
var push = bind.call(Function.call, Array.prototype.push);
var propIsEnumerable = bind.call(Function.call, Object.prototype.propertyIsEnumerable);

module.exports = function assign(target, source1) {
	if (!canBeObject(target)) { throw new TypeError('target must be an object'); }
	var objTarget = toObject(target);
	var s, source, i, props, syms, value, key;
	for (s = 1; s < arguments.length; ++s) {
		source = toObject(arguments[s]);
		props = keys(source);
		if (hasSymbols && Object.getOwnPropertySymbols) {
			syms = Object.getOwnPropertySymbols(source);
			for (i = 0; i < syms.length; ++i) {
				key = syms[i];
				if (propIsEnumerable(source, key)) {
					push(props, key);
				}
			}
		}
		for (i = 0; i < props.length; ++i) {
			key = props[i];
			value = source[key];
			if (propIsEnumerable(source, key)) {
				objTarget[key] = value;
			}
		}
	}
	return objTarget;
};

},{"./hasSymbols":43,"function-bind":49,"object-keys":50}],45:[function(_dereq_,module,exports){
'use strict';

var defineProperties = _dereq_('define-properties');

var implementation = _dereq_('./implementation');
var getPolyfill = _dereq_('./polyfill');
var shim = _dereq_('./shim');

defineProperties(implementation, {
	implementation: implementation,
	getPolyfill: getPolyfill,
	shim: shim
});

module.exports = implementation;

},{"./implementation":44,"./polyfill":52,"./shim":53,"define-properties":46}],46:[function(_dereq_,module,exports){
'use strict';

var keys = _dereq_('object-keys');
var foreach = _dereq_('foreach');
var hasSymbols = typeof Symbol === 'function' && typeof Symbol() === 'symbol';

var toStr = Object.prototype.toString;

var isFunction = function (fn) {
	return typeof fn === 'function' && toStr.call(fn) === '[object Function]';
};

var arePropertyDescriptorsSupported = function () {
	var obj = {};
	try {
		Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
        /* eslint-disable no-unused-vars, no-restricted-syntax */
        for (var _ in obj) { return false; }
        /* eslint-enable no-unused-vars, no-restricted-syntax */
		return obj.x === obj;
	} catch (e) { /* this is IE 8. */
		return false;
	}
};
var supportsDescriptors = Object.defineProperty && arePropertyDescriptorsSupported();

var defineProperty = function (object, name, value, predicate) {
	if (name in object && (!isFunction(predicate) || !predicate())) {
		return;
	}
	if (supportsDescriptors) {
		Object.defineProperty(object, name, {
			configurable: true,
			enumerable: false,
			value: value,
			writable: true
		});
	} else {
		object[name] = value;
	}
};

var defineProperties = function (object, map) {
	var predicates = arguments.length > 2 ? arguments[2] : {};
	var props = keys(map);
	if (hasSymbols) {
		props = props.concat(Object.getOwnPropertySymbols(map));
	}
	foreach(props, function (name) {
		defineProperty(object, name, map[name], predicates[name]);
	});
};

defineProperties.supportsDescriptors = !!supportsDescriptors;

module.exports = defineProperties;

},{"foreach":47,"object-keys":50}],47:[function(_dereq_,module,exports){

var hasOwn = Object.prototype.hasOwnProperty;
var toString = Object.prototype.toString;

module.exports = function forEach (obj, fn, ctx) {
    if (toString.call(fn) !== '[object Function]') {
        throw new TypeError('iterator must be a function');
    }
    var l = obj.length;
    if (l === +l) {
        for (var i = 0; i < l; i++) {
            fn.call(ctx, obj[i], i, obj);
        }
    } else {
        for (var k in obj) {
            if (hasOwn.call(obj, k)) {
                fn.call(ctx, obj[k], k, obj);
            }
        }
    }
};


},{}],48:[function(_dereq_,module,exports){
var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
var slice = Array.prototype.slice;
var toStr = Object.prototype.toString;
var funcType = '[object Function]';

module.exports = function bind(that) {
    var target = this;
    if (typeof target !== 'function' || toStr.call(target) !== funcType) {
        throw new TypeError(ERROR_MESSAGE + target);
    }
    var args = slice.call(arguments, 1);

    var bound;
    var binder = function () {
        if (this instanceof bound) {
            var result = target.apply(
                this,
                args.concat(slice.call(arguments))
            );
            if (Object(result) === result) {
                return result;
            }
            return this;
        } else {
            return target.apply(
                that,
                args.concat(slice.call(arguments))
            );
        }
    };

    var boundLength = Math.max(0, target.length - args.length);
    var boundArgs = [];
    for (var i = 0; i < boundLength; i++) {
        boundArgs.push('$' + i);
    }

    bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);

    if (target.prototype) {
        var Empty = function Empty() {};
        Empty.prototype = target.prototype;
        bound.prototype = new Empty();
        Empty.prototype = null;
    }

    return bound;
};

},{}],49:[function(_dereq_,module,exports){
var implementation = _dereq_('./implementation');

module.exports = Function.prototype.bind || implementation;

},{"./implementation":48}],50:[function(_dereq_,module,exports){
'use strict';

// modified from https://github.com/es-shims/es5-shim
var has = Object.prototype.hasOwnProperty;
var toStr = Object.prototype.toString;
var slice = Array.prototype.slice;
var isArgs = _dereq_('./isArguments');
var hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString');
var hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype');
var dontEnums = [
	'toString',
	'toLocaleString',
	'valueOf',
	'hasOwnProperty',
	'isPrototypeOf',
	'propertyIsEnumerable',
	'constructor'
];
var equalsConstructorPrototype = function (o) {
	var ctor = o.constructor;
	return ctor && ctor.prototype === o;
};
var blacklistedKeys = {
	$console: true,
	$frame: true,
	$frameElement: true,
	$frames: true,
	$parent: true,
	$self: true,
	$webkitIndexedDB: true,
	$webkitStorageInfo: true,
	$window: true
};
var hasAutomationEqualityBug = (function () {
	/* global window */
	if (typeof window === 'undefined') { return false; }
	for (var k in window) {
		try {
			if (!blacklistedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
				try {
					equalsConstructorPrototype(window[k]);
				} catch (e) {
					return true;
				}
			}
		} catch (e) {
			return true;
		}
	}
	return false;
}());
var equalsConstructorPrototypeIfNotBuggy = function (o) {
	/* global window */
	if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
		return equalsConstructorPrototype(o);
	}
	try {
		return equalsConstructorPrototype(o);
	} catch (e) {
		return false;
	}
};

var keysShim = function keys(object) {
	var isObject = object !== null && typeof object === 'object';
	var isFunction = toStr.call(object) === '[object Function]';
	var isArguments = isArgs(object);
	var isString = isObject && toStr.call(object) === '[object String]';
	var theKeys = [];

	if (!isObject && !isFunction && !isArguments) {
		throw new TypeError('Object.keys called on a non-object');
	}

	var skipProto = hasProtoEnumBug && isFunction;
	if (isString && object.length > 0 && !has.call(object, 0)) {
		for (var i = 0; i < object.length; ++i) {
			theKeys.push(String(i));
		}
	}

	if (isArguments && object.length > 0) {
		for (var j = 0; j < object.length; ++j) {
			theKeys.push(String(j));
		}
	} else {
		for (var name in object) {
			if (!(skipProto && name === 'prototype') && has.call(object, name)) {
				theKeys.push(String(name));
			}
		}
	}

	if (hasDontEnumBug) {
		var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);

		for (var k = 0; k < dontEnums.length; ++k) {
			if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
				theKeys.push(dontEnums[k]);
			}
		}
	}
	return theKeys;
};

keysShim.shim = function shimObjectKeys() {
	if (Object.keys) {
		var keysWorksWithArguments = (function () {
			// Safari 5.0 bug
			return (Object.keys(arguments) || '').length === 2;
		}(1, 2));
		if (!keysWorksWithArguments) {
			var originalKeys = Object.keys;
			Object.keys = function keys(object) {
				if (isArgs(object)) {
					return originalKeys(slice.call(object));
				} else {
					return originalKeys(object);
				}
			};
		}
	} else {
		Object.keys = keysShim;
	}
	return Object.keys || keysShim;
};

module.exports = keysShim;

},{"./isArguments":51}],51:[function(_dereq_,module,exports){
'use strict';

var toStr = Object.prototype.toString;

module.exports = function isArguments(value) {
	var str = toStr.call(value);
	var isArgs = str === '[object Arguments]';
	if (!isArgs) {
		isArgs = str !== '[object Array]' &&
			value !== null &&
			typeof value === 'object' &&
			typeof value.length === 'number' &&
			value.length >= 0 &&
			toStr.call(value.callee) === '[object Function]';
	}
	return isArgs;
};

},{}],52:[function(_dereq_,module,exports){
'use strict';

var implementation = _dereq_('./implementation');

var lacksProperEnumerationOrder = function () {
	if (!Object.assign) {
		return false;
	}
	// v8, specifically in node 4.x, has a bug with incorrect property enumeration order
	// note: this does not detect the bug unless there's 20 characters
	var str = 'abcdefghijklmnopqrst';
	var letters = str.split('');
	var map = {};
	for (var i = 0; i < letters.length; ++i) {
		map[letters[i]] = letters[i];
	}
	var obj = Object.assign({}, map);
	var actual = '';
	for (var k in obj) {
		actual += k;
	}
	return str !== actual;
};

var assignHasPendingExceptions = function () {
	if (!Object.assign || !Object.preventExtensions) {
		return false;
	}
	// Firefox 37 still has "pending exception" logic in its Object.assign implementation,
	// which is 72% slower than our shim, and Firefox 40's native implementation.
	var thrower = Object.preventExtensions({ 1: 2 });
	try {
		Object.assign(thrower, 'xy');
	} catch (e) {
		return thrower[1] === 'y';
	}
};

module.exports = function getPolyfill() {
	if (!Object.assign) {
		return implementation;
	}
	if (lacksProperEnumerationOrder()) {
		return implementation;
	}
	if (assignHasPendingExceptions()) {
		return implementation;
	}
	return Object.assign;
};

},{"./implementation":44}],53:[function(_dereq_,module,exports){
'use strict';

var define = _dereq_('define-properties');
var getPolyfill = _dereq_('./polyfill');

module.exports = function shimAssign() {
	var polyfill = getPolyfill();
	define(
		Object,
		{ assign: polyfill },
		{ assign: function () { return Object.assign !== polyfill; } }
	);
	return polyfill;
};

},{"./polyfill":52,"define-properties":46}],54:[function(_dereq_,module,exports){
module.exports = SafeParseTuple

function SafeParseTuple(obj, reviver) {
    var json
    var error = null

    try {
        json = JSON.parse(obj, reviver)
    } catch (err) {
        error = err
    }

    return [error, json]
}

},{}],55:[function(_dereq_,module,exports){
function clean (s) {
  return s.replace(/\n\r?\s*/g, '')
}


module.exports = function tsml (sa) {
  var s = ''
    , i = 0

  for (; i < arguments.length; i++)
    s += clean(sa[i]) + (arguments[i + 1] || '')

  return s
}
},{}],56:[function(_dereq_,module,exports){
"use strict";
var window = _dereq_("global/window")
var once = _dereq_("once")
var isFunction = _dereq_("is-function")
var parseHeaders = _dereq_("parse-headers")
var xtend = _dereq_("xtend")

module.exports = createXHR
createXHR.XMLHttpRequest = window.XMLHttpRequest || noop
createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest

forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) {
    createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) {
        options = initParams(uri, options, callback)
        options.method = method.toUpperCase()
        return _createXHR(options)
    }
})

function forEachArray(array, iterator) {
    for (var i = 0; i < array.length; i++) {
        iterator(array[i])
    }
}

function isEmpty(obj){
    for(var i in obj){
        if(obj.hasOwnProperty(i)) return false
    }
    return true
}

function initParams(uri, options, callback) {
    var params = uri

    if (isFunction(options)) {
        callback = options
        if (typeof uri === "string") {
            params = {uri:uri}
        }
    } else {
        params = xtend(options, {uri: uri})
    }

    params.callback = callback
    return params
}

function createXHR(uri, options, callback) {
    options = initParams(uri, options, callback)
    return _createXHR(options)
}

function _createXHR(options) {
    var callback = options.callback
    if(typeof callback === "undefined"){
        throw new Error("callback argument missing")
    }
    callback = once(callback)

    function readystatechange() {
        if (xhr.readyState === 4) {
            loadFunc()
        }
    }

    function getBody() {
        // Chrome with requestType=blob throws errors arround when even testing access to responseText
        var body = undefined

        if (xhr.response) {
            body = xhr.response
        } else if (xhr.responseType === "text" || !xhr.responseType) {
            body = xhr.responseText || xhr.responseXML
        }

        if (isJson) {
            try {
                body = JSON.parse(body)
            } catch (e) {}
        }

        return body
    }

    var failureResponse = {
                body: undefined,
                headers: {},
                statusCode: 0,
                method: method,
                url: uri,
                rawRequest: xhr
            }

    function errorFunc(evt) {
        clearTimeout(timeoutTimer)
        if(!(evt instanceof Error)){
            evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") )
        }
        evt.statusCode = 0
        callback(evt, failureResponse)
    }

    // will load the data & process the response in a special response object
    function loadFunc() {
        if (aborted) return
        var status
        clearTimeout(timeoutTimer)
        if(options.useXDR && xhr.status===undefined) {
            //IE8 CORS GET successful response doesn't have a status field, but body is fine
            status = 200
        } else {
            status = (xhr.status === 1223 ? 204 : xhr.status)
        }
        var response = failureResponse
        var err = null

        if (status !== 0){
            response = {
                body: getBody(),
                statusCode: status,
                method: method,
                headers: {},
                url: uri,
                rawRequest: xhr
            }
            if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
                response.headers = parseHeaders(xhr.getAllResponseHeaders())
            }
        } else {
            err = new Error("Internal XMLHttpRequest Error")
        }
        callback(err, response, response.body)

    }

    var xhr = options.xhr || null

    if (!xhr) {
        if (options.cors || options.useXDR) {
            xhr = new createXHR.XDomainRequest()
        }else{
            xhr = new createXHR.XMLHttpRequest()
        }
    }

    var key
    var aborted
    var uri = xhr.url = options.uri || options.url
    var method = xhr.method = options.method || "GET"
    var body = options.body || options.data || null
    var headers = xhr.headers = options.headers || {}
    var sync = !!options.sync
    var isJson = false
    var timeoutTimer

    if ("json" in options) {
        isJson = true
        headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user
        if (method !== "GET" && method !== "HEAD") {
            headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user
            body = JSON.stringify(options.json)
        }
    }

    xhr.onreadystatechange = readystatechange
    xhr.onload = loadFunc
    xhr.onerror = errorFunc
    // IE9 must have onprogress be set to a unique function.
    xhr.onprogress = function () {
        // IE must die
    }
    xhr.ontimeout = errorFunc
    xhr.open(method, uri, !sync, options.username, options.password)
    //has to be after open
    if(!sync) {
        xhr.withCredentials = !!options.withCredentials
    }
    // Cannot set timeout with sync request
    // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly
    // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent
    if (!sync && options.timeout > 0 ) {
        timeoutTimer = setTimeout(function(){
            aborted=true//IE9 may still call readystatechange
            xhr.abort("timeout")
            var e = new Error("XMLHttpRequest timeout")
            e.code = "ETIMEDOUT"
            errorFunc(e)
        }, options.timeout )
    }

    if (xhr.setRequestHeader) {
        for(key in headers){
            if(headers.hasOwnProperty(key)){
                xhr.setRequestHeader(key, headers[key])
            }
        }
    } else if (options.headers && !isEmpty(options.headers)) {
        throw new Error("Headers cannot be set on an XDomainRequest object")
    }

    if ("responseType" in options) {
        xhr.responseType = options.responseType
    }

    if ("beforeSend" in options &&
        typeof options.beforeSend === "function"
    ) {
        options.beforeSend(xhr)
    }

    xhr.send(body)

    return xhr


}

function noop() {}

},{"global/window":2,"is-function":57,"once":58,"parse-headers":61,"xtend":62}],57:[function(_dereq_,module,exports){
module.exports = isFunction

var toString = Object.prototype.toString

function isFunction (fn) {
  var string = toString.call(fn)
  return string === '[object Function]' ||
    (typeof fn === 'function' && string !== '[object RegExp]') ||
    (typeof window !== 'undefined' &&
     // IE8 and below
     (fn === window.setTimeout ||
      fn === window.alert ||
      fn === window.confirm ||
      fn === window.prompt))
};

},{}],58:[function(_dereq_,module,exports){
module.exports = once

once.proto = once(function () {
  Object.defineProperty(Function.prototype, 'once', {
    value: function () {
      return once(this)
    },
    configurable: true
  })
})

function once (fn) {
  var called = false
  return function () {
    if (called) return
    called = true
    return fn.apply(this, arguments)
  }
}

},{}],59:[function(_dereq_,module,exports){
var isFunction = _dereq_('is-function')

module.exports = forEach

var toString = Object.prototype.toString
var hasOwnProperty = Object.prototype.hasOwnProperty

function forEach(list, iterator, context) {
    if (!isFunction(iterator)) {
        throw new TypeError('iterator must be a function')
    }

    if (arguments.length < 3) {
        context = this
    }
    
    if (toString.call(list) === '[object Array]')
        forEachArray(list, iterator, context)
    else if (typeof list === 'string')
        forEachString(list, iterator, context)
    else
        forEachObject(list, iterator, context)
}

function forEachArray(array, iterator, context) {
    for (var i = 0, len = array.length; i < len; i++) {
        if (hasOwnProperty.call(array, i)) {
            iterator.call(context, array[i], i, array)
        }
    }
}

function forEachString(string, iterator, context) {
    for (var i = 0, len = string.length; i < len; i++) {
        // no such thing as a sparse string.
        iterator.call(context, string.charAt(i), i, string)
    }
}

function forEachObject(object, iterator, context) {
    for (var k in object) {
        if (hasOwnProperty.call(object, k)) {
            iterator.call(context, object[k], k, object)
        }
    }
}

},{"is-function":57}],60:[function(_dereq_,module,exports){

exports = module.exports = trim;

function trim(str){
  return str.replace(/^\s*|\s*$/g, '');
}

exports.left = function(str){
  return str.replace(/^\s*/, '');
};

exports.right = function(str){
  return str.replace(/\s*$/, '');
};

},{}],61:[function(_dereq_,module,exports){
var trim = _dereq_('trim')
  , forEach = _dereq_('for-each')
  , isArray = function(arg) {
      return Object.prototype.toString.call(arg) === '[object Array]';
    }

module.exports = function (headers) {
  if (!headers)
    return {}

  var result = {}

  forEach(
      trim(headers).split('\n')
    , function (row) {
        var index = row.indexOf(':')
          , key = trim(row.slice(0, index)).toLowerCase()
          , value = trim(row.slice(index + 1))

        if (typeof(result[key]) === 'undefined') {
          result[key] = value
        } else if (isArray(result[key])) {
          result[key].push(value)
        } else {
          result[key] = [ result[key], value ]
        }
      }
  )

  return result
}
},{"for-each":59,"trim":60}],62:[function(_dereq_,module,exports){
module.exports = extend

var hasOwnProperty = Object.prototype.hasOwnProperty;

function extend() {
    var target = {}

    for (var i = 0; i < arguments.length; i++) {
        var source = arguments[i]

        for (var key in source) {
            if (hasOwnProperty.call(source, key)) {
                target[key] = source[key]
            }
        }
    }

    return target
}

},{}],63:[function(_dereq_,module,exports){
/**
 * @file big-play-button.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _buttonJs = _dereq_('./button.js');

var _buttonJs2 = _interopRequireDefault(_buttonJs);

var _componentJs = _dereq_('./component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

/**
 * Initial play button. Shows before the video has played. The hiding of the
 * big play button is done via CSS and player states.
 *
 * @param {Object} player  Main Player
 * @param {Object=} options Object of option names and values
 * @extends Button
 * @class BigPlayButton
 */

var BigPlayButton = (function (_Button) {
  _inherits(BigPlayButton, _Button);

  function BigPlayButton(player, options) {
    _classCallCheck(this, BigPlayButton);

    _Button.call(this, player, options);
  }

  /**
   * Allow sub components to stack CSS class names
   *
   * @return {String} The constructed class name
   * @method buildCSSClass
   */

  BigPlayButton.prototype.buildCSSClass = function buildCSSClass() {
    return 'vjs-big-play-button';
  };

  /**
   * Handles click for play
   *
   * @method handleClick
   */

  BigPlayButton.prototype.handleClick = function handleClick() {
    this.player_.play();
  };

  return BigPlayButton;
})(_buttonJs2['default']);

BigPlayButton.prototype.controlText_ = 'Play Video';

_componentJs2['default'].registerComponent('BigPlayButton', BigPlayButton);
exports['default'] = BigPlayButton;
module.exports = exports['default'];

},{"./button.js":64,"./component.js":67}],64:[function(_dereq_,module,exports){
/**
 * @file button.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _clickableComponentJs = _dereq_('./clickable-component.js');

var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);

var _component = _dereq_('./component');

var _component2 = _interopRequireDefault(_component);

var _utilsEventsJs = _dereq_('./utils/events.js');

var Events = _interopRequireWildcard(_utilsEventsJs);

var _utilsFnJs = _dereq_('./utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsLogJs = _dereq_('./utils/log.js');

var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var _objectAssign = _dereq_('object.assign');

var _objectAssign2 = _interopRequireDefault(_objectAssign);

/**
 * Base class for all buttons
 *
 * @param {Object} player  Main Player
 * @param {Object=} options Object of option names and values
 * @extends ClickableComponent
 * @class Button
 */

var Button = (function (_ClickableComponent) {
  _inherits(Button, _ClickableComponent);

  function Button(player, options) {
    _classCallCheck(this, Button);

    _ClickableComponent.call(this, player, options);
  }

  /**
   * Create the component's DOM element
   *
   * @param {String=} type Element's node type. e.g. 'div'
   * @param {Object=} props An object of properties that should be set on the element
   * @param {Object=} attributes An object of attributes that should be set on the element
   * @return {Element}
   * @method createEl
   */

  Button.prototype.createEl = function createEl() {
    var tag = arguments.length <= 0 || arguments[0] === undefined ? 'button' : arguments[0];
    var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
    var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];

    props = _objectAssign2['default']({
      className: this.buildCSSClass()
    }, props);

    if (tag !== 'button') {
      _utilsLogJs2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.');
    }

    // Add attributes for button element
    attributes = _objectAssign2['default']({
      type: 'button', // Necessary since the default button type is "submit"
      'aria-live': 'polite' // let the screen reader user know that the text of the button may change
    }, attributes);

    var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes);

    this.createControlTextEl(el);

    return el;
  };

  /**
   * Adds a child component inside this button
   *
   * @param {String|Component} child The class name or instance of a child to add
   * @param {Object=} options Options, including options to be passed to children of the child.
   * @return {Component} The child component (created by this process if a string was used)
   * @deprecated
   * @method addChild
   */

  Button.prototype.addChild = function addChild(child) {
    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

    var className = this.constructor.name;
    _utilsLogJs2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.');

    // Avoid the error message generated by ClickableComponent's addChild method
    return _component2['default'].prototype.addChild.call(this, child, options);
  };

  /**
   * Handle KeyPress (document level) - Extend with specific functionality for button
   *
   * @method handleKeyPress
   */

  Button.prototype.handleKeyPress = function handleKeyPress(event) {
    // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button.
    if (event.which === 32 || event.which === 13) {} else {
      _ClickableComponent.prototype.handleKeyPress.call(this, event); // Pass keypress handling up for unsupported keys
    }
  };

  return Button;
})(_clickableComponentJs2['default']);

_component2['default'].registerComponent('Button', Button);
exports['default'] = Button;
module.exports = exports['default'];

},{"./clickable-component.js":65,"./component":67,"./utils/events.js":133,"./utils/fn.js":134,"./utils/log.js":137,"global/document":1,"object.assign":45}],65:[function(_dereq_,module,exports){
/**
 * @file button.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _component = _dereq_('./component');

var _component2 = _interopRequireDefault(_component);

var _utilsDomJs = _dereq_('./utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsEventsJs = _dereq_('./utils/events.js');

var Events = _interopRequireWildcard(_utilsEventsJs);

var _utilsFnJs = _dereq_('./utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsLogJs = _dereq_('./utils/log.js');

var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var _objectAssign = _dereq_('object.assign');

var _objectAssign2 = _interopRequireDefault(_objectAssign);

/**
 * Clickable Component which is clickable or keyboard actionable, but is not a native HTML button
 *
 * @param {Object} player  Main Player
 * @param {Object=} options Object of option names and values
 * @extends Component
 * @class ClickableComponent
 */

var ClickableComponent = (function (_Component) {
  _inherits(ClickableComponent, _Component);

  function ClickableComponent(player, options) {
    _classCallCheck(this, ClickableComponent);

    _Component.call(this, player, options);

    this.emitTapEvents();

    this.on('tap', this.handleClick);
    this.on('click', this.handleClick);
    this.on('focus', this.handleFocus);
    this.on('blur', this.handleBlur);
  }

  /**
   * Create the component's DOM element
   *
   * @param {String=} type Element's node type. e.g. 'div'
   * @param {Object=} props An object of properties that should be set on the element
   * @param {Object=} attributes An object of attributes that should be set on the element
   * @return {Element}
   * @method createEl
   */

  ClickableComponent.prototype.createEl = function createEl() {
    var tag = arguments.length <= 0 || arguments[0] === undefined ? 'div' : arguments[0];
    var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
    var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];

    props = _objectAssign2['default']({
      className: this.buildCSSClass(),
      tabIndex: 0
    }, props);

    if (tag === 'button') {
      _utilsLogJs2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.');
    }

    // Add ARIA attributes for clickable element which is not a native HTML button
    attributes = _objectAssign2['default']({
      role: 'button',
      'aria-live': 'polite' // let the screen reader user know that the text of the element may change
    }, attributes);

    var el = _Component.prototype.createEl.call(this, tag, props, attributes);

    this.createControlTextEl(el);

    return el;
  };

  /**
   * create control text
   *
   * @param {Element} el Parent element for the control text
   * @return {Element}
   * @method controlText
   */

  ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) {
    this.controlTextEl_ = Dom.createEl('span', {
      className: 'vjs-control-text'
    });

    if (el) {
      el.appendChild(this.controlTextEl_);
    }

    this.controlText(this.controlText_);

    return this.controlTextEl_;
  };

  /**
   * Controls text - both request and localize
   *
   * @param {String} text Text for element
   * @return {String}
   * @method controlText
   */

  ClickableComponent.prototype.controlText = function controlText(text) {
    if (!text) return this.controlText_ || 'Need Text';

    this.controlText_ = text;
    this.controlTextEl_.innerHTML = this.localize(this.controlText_);

    return this;
  };

  /**
   * Allows sub components to stack CSS class names
   *
   * @return {String}
   * @method buildCSSClass
   */

  ClickableComponent.prototype.buildCSSClass = function buildCSSClass() {
    return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this);
  };

  /**
   * Adds a child component inside this clickable-component
   *
   * @param {String|Component} child The class name or instance of a child to add
   * @param {Object=} options Options, including options to be passed to children of the child.
   * @return {Component} The child component (created by this process if a string was used)
   * @method addChild
   */

  ClickableComponent.prototype.addChild = function addChild(child) {
    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

    // TODO: Fix adding an actionable child to a ClickableComponent; currently
    // it will cause issues with assistive technology (e.g. screen readers)
    // which support ARIA, since an element with role="button" cannot have
    // actionable child elements.

    //let className = this.constructor.name;
    //log.warn(`Adding a child to a ClickableComponent (${className}) can cause issues with assistive technology which supports ARIA, since an element with role="button" cannot have actionable child elements.`);

    return _Component.prototype.addChild.call(this, child, options);
  };

  /**
   * Handle Click - Override with specific functionality for component
   *
   * @method handleClick
   */

  ClickableComponent.prototype.handleClick = function handleClick() {};

  /**
   * Handle Focus - Add keyboard functionality to element
   *
   * @method handleFocus
   */

  ClickableComponent.prototype.handleFocus = function handleFocus() {
    Events.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
  };

  /**
   * Handle KeyPress (document level) - Trigger click when Space or Enter key is pressed
   *
   * @method handleKeyPress
   */

  ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) {
    // Support Space (32) or Enter (13) key operation to fire a click event
    if (event.which === 32 || event.which === 13) {
      event.preventDefault();
      this.handleClick(event);
    } else if (_Component.prototype.handleKeyPress) {
      _Component.prototype.handleKeyPress.call(this, event); // Pass keypress handling up for unsupported keys
    }
  };

  /**
   * Handle Blur - Remove keyboard triggers
   *
   * @method handleBlur
   */

  ClickableComponent.prototype.handleBlur = function handleBlur() {
    Events.off(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
  };

  return ClickableComponent;
})(_component2['default']);

_component2['default'].registerComponent('ClickableComponent', ClickableComponent);
exports['default'] = ClickableComponent;
module.exports = exports['default'];

},{"./component":67,"./utils/dom.js":132,"./utils/events.js":133,"./utils/fn.js":134,"./utils/log.js":137,"global/document":1,"object.assign":45}],66:[function(_dereq_,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _button = _dereq_('./button');

var _button2 = _interopRequireDefault(_button);

var _component = _dereq_('./component');

var _component2 = _interopRequireDefault(_component);

/**
 * The `CloseButton` component is a button which fires a "close" event
 * when it is activated.
 *
 * @extends Button
 * @class CloseButton
 */

var CloseButton = (function (_Button) {
  _inherits(CloseButton, _Button);

  function CloseButton(player, options) {
    _classCallCheck(this, CloseButton);

    _Button.call(this, player, options);
    this.controlText(options && options.controlText || this.localize('Close'));
  }

  CloseButton.prototype.buildCSSClass = function buildCSSClass() {
    return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this);
  };

  CloseButton.prototype.handleClick = function handleClick() {
    this.trigger({ type: 'close', bubbles: false });
  };

  return CloseButton;
})(_button2['default']);

_component2['default'].registerComponent('CloseButton', CloseButton);
exports['default'] = CloseButton;
module.exports = exports['default'];

},{"./button":64,"./component":67}],67:[function(_dereq_,module,exports){
/**
 * @file component.js
 *
 * Player Component - Base class for all UI objects
 */

'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

var _utilsDomJs = _dereq_('./utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsFnJs = _dereq_('./utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsGuidJs = _dereq_('./utils/guid.js');

var Guid = _interopRequireWildcard(_utilsGuidJs);

var _utilsEventsJs = _dereq_('./utils/events.js');

var Events = _interopRequireWildcard(_utilsEventsJs);

var _utilsLogJs = _dereq_('./utils/log.js');

var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);

var _utilsToTitleCaseJs = _dereq_('./utils/to-title-case.js');

var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);

var _objectAssign = _dereq_('object.assign');

var _objectAssign2 = _interopRequireDefault(_objectAssign);

var _utilsMergeOptionsJs = _dereq_('./utils/merge-options.js');

var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);

/**
 * Base UI Component class
 * Components are embeddable UI objects that are represented by both a
 * javascript object and an element in the DOM. They can be children of other
 * components, and can have many children themselves.
 * ```js
 *     // adding a button to the player
 *     var button = player.addChild('button');
 *     button.el(); // -> button element
 * ```
 * ```html
 *     <div class="video-js">
 *       <div class="vjs-button">Button</div>
 *     </div>
 * ```
 * Components are also event targets.
 * ```js
 *     button.on('click', function(){
 *       console.log('Button Clicked!');
 *     });
 *     button.trigger('customevent');
 * ```
 *
 * @param {Object} player  Main Player
 * @param {Object=} options Object of option names and values
 * @param {Function=} ready    Ready callback function
 * @class Component
 */

var Component = (function () {
  function Component(player, options, ready) {
    _classCallCheck(this, Component);

    // The component might be the player itself and we can't pass `this` to super
    if (!player && this.play) {
      this.player_ = player = this; // eslint-disable-line
    } else {
        this.player_ = player;
      }

    // Make a copy of prototype.options_ to protect against overriding defaults
    this.options_ = _utilsMergeOptionsJs2['default']({}, this.options_);

    // Updated options with supplied options
    options = this.options_ = _utilsMergeOptionsJs2['default'](this.options_, options);

    // Get ID from options or options element if one is supplied
    this.id_ = options.id || options.el && options.el.id;

    // If there was no ID from the options, generate one
    if (!this.id_) {
      // Don't require the player ID function in the case of mock players
      var id = player && player.id && player.id() || 'no_player';

      this.id_ = id + '_component_' + Guid.newGUID();
    }

    this.name_ = options.name || null;

    // Create element if one wasn't provided in options
    if (options.el) {
      this.el_ = options.el;
    } else if (options.createEl !== false) {
      this.el_ = this.createEl();
    }

    this.children_ = [];
    this.childIndex_ = {};
    this.childNameIndex_ = {};

    // Add any child components in options
    if (options.initChildren !== false) {
      this.initChildren();
    }

    this.ready(ready);
    // Don't want to trigger ready here or it will before init is actually
    // finished for all children that run this constructor

    if (options.reportTouchActivity !== false) {
      this.enableTouchActivity();
    }
  }

  /**
   * Dispose of the component and all child components
   *
   * @method dispose
   */

  Component.prototype.dispose = function dispose() {
    this.trigger({ type: 'dispose', bubbles: false });

    // Dispose all children.
    if (this.children_) {
      for (var i = this.children_.length - 1; i >= 0; i--) {
        if (this.children_[i].dispose) {
          this.children_[i].dispose();
        }
      }
    }

    // Delete child references
    this.children_ = null;
    this.childIndex_ = null;
    this.childNameIndex_ = null;

    // Remove all event listeners.
    this.off();

    // Remove element from DOM
    if (this.el_.parentNode) {
      this.el_.parentNode.removeChild(this.el_);
    }

    Dom.removeElData(this.el_);
    this.el_ = null;
  };

  /**
   * Return the component's player
   *
   * @return {Player}
   * @method player
   */

  Component.prototype.player = function player() {
    return this.player_;
  };

  /**
   * Deep merge of options objects
   * Whenever a property is an object on both options objects
   * the two properties will be merged using mergeOptions.
   *
   * ```js
   *     Parent.prototype.options_ = {
   *       optionSet: {
   *         'childOne': { 'foo': 'bar', 'asdf': 'fdsa' },
   *         'childTwo': {},
   *         'childThree': {}
   *       }
   *     }
   *     newOptions = {
   *       optionSet: {
   *         'childOne': { 'foo': 'baz', 'abc': '123' }
   *         'childTwo': null,
   *         'childFour': {}
   *       }
   *     }
   *
   *     this.options(newOptions);
   * ```
   * RESULT
   * ```js
   *     {
   *       optionSet: {
   *         'childOne': { 'foo': 'baz', 'asdf': 'fdsa', 'abc': '123' },
   *         'childTwo': null, // Disabled. Won't be initialized.
   *         'childThree': {},
   *         'childFour': {}
   *       }
   *     }
   * ```
   *
   * @param  {Object} obj Object of new option values
   * @return {Object}     A NEW object of this.options_ and obj merged
   * @method options
   */

  Component.prototype.options = function options(obj) {
    _utilsLogJs2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0');

    if (!obj) {
      return this.options_;
    }

    this.options_ = _utilsMergeOptionsJs2['default'](this.options_, obj);
    return this.options_;
  };

  /**
   * Get the component's DOM element
   * ```js
   *     var domEl = myComponent.el();
   * ```
   *
   * @return {Element}
   * @method el
   */

  Component.prototype.el = function el() {
    return this.el_;
  };

  /**
   * Create the component's DOM element
   *
   * @param  {String=} tagName  Element's node type. e.g. 'div'
   * @param  {Object=} properties An object of properties that should be set
   * @param  {Object=} attributes An object of attributes that should be set
   * @return {Element}
   * @method createEl
   */

  Component.prototype.createEl = function createEl(tagName, properties, attributes) {
    return Dom.createEl(tagName, properties, attributes);
  };

  Component.prototype.localize = function localize(string) {
    var code = this.player_.language && this.player_.language();
    var languages = this.player_.languages && this.player_.languages();

    if (!code || !languages) {
      return string;
    }

    var language = languages[code];

    if (language && language[string]) {
      return language[string];
    }

    var primaryCode = code.split('-')[0];
    var primaryLang = languages[primaryCode];

    if (primaryLang && primaryLang[string]) {
      return primaryLang[string];
    }

    return string;
  };

  /**
   * Return the component's DOM element where children are inserted.
   * Will either be the same as el() or a new element defined in createEl().
   *
   * @return {Element}
   * @method contentEl
   */

  Component.prototype.contentEl = function contentEl() {
    return this.contentEl_ || this.el_;
  };

  /**
   * Get the component's ID
   * ```js
   *     var id = myComponent.id();
   * ```
   *
   * @return {String}
   * @method id
   */

  Component.prototype.id = function id() {
    return this.id_;
  };

  /**
   * Get the component's name. The name is often used to reference the component.
   * ```js
   *     var name = myComponent.name();
   * ```
   *
   * @return {String}
   * @method name
   */

  Component.prototype.name = function name() {
    return this.name_;
  };

  /**
   * Get an array of all child components
   * ```js
   *     var kids = myComponent.children();
   * ```
   *
   * @return {Array} The children
   * @method children
   */

  Component.prototype.children = function children() {
    return this.children_;
  };

  /**
   * Returns a child component with the provided ID
   *
   * @return {Component}
   * @method getChildById
   */

  Component.prototype.getChildById = function getChildById(id) {
    return this.childIndex_[id];
  };

  /**
   * Returns a child component with the provided name
   *
   * @return {Component}
   * @method getChild
   */

  Component.prototype.getChild = function getChild(name) {
    return this.childNameIndex_[name];
  };

  /**
   * Adds a child component inside this component
   * ```js
   *     myComponent.el();
   *     // -> <div class='my-component'></div>
   *     myComponent.children();
   *     // [empty array]
   *
   *     var myButton = myComponent.addChild('MyButton');
   *     // -> <div class='my-component'><div class="my-button">myButton<div></div>
   *     // -> myButton === myComponent.children()[0];
   * ```
   * Pass in options for child constructors and options for children of the child
   * ```js
   *     var myButton = myComponent.addChild('MyButton', {
   *       text: 'Press Me',
   *       buttonChildExample: {
   *         buttonChildOption: true
   *       }
   *     });
   * ```
   *
   * @param {String|Component} child The class name or instance of a child to add
   * @param {Object=} options Options, including options to be passed to children of the child.
   * @param {Number} index into our children array to attempt to add the child
   * @return {Component} The child component (created by this process if a string was used)
   * @method addChild
   */

  Component.prototype.addChild = function addChild(child) {
    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
    var index = arguments.length <= 2 || arguments[2] === undefined ? this.children_.length : arguments[2];

    var component = undefined;
    var componentName = undefined;

    // If child is a string, create nt with options
    if (typeof child === 'string') {
      componentName = child;

      // Options can also be specified as a boolean, so convert to an empty object if false.
      if (!options) {
        options = {};
      }

      // Same as above, but true is deprecated so show a warning.
      if (options === true) {
        _utilsLogJs2['default'].warn('Initializing a child component with `true` is deprecated. Children should be defined in an array when possible, but if necessary use an object instead of `true`.');
        options = {};
      }

      // If no componentClass in options, assume componentClass is the name lowercased
      // (e.g. playButton)
      var componentClassName = options.componentClass || _utilsToTitleCaseJs2['default'](componentName);

      // Set name through options
      options.name = componentName;

      // Create a new object & element for this controls set
      // If there's no .player_, this is a player
      var ComponentClass = Component.getComponent(componentClassName);

      if (!ComponentClass) {
        throw new Error('Component ' + componentClassName + ' does not exist');
      }

      // data stored directly on the videojs object may be
      // misidentified as a component to retain
      // backwards-compatibility with 4.x. check to make sure the
      // component class can be instantiated.
      if (typeof ComponentClass !== 'function') {
        return null;
      }

      component = new ComponentClass(this.player_ || this, options);

      // child is a component instance
    } else {
        component = child;
      }

    this.children_.splice(index, 0, component);

    if (typeof component.id === 'function') {
      this.childIndex_[component.id()] = component;
    }

    // If a name wasn't used to create the component, check if we can use the
    // name function of the component
    componentName = componentName || component.name && component.name();

    if (componentName) {
      this.childNameIndex_[componentName] = component;
    }

    // Add the UI object's element to the container div (box)
    // Having an element is not required
    if (typeof component.el === 'function' && component.el()) {
      var childNodes = this.contentEl().children;
      var refNode = childNodes[index] || null;
      this.contentEl().insertBefore(component.el(), refNode);
    }

    // Return so it can stored on parent object if desired.
    return component;
  };

  /**
   * Remove a child component from this component's list of children, and the
   * child component's element from this component's element
   *
   * @param  {Component} component Component to remove
   * @method removeChild
   */

  Component.prototype.removeChild = function removeChild(component) {
    if (typeof component === 'string') {
      component = this.getChild(component);
    }

    if (!component || !this.children_) {
      return;
    }

    var childFound = false;

    for (var i = this.children_.length - 1; i >= 0; i--) {
      if (this.children_[i] === component) {
        childFound = true;
        this.children_.splice(i, 1);
        break;
      }
    }

    if (!childFound) {
      return;
    }

    this.childIndex_[component.id()] = null;
    this.childNameIndex_[component.name()] = null;

    var compEl = component.el();

    if (compEl && compEl.parentNode === this.contentEl()) {
      this.contentEl().removeChild(component.el());
    }
  };

  /**
   * Add and initialize default child components from options
   * ```js
   *     // when an instance of MyComponent is created, all children in options
   *     // will be added to the instance by their name strings and options
   *     MyComponent.prototype.options_ = {
   *       children: [
   *         'myChildComponent'
   *       ],
   *       myChildComponent: {
   *         myChildOption: true
   *       }
   *     };
   *
   *     // Or when creating the component
   *     var myComp = new MyComponent(player, {
   *       children: [
   *         'myChildComponent'
   *       ],
   *       myChildComponent: {
   *         myChildOption: true
   *       }
   *     });
   * ```
   * The children option can also be an array of
   * child options objects (that also include a 'name' key).
   * This can be used if you have two child components of the
   * same type that need different options.
   * ```js
   *     var myComp = new MyComponent(player, {
   *       children: [
   *         'button',
   *         {
   *           name: 'button',
   *           someOtherOption: true
   *         },
   *         {
   *           name: 'button',
   *           someOtherOption: false
   *         }
   *       ]
   *     });
   * ```
   *
   * @method initChildren
   */

  Component.prototype.initChildren = function initChildren() {
    var _this = this;

    var children = this.options_.children;

    if (children) {
      (function () {
        // `this` is `parent`
        var parentOptions = _this.options_;

        var handleAdd = function handleAdd(child) {
          var name = child.name;
          var opts = child.opts;

          // Allow options for children to be set at the parent options
          // e.g. videojs(id, { controlBar: false });
          // instead of videojs(id, { children: { controlBar: false });
          if (parentOptions[name] !== undefined) {
            opts = parentOptions[name];
          }

          // Allow for disabling default components
          // e.g. options['children']['posterImage'] = false
          if (opts === false) {
            return;
          }

          // Allow options to be passed as a simple boolean if no configuration
          // is necessary.
          if (opts === true) {
            opts = {};
          }

          // We also want to pass the original player options to each component as well so they don't need to
          // reach back into the player for options later.
          opts.playerOptions = _this.options_.playerOptions;

          // Create and add the child component.
          // Add a direct reference to the child by name on the parent instance.
          // If two of the same component are used, different names should be supplied
          // for each
          var newChild = _this.addChild(name, opts);
          if (newChild) {
            _this[name] = newChild;
          }
        };

        // Allow for an array of children details to passed in the options
        var workingChildren = undefined;
        var Tech = Component.getComponent('Tech');

        if (Array.isArray(children)) {
          workingChildren = children;
        } else {
          workingChildren = Object.keys(children);
        }

        workingChildren
        // children that are in this.options_ but also in workingChildren  would
        // give us extra children we do not want. So, we want to filter them out.
        .concat(Object.keys(_this.options_).filter(function (child) {
          return !workingChildren.some(function (wchild) {
            if (typeof wchild === 'string') {
              return child === wchild;
            } else {
              return child === wchild.name;
            }
          });
        })).map(function (child) {
          var name = undefined,
              opts = undefined;

          if (typeof child === 'string') {
            name = child;
            opts = children[name] || _this.options_[name] || {};
          } else {
            name = child.name;
            opts = child;
          }

          return { name: name, opts: opts };
        }).filter(function (child) {
          // we have to make sure that child.name isn't in the techOrder since
          // techs are registerd as Components but can't aren't compatible
          // See https://github.com/videojs/video.js/issues/2772
          var c = Component.getComponent(child.opts.componentClass || _utilsToTitleCaseJs2['default'](child.name));
          return c && !Tech.isTech(c);
        }).forEach(handleAdd);
      })();
    }
  };

  /**
   * Allows sub components to stack CSS class names
   *
   * @return {String} The constructed class name
   * @method buildCSSClass
   */

  Component.prototype.buildCSSClass = function buildCSSClass() {
    // Child classes can include a function that does:
    // return 'CLASS NAME' + this._super();
    return '';
  };

  /**
   * Add an event listener to this component's element
   * ```js
   *     var myFunc = function(){
   *       var myComponent = this;
   *       // Do something when the event is fired
   *     };
   *
   *     myComponent.on('eventType', myFunc);
   * ```
   * The context of myFunc will be myComponent unless previously bound.
   * Alternatively, you can add a listener to another element or component.
   * ```js
   *     myComponent.on(otherElement, 'eventName', myFunc);
   *     myComponent.on(otherComponent, 'eventName', myFunc);
   * ```
   * The benefit of using this over `VjsEvents.on(otherElement, 'eventName', myFunc)`
   * and `otherComponent.on('eventName', myFunc)` is that this way the listeners
   * will be automatically cleaned up when either component is disposed.
   * It will also bind myComponent as the context of myFunc.
   * **NOTE**: When using this on elements in the page other than window
   * and document (both permanent), if you remove the element from the DOM
   * you need to call `myComponent.trigger(el, 'dispose')` on it to clean up
   * references to it and allow the browser to garbage collect it.
   *
   * @param  {String|Component} first   The event type or other component
   * @param  {Function|String}      second  The event handler or event type
   * @param  {Function}             third   The event handler
   * @return {Component}
   * @method on
   */

  Component.prototype.on = function on(first, second, third) {
    var _this2 = this;

    if (typeof first === 'string' || Array.isArray(first)) {
      Events.on(this.el_, first, Fn.bind(this, second));

      // Targeting another component or element
    } else {
        (function () {
          var target = first;
          var type = second;
          var fn = Fn.bind(_this2, third);

          // When this component is disposed, remove the listener from the other component
          var removeOnDispose = function removeOnDispose() {
            return _this2.off(target, type, fn);
          };

          // Use the same function ID so we can remove it later it using the ID
          // of the original listener
          removeOnDispose.guid = fn.guid;
          _this2.on('dispose', removeOnDispose);

          // If the other component is disposed first we need to clean the reference
          // to the other component in this component's removeOnDispose listener
          // Otherwise we create a memory leak.
          var cleanRemover = function cleanRemover() {
            return _this2.off('dispose', removeOnDispose);
          };

          // Add the same function ID so we can easily remove it later
          cleanRemover.guid = fn.guid;

          // Check if this is a DOM node
          if (first.nodeName) {
            // Add the listener to the other element
            Events.on(target, type, fn);
            Events.on(target, 'dispose', cleanRemover);

            // Should be a component
            // Not using `instanceof Component` because it makes mock players difficult
          } else if (typeof first.on === 'function') {
              // Add the listener to the other component
              target.on(type, fn);
              target.on('dispose', cleanRemover);
            }
        })();
      }

    return this;
  };

  /**
   * Remove an event listener from this component's element
   * ```js
   *     myComponent.off('eventType', myFunc);
   * ```
   * If myFunc is excluded, ALL listeners for the event type will be removed.
   * If eventType is excluded, ALL listeners will be removed from the component.
   * Alternatively you can use `off` to remove listeners that were added to other
   * elements or components using `myComponent.on(otherComponent...`.
   * In this case both the event type and listener function are REQUIRED.
   * ```js
   *     myComponent.off(otherElement, 'eventType', myFunc);
   *     myComponent.off(otherComponent, 'eventType', myFunc);
   * ```
   *
   * @param  {String=|Component}  first  The event type or other component
   * @param  {Function=|String}       second The listener function or event type
   * @param  {Function=}              third  The listener for other component
   * @return {Component}
   * @method off
   */

  Component.prototype.off = function off(first, second, third) {
    if (!first || typeof first === 'string' || Array.isArray(first)) {
      Events.off(this.el_, first, second);
    } else {
      var target = first;
      var type = second;
      // Ensure there's at least a guid, even if the function hasn't been used
      var fn = Fn.bind(this, third);

      // Remove the dispose listener on this component,
      // which was given the same guid as the event listener
      this.off('dispose', fn);

      if (first.nodeName) {
        // Remove the listener
        Events.off(target, type, fn);
        // Remove the listener for cleaning the dispose listener
        Events.off(target, 'dispose', fn);
      } else {
        target.off(type, fn);
        target.off('dispose', fn);
      }
    }

    return this;
  };

  /**
   * Add an event listener to be triggered only once and then removed
   * ```js
   *     myComponent.one('eventName', myFunc);
   * ```
   * Alternatively you can add a listener to another element or component
   * that will be triggered only once.
   * ```js
   *     myComponent.one(otherElement, 'eventName', myFunc);
   *     myComponent.one(otherComponent, 'eventName', myFunc);
   * ```
   *
   * @param  {String|Component}  first   The event type or other component
   * @param  {Function|String}       second  The listener function or event type
   * @param  {Function=}             third   The listener function for other component
   * @return {Component}
   * @method one
   */

  Component.prototype.one = function one(first, second, third) {
    var _this3 = this,
        _arguments = arguments;

    if (typeof first === 'string' || Array.isArray(first)) {
      Events.one(this.el_, first, Fn.bind(this, second));
    } else {
      (function () {
        var target = first;
        var type = second;
        var fn = Fn.bind(_this3, third);

        var newFunc = function newFunc() {
          _this3.off(target, type, newFunc);
          fn.apply(null, _arguments);
        };

        // Keep the same function ID so we can remove it later
        newFunc.guid = fn.guid;

        _this3.on(target, type, newFunc);
      })();
    }

    return this;
  };

  /**
   * Trigger an event on an element
   * ```js
   *     myComponent.trigger('eventName');
   *     myComponent.trigger({'type':'eventName'});
   *     myComponent.trigger('eventName', {data: 'some data'});
   *     myComponent.trigger({'type':'eventName'}, {data: 'some data'});
   * ```
   *
   * @param  {Event|Object|String} event  A string (the type) or an event object with a type attribute
   * @param  {Object} [hash] data hash to pass along with the event
   * @return {Component}       self
   * @method trigger
   */

  Component.prototype.trigger = function trigger(event, hash) {
    Events.trigger(this.el_, event, hash);
    return this;
  };

  /**
   * Bind a listener to the component's ready state.
   * Different from event listeners in that if the ready event has already happened
   * it will trigger the function immediately.
   *
   * @param  {Function} fn Ready listener
   * @param  {Boolean} sync Exec the listener synchronously if component is ready
   * @return {Component}
   * @method ready
   */

  Component.prototype.ready = function ready(fn) {
    var sync = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];

    if (fn) {
      if (this.isReady_) {
        if (sync) {
          fn.call(this);
        } else {
          // Call the function asynchronously by default for consistency
          this.setTimeout(fn, 1);
        }
      } else {
        this.readyQueue_ = this.readyQueue_ || [];
        this.readyQueue_.push(fn);
      }
    }
    return this;
  };

  /**
   * Trigger the ready listeners
   *
   * @return {Component}
   * @method triggerReady
   */

  Component.prototype.triggerReady = function triggerReady() {
    this.isReady_ = true;

    // Ensure ready is triggerd asynchronously
    this.setTimeout(function () {
      var readyQueue = this.readyQueue_;

      // Reset Ready Queue
      this.readyQueue_ = [];

      if (readyQueue && readyQueue.length > 0) {
        readyQueue.forEach(function (fn) {
          fn.call(this);
        }, this);
      }

      // Allow for using event listeners also
      this.trigger('ready');
    }, 1);
  };

  /**
   * Finds a single DOM element matching `selector` within the component's
   * `contentEl` or another custom context.
   *
   * @method $
   * @param  {String} selector
   *         A valid CSS selector, which will be passed to `querySelector`.
   *
   * @param  {Element|String} [context=document]
   *         A DOM element within which to query. Can also be a selector
   *         string in which case the first matching element will be used
   *         as context. If missing (or no element matches selector), falls
   *         back to `document`.
   *
   * @return {Element|null}
   */

  Component.prototype.$ = function $(selector, context) {
    return Dom.$(selector, context || this.contentEl());
  };

  /**
   * Finds a all DOM elements matching `selector` within the component's
   * `contentEl` or another custom context.
   *
   * @method $$
   * @param  {String} selector
   *         A valid CSS selector, which will be passed to `querySelectorAll`.
   *
   * @param  {Element|String} [context=document]
   *         A DOM element within which to query. Can also be a selector
   *         string in which case the first matching element will be used
   *         as context. If missing (or no element matches selector), falls
   *         back to `document`.
   *
   * @return {NodeList}
   */

  Component.prototype.$$ = function $$(selector, context) {
    return Dom.$$(selector, context || this.contentEl());
  };

  /**
   * Check if a component's element has a CSS class name
   *
   * @param {String} classToCheck Classname to check
   * @return {Component}
   * @method hasClass
   */

  Component.prototype.hasClass = function hasClass(classToCheck) {
    return Dom.hasElClass(this.el_, classToCheck);
  };

  /**
   * Add a CSS class name to the component's element
   *
   * @param {String} classToAdd Classname to add
   * @return {Component}
   * @method addClass
   */

  Component.prototype.addClass = function addClass(classToAdd) {
    Dom.addElClass(this.el_, classToAdd);
    return this;
  };

  /**
   * Remove a CSS class name from the component's element
   *
   * @param {String} classToRemove Classname to remove
   * @return {Component}
   * @method removeClass
   */

  Component.prototype.removeClass = function removeClass(classToRemove) {
    Dom.removeElClass(this.el_, classToRemove);
    return this;
  };

  /**
   * Add or remove a CSS class name from the component's element
   *
   * @param  {String} classToToggle
   * @param  {Boolean|Function} [predicate]
   *         Can be a function that returns a Boolean. If `true`, the class
   *         will be added; if `false`, the class will be removed. If not
   *         given, the class will be added if not present and vice versa.
   *
   * @return {Component}
   * @method toggleClass
   */

  Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) {
    Dom.toggleElClass(this.el_, classToToggle, predicate);
    return this;
  };

  /**
   * Show the component element if hidden
   *
   * @return {Component}
   * @method show
   */

  Component.prototype.show = function show() {
    this.removeClass('vjs-hidden');
    return this;
  };

  /**
   * Hide the component element if currently showing
   *
   * @return {Component}
   * @method hide
   */

  Component.prototype.hide = function hide() {
    this.addClass('vjs-hidden');
    return this;
  };

  /**
   * Lock an item in its visible state
   * To be used with fadeIn/fadeOut.
   *
   * @return {Component}
   * @private
   * @method lockShowing
   */

  Component.prototype.lockShowing = function lockShowing() {
    this.addClass('vjs-lock-showing');
    return this;
  };

  /**
   * Unlock an item to be hidden
   * To be used with fadeIn/fadeOut.
   *
   * @return {Component}
   * @private
   * @method unlockShowing
   */

  Component.prototype.unlockShowing = function unlockShowing() {
    this.removeClass('vjs-lock-showing');
    return this;
  };

  /**
   * Set or get the width of the component (CSS values)
   * Setting the video tag dimension values only works with values in pixels.
   * Percent values will not work.
   * Some percents can be used, but width()/height() will return the number + %,
   * not the actual computed width/height.
   *
   * @param  {Number|String=} num   Optional width number
   * @param  {Boolean} skipListeners Skip the 'resize' event trigger
   * @return {Component} This component, when setting the width
   * @return {Number|String} The width, when getting
   * @method width
   */

  Component.prototype.width = function width(num, skipListeners) {
    return this.dimension('width', num, skipListeners);
  };

  /**
   * Get or set the height of the component (CSS values)
   * Setting the video tag dimension values only works with values in pixels.
   * Percent values will not work.
   * Some percents can be used, but width()/height() will return the number + %,
   * not the actual computed width/height.
   *
   * @param  {Number|String=} num     New component height
   * @param  {Boolean=} skipListeners Skip the resize event trigger
   * @return {Component} This component, when setting the height
   * @return {Number|String} The height, when getting
   * @method height
   */

  Component.prototype.height = function height(num, skipListeners) {
    return this.dimension('height', num, skipListeners);
  };

  /**
   * Set both width and height at the same time
   *
   * @param  {Number|String} width Width of player
   * @param  {Number|String} height Height of player
   * @return {Component} The component
   * @method dimensions
   */

  Component.prototype.dimensions = function dimensions(width, height) {
    // Skip resize listeners on width for optimization
    return this.width(width, true).height(height);
  };

  /**
   * Get or set width or height
   * This is the shared code for the width() and height() methods.
   * All for an integer, integer + 'px' or integer + '%';
   * Known issue: Hidden elements officially have a width of 0. We're defaulting
   * to the style.width value and falling back to computedStyle which has the
   * hidden element issue. Info, but probably not an efficient fix:
   * http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/
   *
   * @param  {String} widthOrHeight  'width' or 'height'
   * @param  {Number|String=} num     New dimension
   * @param  {Boolean=} skipListeners Skip resize event trigger
   * @return {Component} The component if a dimension was set
   * @return {Number|String} The dimension if nothing was set
   * @private
   * @method dimension
   */

  Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) {
    if (num !== undefined) {
      // Set to zero if null or literally NaN (NaN !== NaN)
      if (num === null || num !== num) {
        num = 0;
      }

      // Check if using css width/height (% or px) and adjust
      if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) {
        this.el_.style[widthOrHeight] = num;
      } else if (num === 'auto') {
        this.el_.style[widthOrHeight] = '';
      } else {
        this.el_.style[widthOrHeight] = num + 'px';
      }

      // skipListeners allows us to avoid triggering the resize event when setting both width and height
      if (!skipListeners) {
        this.trigger('resize');
      }

      // Return component
      return this;
    }

    // Not setting a value, so getting it
    // Make sure element exists
    if (!this.el_) {
      return 0;
    }

    // Get dimension value from style
    var val = this.el_.style[widthOrHeight];
    var pxIndex = val.indexOf('px');

    if (pxIndex !== -1) {
      // Return the pixel value with no 'px'
      return parseInt(val.slice(0, pxIndex), 10);
    }

    // No px so using % or no style was set, so falling back to offsetWidth/height
    // If component has display:none, offset will return 0
    // TODO: handle display:none and no dimension style using px
    return parseInt(this.el_['offset' + _utilsToTitleCaseJs2['default'](widthOrHeight)], 10);
  };

  /**
   * Emit 'tap' events when touch events are supported
   * This is used to support toggling the controls through a tap on the video.
   * We're requiring them to be enabled because otherwise every component would
   * have this extra overhead unnecessarily, on mobile devices where extra
   * overhead is especially bad.
   *
   * @private
   * @method emitTapEvents
   */

  Component.prototype.emitTapEvents = function emitTapEvents() {
    // Track the start time so we can determine how long the touch lasted
    var touchStart = 0;
    var firstTouch = null;

    // Maximum movement allowed during a touch event to still be considered a tap
    // Other popular libs use anywhere from 2 (hammer.js) to 15, so 10 seems like a nice, round number.
    var tapMovementThreshold = 10;

    // The maximum length a touch can be while still being considered a tap
    var touchTimeThreshold = 200;

    var couldBeTap = undefined;

    this.on('touchstart', function (event) {
      // If more than one finger, don't consider treating this as a click
      if (event.touches.length === 1) {
        // Copy the touches object to prevent modifying the original
        firstTouch = _objectAssign2['default']({}, event.touches[0]);
        // Record start time so we can detect a tap vs. "touch and hold"
        touchStart = new Date().getTime();
        // Reset couldBeTap tracking
        couldBeTap = true;
      }
    });

    this.on('touchmove', function (event) {
      // If more than one finger, don't consider treating this as a click
      if (event.touches.length > 1) {
        couldBeTap = false;
      } else if (firstTouch) {
        // Some devices will throw touchmoves for all but the slightest of taps.
        // So, if we moved only a small distance, this could still be a tap
        var xdiff = event.touches[0].pageX - firstTouch.pageX;
        var ydiff = event.touches[0].pageY - firstTouch.pageY;
        var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);

        if (touchDistance > tapMovementThreshold) {
          couldBeTap = false;
        }
      }
    });

    var noTap = function noTap() {
      couldBeTap = false;
    };

    // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s
    this.on('touchleave', noTap);
    this.on('touchcancel', noTap);

    // When the touch ends, measure how long it took and trigger the appropriate
    // event
    this.on('touchend', function (event) {
      firstTouch = null;
      // Proceed only if the touchmove/leave/cancel event didn't happen
      if (couldBeTap === true) {
        // Measure how long the touch lasted
        var touchTime = new Date().getTime() - touchStart;

        // Make sure the touch was less than the threshold to be considered a tap
        if (touchTime < touchTimeThreshold) {
          // Don't let browser turn this into a click
          event.preventDefault();
          this.trigger('tap');
          // It may be good to copy the touchend event object and change the
          // type to tap, if the other event properties aren't exact after
          // Events.fixEvent runs (e.g. event.target)
        }
      }
    });
  };

  /**
   * Report user touch activity when touch events occur
   * User activity is used to determine when controls should show/hide. It's
   * relatively simple when it comes to mouse events, because any mouse event
   * should show the controls. So we capture mouse events that bubble up to the
   * player and report activity when that happens.
   * With touch events it isn't as easy. We can't rely on touch events at the
   * player level, because a tap (touchstart + touchend) on the video itself on
   * mobile devices is meant to turn controls off (and on). User activity is
   * checked asynchronously, so what could happen is a tap event on the video
   * turns the controls off, then the touchend event bubbles up to the player,
   * which if it reported user activity, would turn the controls right back on.
   * (We also don't want to completely block touch events from bubbling up)
   * Also a touchmove, touch+hold, and anything other than a tap is not supposed
   * to turn the controls back on on a mobile device.
   * Here we're setting the default component behavior to report user activity
   * whenever touch events happen, and this can be turned off by components that
   * want touch events to act differently.
   *
   * @method enableTouchActivity
   */

  Component.prototype.enableTouchActivity = function enableTouchActivity() {
    // Don't continue if the root player doesn't support reporting user activity
    if (!this.player() || !this.player().reportUserActivity) {
      return;
    }

    // listener for reporting that the user is active
    var report = Fn.bind(this.player(), this.player().reportUserActivity);

    var touchHolding = undefined;

    this.on('touchstart', function () {
      report();
      // For as long as the they are touching the device or have their mouse down,
      // we consider them active even if they're not moving their finger or mouse.
      // So we want to continue to update that they are active
      this.clearInterval(touchHolding);
      // report at the same interval as activityCheck
      touchHolding = this.setInterval(report, 250);
    });

    var touchEnd = function touchEnd(event) {
      report();
      // stop the interval that maintains activity if the touch is holding
      this.clearInterval(touchHolding);
    };

    this.on('touchmove', report);
    this.on('touchend', touchEnd);
    this.on('touchcancel', touchEnd);
  };

  /**
   * Creates timeout and sets up disposal automatically.
   *
   * @param {Function} fn The function to run after the timeout.
   * @param {Number} timeout Number of ms to delay before executing specified function.
   * @return {Number} Returns the timeout ID
   * @method setTimeout
   */

  Component.prototype.setTimeout = function setTimeout(fn, timeout) {
    fn = Fn.bind(this, fn);

    // window.setTimeout would be preferable here, but due to some bizarre issue with Sinon and/or Phantomjs, we can't.
    var timeoutId = _globalWindow2['default'].setTimeout(fn, timeout);

    var disposeFn = function disposeFn() {
      this.clearTimeout(timeoutId);
    };

    disposeFn.guid = 'vjs-timeout-' + timeoutId;

    this.on('dispose', disposeFn);

    return timeoutId;
  };

  /**
   * Clears a timeout and removes the associated dispose listener
   *
   * @param {Number} timeoutId The id of the timeout to clear
   * @return {Number} Returns the timeout ID
   * @method clearTimeout
   */

  Component.prototype.clearTimeout = function clearTimeout(timeoutId) {
    _globalWindow2['default'].clearTimeout(timeoutId);

    var disposeFn = function disposeFn() {};

    disposeFn.guid = 'vjs-timeout-' + timeoutId;

    this.off('dispose', disposeFn);

    return timeoutId;
  };

  /**
   * Creates an interval and sets up disposal automatically.
   *
   * @param {Function} fn The function to run every N seconds.
   * @param {Number} interval Number of ms to delay before executing specified function.
   * @return {Number} Returns the interval ID
   * @method setInterval
   */

  Component.prototype.setInterval = function setInterval(fn, interval) {
    fn = Fn.bind(this, fn);

    var intervalId = _globalWindow2['default'].setInterval(fn, interval);

    var disposeFn = function disposeFn() {
      this.clearInterval(intervalId);
    };

    disposeFn.guid = 'vjs-interval-' + intervalId;

    this.on('dispose', disposeFn);

    return intervalId;
  };

  /**
   * Clears an interval and removes the associated dispose listener
   *
   * @param {Number} intervalId The id of the interval to clear
   * @return {Number} Returns the interval ID
   * @method clearInterval
   */

  Component.prototype.clearInterval = function clearInterval(intervalId) {
    _globalWindow2['default'].clearInterval(intervalId);

    var disposeFn = function disposeFn() {};

    disposeFn.guid = 'vjs-interval-' + intervalId;

    this.off('dispose', disposeFn);

    return intervalId;
  };

  /**
   * Registers a component
   *
   * @param {String} name Name of the component to register
   * @param {Object} comp The component to register
   * @static
   * @method registerComponent
   */

  Component.registerComponent = function registerComponent(name, comp) {
    if (!Component.components_) {
      Component.components_ = {};
    }

    Component.components_[name] = comp;
    return comp;
  };

  /**
   * Gets a component by name
   *
   * @param {String} name Name of the component to get
   * @return {Component}
   * @static
   * @method getComponent
   */

  Component.getComponent = function getComponent(name) {
    if (Component.components_ && Component.components_[name]) {
      return Component.components_[name];
    }

    if (_globalWindow2['default'] && _globalWindow2['default'].videojs && _globalWindow2['default'].videojs[name]) {
      _utilsLogJs2['default'].warn('The ' + name + ' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)');
      return _globalWindow2['default'].videojs[name];
    }
  };

  /**
   * Sets up the constructor using the supplied init method
   * or uses the init of the parent object
   *
   * @param {Object} props An object of properties
   * @static
   * @deprecated
   * @method extend
   */

  Component.extend = function extend(props) {
    props = props || {};

    _utilsLogJs2['default'].warn('Component.extend({}) has been deprecated, use videojs.extend(Component, {}) instead');

    // Set up the constructor using the supplied init method
    // or using the init of the parent object
    // Make sure to check the unobfuscated version for external libs
    var init = props.init || props.init || this.prototype.init || this.prototype.init || function () {};
    // In Resig's simple class inheritance (previously used) the constructor
    //  is a function that calls `this.init.apply(arguments)`
    // However that would prevent us from using `ParentObject.call(this);`
    //  in a Child constructor because the `this` in `this.init`
    //  would still refer to the Child and cause an infinite loop.
    // We would instead have to do
    //    `ParentObject.prototype.init.apply(this, arguments);`
    //  Bleh. We're not creating a _super() function, so it's good to keep
    //  the parent constructor reference simple.
    var subObj = function subObj() {
      init.apply(this, arguments);
    };

    // Inherit from this object's prototype
    subObj.prototype = Object.create(this.prototype);
    // Reset the constructor property for subObj otherwise
    // instances of subObj would have the constructor of the parent Object
    subObj.prototype.constructor = subObj;

    // Make the class extendable
    subObj.extend = Component.extend;

    // Extend subObj's prototype with functions and other properties from props
    for (var _name in props) {
      if (props.hasOwnProperty(_name)) {
        subObj.prototype[_name] = props[_name];
      }
    }

    return subObj;
  };

  return Component;
})();

Component.registerComponent('Component', Component);
exports['default'] = Component;
module.exports = exports['default'];

},{"./utils/dom.js":132,"./utils/events.js":133,"./utils/fn.js":134,"./utils/guid.js":136,"./utils/log.js":137,"./utils/merge-options.js":138,"./utils/to-title-case.js":141,"global/window":2,"object.assign":45}],68:[function(_dereq_,module,exports){
/**
 * @file control-bar.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

// Required children

var _playToggleJs = _dereq_('./play-toggle.js');

var _playToggleJs2 = _interopRequireDefault(_playToggleJs);

var _timeControlsCurrentTimeDisplayJs = _dereq_('./time-controls/current-time-display.js');

var _timeControlsCurrentTimeDisplayJs2 = _interopRequireDefault(_timeControlsCurrentTimeDisplayJs);

var _timeControlsDurationDisplayJs = _dereq_('./time-controls/duration-display.js');

var _timeControlsDurationDisplayJs2 = _interopRequireDefault(_timeControlsDurationDisplayJs);

var _timeControlsTimeDividerJs = _dereq_('./time-controls/time-divider.js');

var _timeControlsTimeDividerJs2 = _interopRequireDefault(_timeControlsTimeDividerJs);

var _timeControlsRemainingTimeDisplayJs = _dereq_('./time-controls/remaining-time-display.js');

var _timeControlsRemainingTimeDisplayJs2 = _interopRequireDefault(_timeControlsRemainingTimeDisplayJs);

var _liveDisplayJs = _dereq_('./live-display.js');

var _liveDisplayJs2 = _interopRequireDefault(_liveDisplayJs);

var _progressControlProgressControlJs = _dereq_('./progress-control/progress-control.js');

var _progressControlProgressControlJs2 = _interopRequireDefault(_progressControlProgressControlJs);

var _fullscreenToggleJs = _dereq_('./fullscreen-toggle.js');

var _fullscreenToggleJs2 = _interopRequireDefault(_fullscreenToggleJs);

var _volumeControlVolumeControlJs = _dereq_('./volume-control/volume-control.js');

var _volumeControlVolumeControlJs2 = _interopRequireDefault(_volumeControlVolumeControlJs);

var _volumeMenuButtonJs = _dereq_('./volume-menu-button.js');

var _volumeMenuButtonJs2 = _interopRequireDefault(_volumeMenuButtonJs);

var _muteToggleJs = _dereq_('./mute-toggle.js');

var _muteToggleJs2 = _interopRequireDefault(_muteToggleJs);

var _textTrackControlsChaptersButtonJs = _dereq_('./text-track-controls/chapters-button.js');

var _textTrackControlsChaptersButtonJs2 = _interopRequireDefault(_textTrackControlsChaptersButtonJs);

var _textTrackControlsSubtitlesButtonJs = _dereq_('./text-track-controls/subtitles-button.js');

var _textTrackControlsSubtitlesButtonJs2 = _interopRequireDefault(_textTrackControlsSubtitlesButtonJs);

var _textTrackControlsCaptionsButtonJs = _dereq_('./text-track-controls/captions-button.js');

var _textTrackControlsCaptionsButtonJs2 = _interopRequireDefault(_textTrackControlsCaptionsButtonJs);

var _playbackRateMenuPlaybackRateMenuButtonJs = _dereq_('./playback-rate-menu/playback-rate-menu-button.js');

var _playbackRateMenuPlaybackRateMenuButtonJs2 = _interopRequireDefault(_playbackRateMenuPlaybackRateMenuButtonJs);

var _spacerControlsCustomControlSpacerJs = _dereq_('./spacer-controls/custom-control-spacer.js');

var _spacerControlsCustomControlSpacerJs2 = _interopRequireDefault(_spacerControlsCustomControlSpacerJs);

/**
 * Container of main controls
 *
 * @extends Component
 * @class ControlBar
 */

var ControlBar = (function (_Component) {
  _inherits(ControlBar, _Component);

  function ControlBar() {
    _classCallCheck(this, ControlBar);

    _Component.apply(this, arguments);
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  ControlBar.prototype.createEl = function createEl() {
    return _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-control-bar',
      dir: 'ltr'
    }, {
      'role': 'group' // The control bar is a group, so it can contain menuitems
    });
  };

  return ControlBar;
})(_componentJs2['default']);

ControlBar.prototype.options_ = {
  loadEvent: 'play',
  children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'subtitlesButton', 'captionsButton', 'fullscreenToggle']
};

_componentJs2['default'].registerComponent('ControlBar', ControlBar);
exports['default'] = ControlBar;
module.exports = exports['default'];

},{"../component.js":67,"./fullscreen-toggle.js":69,"./live-display.js":70,"./mute-toggle.js":71,"./play-toggle.js":72,"./playback-rate-menu/playback-rate-menu-button.js":73,"./progress-control/progress-control.js":78,"./spacer-controls/custom-control-spacer.js":80,"./text-track-controls/captions-button.js":83,"./text-track-controls/chapters-button.js":84,"./text-track-controls/subtitles-button.js":87,"./time-controls/current-time-display.js":90,"./time-controls/duration-display.js":91,"./time-controls/remaining-time-display.js":92,"./time-controls/time-divider.js":93,"./volume-control/volume-control.js":95,"./volume-menu-button.js":97}],69:[function(_dereq_,module,exports){
/**
 * @file fullscreen-toggle.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _buttonJs = _dereq_('../button.js');

var _buttonJs2 = _interopRequireDefault(_buttonJs);

var _componentJs = _dereq_('../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

/**
 * Toggle fullscreen video
 *
 * @extends Button
 * @class FullscreenToggle
 */

var FullscreenToggle = (function (_Button) {
  _inherits(FullscreenToggle, _Button);

  function FullscreenToggle() {
    _classCallCheck(this, FullscreenToggle);

    _Button.apply(this, arguments);
  }

  /**
   * Allow sub components to stack CSS class names
   *
   * @return {String} The constructed class name
   * @method buildCSSClass
   */

  FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() {
    return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this);
  };

  /**
   * Handles click for full screen
   *
   * @method handleClick
   */

  FullscreenToggle.prototype.handleClick = function handleClick() {
    if (!this.player_.isFullscreen()) {
      this.player_.requestFullscreen();
      this.controlText('Non-Fullscreen');
    } else {
      this.player_.exitFullscreen();
      this.controlText('Fullscreen');
    }
  };

  return FullscreenToggle;
})(_buttonJs2['default']);

FullscreenToggle.prototype.controlText_ = 'Fullscreen';

_componentJs2['default'].registerComponent('FullscreenToggle', FullscreenToggle);
exports['default'] = FullscreenToggle;
module.exports = exports['default'];

},{"../button.js":64,"../component.js":67}],70:[function(_dereq_,module,exports){
/**
 * @file live-display.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _component = _dereq_('../component');

var _component2 = _interopRequireDefault(_component);

var _utilsDomJs = _dereq_('../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

/**
 * Displays the live indicator
 * TODO - Future make it click to snap to live
 *
 * @extends Component
 * @class LiveDisplay
 */

var LiveDisplay = (function (_Component) {
  _inherits(LiveDisplay, _Component);

  function LiveDisplay(player, options) {
    _classCallCheck(this, LiveDisplay);

    _Component.call(this, player, options);

    this.updateShowing();
    this.on(this.player(), 'durationchange', this.updateShowing);
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  LiveDisplay.prototype.createEl = function createEl() {
    var el = _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-live-control vjs-control'
    });

    this.contentEl_ = Dom.createEl('div', {
      className: 'vjs-live-display',
      innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE')
    }, {
      'aria-live': 'off'
    });

    el.appendChild(this.contentEl_);
    return el;
  };

  LiveDisplay.prototype.updateShowing = function updateShowing() {
    if (this.player().duration() === Infinity) {
      this.show();
    } else {
      this.hide();
    }
  };

  return LiveDisplay;
})(_component2['default']);

_component2['default'].registerComponent('LiveDisplay', LiveDisplay);
exports['default'] = LiveDisplay;
module.exports = exports['default'];

},{"../component":67,"../utils/dom.js":132}],71:[function(_dereq_,module,exports){
/**
 * @file mute-toggle.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _button = _dereq_('../button');

var _button2 = _interopRequireDefault(_button);

var _component = _dereq_('../component');

var _component2 = _interopRequireDefault(_component);

var _utilsDomJs = _dereq_('../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

/**
 * A button component for muting the audio
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Button
 * @class MuteToggle
 */

var MuteToggle = (function (_Button) {
  _inherits(MuteToggle, _Button);

  function MuteToggle(player, options) {
    _classCallCheck(this, MuteToggle);

    _Button.call(this, player, options);

    this.on(player, 'volumechange', this.update);

    // hide mute toggle if the current tech doesn't support volume control
    if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
      this.addClass('vjs-hidden');
    }

    this.on(player, 'loadstart', function () {
      this.update(); // We need to update the button to account for a default muted state.

      if (player.tech_['featuresVolumeControl'] === false) {
        this.addClass('vjs-hidden');
      } else {
        this.removeClass('vjs-hidden');
      }
    });
  }

  /**
   * Allow sub components to stack CSS class names
   *
   * @return {String} The constructed class name
   * @method buildCSSClass
   */

  MuteToggle.prototype.buildCSSClass = function buildCSSClass() {
    return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this);
  };

  /**
   * Handle click on mute
   *
   * @method handleClick
   */

  MuteToggle.prototype.handleClick = function handleClick() {
    this.player_.muted(this.player_.muted() ? false : true);
  };

  /**
   * Update volume
   *
   * @method update
   */

  MuteToggle.prototype.update = function update() {
    var vol = this.player_.volume(),
        level = 3;

    if (vol === 0 || this.player_.muted()) {
      level = 0;
    } else if (vol < 0.33) {
      level = 1;
    } else if (vol < 0.67) {
      level = 2;
    }

    // Don't rewrite the button text if the actual text doesn't change.
    // This causes unnecessary and confusing information for screen reader users.
    // This check is needed because this function gets called every time the volume level is changed.
    var toMute = this.player_.muted() ? 'Unmute' : 'Mute';
    if (this.controlText() !== toMute) {
      this.controlText(toMute);
    }

    /* TODO improve muted icon classes */
    for (var i = 0; i < 4; i++) {
      Dom.removeElClass(this.el_, 'vjs-vol-' + i);
    }
    Dom.addElClass(this.el_, 'vjs-vol-' + level);
  };

  return MuteToggle;
})(_button2['default']);

MuteToggle.prototype.controlText_ = 'Mute';

_component2['default'].registerComponent('MuteToggle', MuteToggle);
exports['default'] = MuteToggle;
module.exports = exports['default'];

},{"../button":64,"../component":67,"../utils/dom.js":132}],72:[function(_dereq_,module,exports){
/**
 * @file play-toggle.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _buttonJs = _dereq_('../button.js');

var _buttonJs2 = _interopRequireDefault(_buttonJs);

var _componentJs = _dereq_('../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

/**
 * Button to toggle between play and pause
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Button
 * @class PlayToggle
 */

var PlayToggle = (function (_Button) {
  _inherits(PlayToggle, _Button);

  function PlayToggle(player, options) {
    _classCallCheck(this, PlayToggle);

    _Button.call(this, player, options);

    this.on(player, 'play', this.handlePlay);
    this.on(player, 'pause', this.handlePause);
  }

  /**
   * Allow sub components to stack CSS class names
   *
   * @return {String} The constructed class name
   * @method buildCSSClass
   */

  PlayToggle.prototype.buildCSSClass = function buildCSSClass() {
    return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this);
  };

  /**
   * Handle click to toggle between play and pause
   *
   * @method handleClick
   */

  PlayToggle.prototype.handleClick = function handleClick() {
    if (this.player_.paused()) {
      this.player_.play();
    } else {
      this.player_.pause();
    }
  };

  /**
   * Add the vjs-playing class to the element so it can change appearance
   *
   * @method handlePlay
   */

  PlayToggle.prototype.handlePlay = function handlePlay() {
    this.removeClass('vjs-paused');
    this.addClass('vjs-playing');
    this.controlText('Pause'); // change the button text to "Pause"
  };

  /**
   * Add the vjs-paused class to the element so it can change appearance
   *
   * @method handlePause
   */

  PlayToggle.prototype.handlePause = function handlePause() {
    this.removeClass('vjs-playing');
    this.addClass('vjs-paused');
    this.controlText('Play'); // change the button text to "Play"
  };

  return PlayToggle;
})(_buttonJs2['default']);

PlayToggle.prototype.controlText_ = 'Play';

_componentJs2['default'].registerComponent('PlayToggle', PlayToggle);
exports['default'] = PlayToggle;
module.exports = exports['default'];

},{"../button.js":64,"../component.js":67}],73:[function(_dereq_,module,exports){
/**
 * @file playback-rate-menu-button.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _menuMenuButtonJs = _dereq_('../../menu/menu-button.js');

var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs);

var _menuMenuJs = _dereq_('../../menu/menu.js');

var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs);

var _playbackRateMenuItemJs = _dereq_('./playback-rate-menu-item.js');

var _playbackRateMenuItemJs2 = _interopRequireDefault(_playbackRateMenuItemJs);

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsDomJs = _dereq_('../../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

/**
 * The component for controlling the playback rate
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends MenuButton
 * @class PlaybackRateMenuButton
 */

var PlaybackRateMenuButton = (function (_MenuButton) {
  _inherits(PlaybackRateMenuButton, _MenuButton);

  function PlaybackRateMenuButton(player, options) {
    _classCallCheck(this, PlaybackRateMenuButton);

    _MenuButton.call(this, player, options);

    this.updateVisibility();
    this.updateLabel();

    this.on(player, 'loadstart', this.updateVisibility);
    this.on(player, 'ratechange', this.updateLabel);
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  PlaybackRateMenuButton.prototype.createEl = function createEl() {
    var el = _MenuButton.prototype.createEl.call(this);

    this.labelEl_ = Dom.createEl('div', {
      className: 'vjs-playback-rate-value',
      innerHTML: 1.0
    });

    el.appendChild(this.labelEl_);

    return el;
  };

  /**
   * Allow sub components to stack CSS class names
   *
   * @return {String} The constructed class name
   * @method buildCSSClass
   */

  PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() {
    return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this);
  };

  /**
   * Create the playback rate menu
   *
   * @return {Menu} Menu object populated with items
   * @method createMenu
   */

  PlaybackRateMenuButton.prototype.createMenu = function createMenu() {
    var menu = new _menuMenuJs2['default'](this.player());
    var rates = this.playbackRates();

    if (rates) {
      for (var i = rates.length - 1; i >= 0; i--) {
        menu.addChild(new _playbackRateMenuItemJs2['default'](this.player(), { 'rate': rates[i] + 'x' }));
      }
    }

    return menu;
  };

  /**
   * Updates ARIA accessibility attributes
   *
   * @method updateARIAAttributes
   */

  PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() {
    // Current playback rate
    this.el().setAttribute('aria-valuenow', this.player().playbackRate());
  };

  /**
   * Handle menu item click
   *
   * @method handleClick
   */

  PlaybackRateMenuButton.prototype.handleClick = function handleClick() {
    // select next rate option
    var currentRate = this.player().playbackRate();
    var rates = this.playbackRates();

    // this will select first one if the last one currently selected
    var newRate = rates[0];
    for (var i = 0; i < rates.length; i++) {
      if (rates[i] > currentRate) {
        newRate = rates[i];
        break;
      }
    }
    this.player().playbackRate(newRate);
  };

  /**
   * Get possible playback rates
   *
   * @return {Array} Possible playback rates
   * @method playbackRates
   */

  PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() {
    return this.options_['playbackRates'] || this.options_.playerOptions && this.options_.playerOptions['playbackRates'];
  };

  /**
   * Get supported playback rates
   *
   * @return {Array} Supported playback rates
   * @method playbackRateSupported
   */

  PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() {
    return this.player().tech_ && this.player().tech_['featuresPlaybackRate'] && this.playbackRates() && this.playbackRates().length > 0;
  };

  /**
   * Hide playback rate controls when they're no playback rate options to select
   *
   * @method updateVisibility
   */

  PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility() {
    if (this.playbackRateSupported()) {
      this.removeClass('vjs-hidden');
    } else {
      this.addClass('vjs-hidden');
    }
  };

  /**
   * Update button label when rate changed
   *
   * @method updateLabel
   */

  PlaybackRateMenuButton.prototype.updateLabel = function updateLabel() {
    if (this.playbackRateSupported()) {
      this.labelEl_.innerHTML = this.player().playbackRate() + 'x';
    }
  };

  return PlaybackRateMenuButton;
})(_menuMenuButtonJs2['default']);

PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate';

_componentJs2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton);
exports['default'] = PlaybackRateMenuButton;
module.exports = exports['default'];

},{"../../component.js":67,"../../menu/menu-button.js":104,"../../menu/menu.js":106,"../../utils/dom.js":132,"./playback-rate-menu-item.js":74}],74:[function(_dereq_,module,exports){
/**
 * @file playback-rate-menu-item.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _menuMenuItemJs = _dereq_('../../menu/menu-item.js');

var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

/**
 * The specific menu item type for selecting a playback rate
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends MenuItem
 * @class PlaybackRateMenuItem
 */

var PlaybackRateMenuItem = (function (_MenuItem) {
  _inherits(PlaybackRateMenuItem, _MenuItem);

  function PlaybackRateMenuItem(player, options) {
    _classCallCheck(this, PlaybackRateMenuItem);

    var label = options['rate'];
    var rate = parseFloat(label, 10);

    // Modify options for parent MenuItem class's init.
    options['label'] = label;
    options['selected'] = rate === 1;
    _MenuItem.call(this, player, options);

    this.label = label;
    this.rate = rate;

    this.on(player, 'ratechange', this.update);
  }

  /**
   * Handle click on menu item
   *
   * @method handleClick
   */

  PlaybackRateMenuItem.prototype.handleClick = function handleClick() {
    _MenuItem.prototype.handleClick.call(this);
    this.player().playbackRate(this.rate);
  };

  /**
   * Update playback rate with selected rate
   *
   * @method update
   */

  PlaybackRateMenuItem.prototype.update = function update() {
    this.selected(this.player().playbackRate() === this.rate);
  };

  return PlaybackRateMenuItem;
})(_menuMenuItemJs2['default']);

PlaybackRateMenuItem.prototype.contentElType = 'button';

_componentJs2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem);
exports['default'] = PlaybackRateMenuItem;
module.exports = exports['default'];

},{"../../component.js":67,"../../menu/menu-item.js":105}],75:[function(_dereq_,module,exports){
/**
 * @file load-progress-bar.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsDomJs = _dereq_('../../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

/**
 * Shows load progress
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Component
 * @class LoadProgressBar
 */

var LoadProgressBar = (function (_Component) {
  _inherits(LoadProgressBar, _Component);

  function LoadProgressBar(player, options) {
    _classCallCheck(this, LoadProgressBar);

    _Component.call(this, player, options);
    this.on(player, 'progress', this.update);
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  LoadProgressBar.prototype.createEl = function createEl() {
    return _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-load-progress',
      innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>'
    });
  };

  /**
   * Update progress bar
   *
   * @method update
   */

  LoadProgressBar.prototype.update = function update() {
    var buffered = this.player_.buffered();
    var duration = this.player_.duration();
    var bufferedEnd = this.player_.bufferedEnd();
    var children = this.el_.children;

    // get the percent width of a time compared to the total end
    var percentify = function percentify(time, end) {
      var percent = time / end || 0; // no NaN
      return (percent >= 1 ? 1 : percent) * 100 + '%';
    };

    // update the width of the progress bar
    this.el_.style.width = percentify(bufferedEnd, duration);

    // add child elements to represent the individual buffered time ranges
    for (var i = 0; i < buffered.length; i++) {
      var start = buffered.start(i);
      var end = buffered.end(i);
      var part = children[i];

      if (!part) {
        part = this.el_.appendChild(Dom.createEl());
      }

      // set the percent based on the width of the progress bar (bufferedEnd)
      part.style.left = percentify(start, bufferedEnd);
      part.style.width = percentify(end - start, bufferedEnd);
    }

    // remove unused buffered range elements
    for (var i = children.length; i > buffered.length; i--) {
      this.el_.removeChild(children[i - 1]);
    }
  };

  return LoadProgressBar;
})(_componentJs2['default']);

_componentJs2['default'].registerComponent('LoadProgressBar', LoadProgressBar);
exports['default'] = LoadProgressBar;
module.exports = exports['default'];

},{"../../component.js":67,"../../utils/dom.js":132}],76:[function(_dereq_,module,exports){
/**
 * @file mouse-time-display.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsDomJs = _dereq_('../../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsFnJs = _dereq_('../../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');

var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);

var _lodashCompatFunctionThrottle = _dereq_('lodash-compat/function/throttle');

var _lodashCompatFunctionThrottle2 = _interopRequireDefault(_lodashCompatFunctionThrottle);

/**
 * The Mouse Time Display component shows the time you will seek to
 * when hovering over the progress bar
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Component
 * @class MouseTimeDisplay
 */

var MouseTimeDisplay = (function (_Component) {
  _inherits(MouseTimeDisplay, _Component);

  function MouseTimeDisplay(player, options) {
    var _this = this;

    _classCallCheck(this, MouseTimeDisplay);

    _Component.call(this, player, options);

    this.update(0, 0);

    player.on('ready', function () {
      _this.on(player.controlBar.progressControl.el(), 'mousemove', _lodashCompatFunctionThrottle2['default'](Fn.bind(_this, _this.handleMouseMove), 25));
    });
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  MouseTimeDisplay.prototype.createEl = function createEl() {
    return _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-mouse-display'
    });
  };

  MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) {
    var duration = this.player_.duration();
    var newTime = this.calculateDistance(event) * duration;
    var position = event.pageX - Dom.findElPosition(this.el().parentNode).left;

    this.update(newTime, position);
  };

  MouseTimeDisplay.prototype.update = function update(newTime, position) {
    var time = _utilsFormatTimeJs2['default'](newTime, this.player_.duration());

    this.el().style.left = position + 'px';
    this.el().setAttribute('data-current-time', time);
  };

  MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) {
    return Dom.getPointerPosition(this.el().parentNode, event).x;
  };

  return MouseTimeDisplay;
})(_componentJs2['default']);

_componentJs2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay);
exports['default'] = MouseTimeDisplay;
module.exports = exports['default'];

},{"../../component.js":67,"../../utils/dom.js":132,"../../utils/fn.js":134,"../../utils/format-time.js":135,"lodash-compat/function/throttle":7}],77:[function(_dereq_,module,exports){
/**
 * @file play-progress-bar.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsFnJs = _dereq_('../../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');

var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);

/**
 * Shows play progress
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Component
 * @class PlayProgressBar
 */

var PlayProgressBar = (function (_Component) {
  _inherits(PlayProgressBar, _Component);

  function PlayProgressBar(player, options) {
    _classCallCheck(this, PlayProgressBar);

    _Component.call(this, player, options);
    this.updateDataAttr();
    this.on(player, 'timeupdate', this.updateDataAttr);
    player.ready(Fn.bind(this, this.updateDataAttr));
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  PlayProgressBar.prototype.createEl = function createEl() {
    return _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-play-progress vjs-slider-bar',
      innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
    });
  };

  PlayProgressBar.prototype.updateDataAttr = function updateDataAttr() {
    var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
    this.el_.setAttribute('data-current-time', _utilsFormatTimeJs2['default'](time, this.player_.duration()));
  };

  return PlayProgressBar;
})(_componentJs2['default']);

_componentJs2['default'].registerComponent('PlayProgressBar', PlayProgressBar);
exports['default'] = PlayProgressBar;
module.exports = exports['default'];

},{"../../component.js":67,"../../utils/fn.js":134,"../../utils/format-time.js":135}],78:[function(_dereq_,module,exports){
/**
 * @file progress-control.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _seekBarJs = _dereq_('./seek-bar.js');

var _seekBarJs2 = _interopRequireDefault(_seekBarJs);

var _mouseTimeDisplayJs = _dereq_('./mouse-time-display.js');

var _mouseTimeDisplayJs2 = _interopRequireDefault(_mouseTimeDisplayJs);

/**
 * The Progress Control component contains the seek bar, load progress,
 * and play progress
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Component
 * @class ProgressControl
 */

var ProgressControl = (function (_Component) {
  _inherits(ProgressControl, _Component);

  function ProgressControl() {
    _classCallCheck(this, ProgressControl);

    _Component.apply(this, arguments);
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  ProgressControl.prototype.createEl = function createEl() {
    return _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-progress-control vjs-control'
    });
  };

  return ProgressControl;
})(_componentJs2['default']);

ProgressControl.prototype.options_ = {
  children: ['seekBar']
};

_componentJs2['default'].registerComponent('ProgressControl', ProgressControl);
exports['default'] = ProgressControl;
module.exports = exports['default'];

},{"../../component.js":67,"./mouse-time-display.js":76,"./seek-bar.js":79}],79:[function(_dereq_,module,exports){
/**
 * @file seek-bar.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _sliderSliderJs = _dereq_('../../slider/slider.js');

var _sliderSliderJs2 = _interopRequireDefault(_sliderSliderJs);

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _loadProgressBarJs = _dereq_('./load-progress-bar.js');

var _loadProgressBarJs2 = _interopRequireDefault(_loadProgressBarJs);

var _playProgressBarJs = _dereq_('./play-progress-bar.js');

var _playProgressBarJs2 = _interopRequireDefault(_playProgressBarJs);

var _utilsFnJs = _dereq_('../../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');

var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);

var _objectAssign = _dereq_('object.assign');

var _objectAssign2 = _interopRequireDefault(_objectAssign);

/**
 * Seek Bar and holder for the progress bars
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Slider
 * @class SeekBar
 */

var SeekBar = (function (_Slider) {
  _inherits(SeekBar, _Slider);

  function SeekBar(player, options) {
    _classCallCheck(this, SeekBar);

    _Slider.call(this, player, options);
    this.on(player, 'timeupdate', this.updateARIAAttributes);
    player.ready(Fn.bind(this, this.updateARIAAttributes));
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  SeekBar.prototype.createEl = function createEl() {
    return _Slider.prototype.createEl.call(this, 'div', {
      className: 'vjs-progress-holder'
    }, {
      'aria-label': 'video progress bar'
    });
  };

  /**
   * Update ARIA accessibility attributes
   *
   * @method updateARIAAttributes
   */

  SeekBar.prototype.updateARIAAttributes = function updateARIAAttributes() {
    // Allows for smooth scrubbing, when player can't keep up.
    var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
    this.el_.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2)); // machine readable value of progress bar (percentage complete)
    this.el_.setAttribute('aria-valuetext', _utilsFormatTimeJs2['default'](time, this.player_.duration())); // human readable value of progress bar (time complete)
  };

  /**
   * Get percentage of video played
   *
   * @return {Number} Percentage played
   * @method getPercent
   */

  SeekBar.prototype.getPercent = function getPercent() {
    var percent = this.player_.currentTime() / this.player_.duration();
    return percent >= 1 ? 1 : percent;
  };

  /**
   * Handle mouse down on seek bar
   *
   * @method handleMouseDown
   */

  SeekBar.prototype.handleMouseDown = function handleMouseDown(event) {
    _Slider.prototype.handleMouseDown.call(this, event);

    this.player_.scrubbing(true);

    this.videoWasPlaying = !this.player_.paused();
    this.player_.pause();
  };

  /**
   * Handle mouse move on seek bar
   *
   * @method handleMouseMove
   */

  SeekBar.prototype.handleMouseMove = function handleMouseMove(event) {
    var newTime = this.calculateDistance(event) * this.player_.duration();

    // Don't let video end while scrubbing.
    if (newTime === this.player_.duration()) {
      newTime = newTime - 0.1;
    }

    // Set new time (tell player to seek to new time)
    this.player_.currentTime(newTime);
  };

  /**
   * Handle mouse up on seek bar
   *
   * @method handleMouseUp
   */

  SeekBar.prototype.handleMouseUp = function handleMouseUp(event) {
    _Slider.prototype.handleMouseUp.call(this, event);

    this.player_.scrubbing(false);
    if (this.videoWasPlaying) {
      this.player_.play();
    }
  };

  /**
   * Move more quickly fast forward for keyboard-only users
   *
   * @method stepForward
   */

  SeekBar.prototype.stepForward = function stepForward() {
    this.player_.currentTime(this.player_.currentTime() + 5); // more quickly fast forward for keyboard-only users
  };

  /**
   * Move more quickly rewind for keyboard-only users
   *
   * @method stepBack
   */

  SeekBar.prototype.stepBack = function stepBack() {
    this.player_.currentTime(this.player_.currentTime() - 5); // more quickly rewind for keyboard-only users
  };

  return SeekBar;
})(_sliderSliderJs2['default']);

SeekBar.prototype.options_ = {
  children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'],
  'barName': 'playProgressBar'
};

SeekBar.prototype.playerEvent = 'timeupdate';

_componentJs2['default'].registerComponent('SeekBar', SeekBar);
exports['default'] = SeekBar;
module.exports = exports['default'];

},{"../../component.js":67,"../../slider/slider.js":114,"../../utils/fn.js":134,"../../utils/format-time.js":135,"./load-progress-bar.js":75,"./play-progress-bar.js":77,"object.assign":45}],80:[function(_dereq_,module,exports){
/**
 * @file custom-control-spacer.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _spacerJs = _dereq_('./spacer.js');

var _spacerJs2 = _interopRequireDefault(_spacerJs);

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

/**
 * Spacer specifically meant to be used as an insertion point for new plugins, etc.
 *
 * @extends Spacer
 * @class CustomControlSpacer
 */

var CustomControlSpacer = (function (_Spacer) {
  _inherits(CustomControlSpacer, _Spacer);

  function CustomControlSpacer() {
    _classCallCheck(this, CustomControlSpacer);

    _Spacer.apply(this, arguments);
  }

  /**
   * Allow sub components to stack CSS class names
   *
   * @return {String} The constructed class name
   * @method buildCSSClass
   */

  CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() {
    return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this);
  };

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  CustomControlSpacer.prototype.createEl = function createEl() {
    var el = _Spacer.prototype.createEl.call(this, {
      className: this.buildCSSClass()
    });

    // No-flex/table-cell mode requires there be some content
    // in the cell to fill the remaining space of the table.
    el.innerHTML = '&nbsp;';
    return el;
  };

  return CustomControlSpacer;
})(_spacerJs2['default']);

_componentJs2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer);
exports['default'] = CustomControlSpacer;
module.exports = exports['default'];

},{"../../component.js":67,"./spacer.js":81}],81:[function(_dereq_,module,exports){
/**
 * @file spacer.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

/**
 * Just an empty spacer element that can be used as an append point for plugins, etc.
 * Also can be used to create space between elements when necessary.
 *
 * @extends Component
 * @class Spacer
 */

var Spacer = (function (_Component) {
  _inherits(Spacer, _Component);

  function Spacer() {
    _classCallCheck(this, Spacer);

    _Component.apply(this, arguments);
  }

  /**
   * Allow sub components to stack CSS class names
   *
   * @return {String} The constructed class name
   * @method buildCSSClass
   */

  Spacer.prototype.buildCSSClass = function buildCSSClass() {
    return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this);
  };

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  Spacer.prototype.createEl = function createEl() {
    return _Component.prototype.createEl.call(this, 'div', {
      className: this.buildCSSClass()
    });
  };

  return Spacer;
})(_componentJs2['default']);

_componentJs2['default'].registerComponent('Spacer', Spacer);

exports['default'] = Spacer;
module.exports = exports['default'];

},{"../../component.js":67}],82:[function(_dereq_,module,exports){
/**
 * @file caption-settings-menu-item.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');

var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

/**
 * The menu item for caption track settings menu
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends TextTrackMenuItem
 * @class CaptionSettingsMenuItem
 */

var CaptionSettingsMenuItem = (function (_TextTrackMenuItem) {
  _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem);

  function CaptionSettingsMenuItem(player, options) {
    _classCallCheck(this, CaptionSettingsMenuItem);

    options['track'] = {
      'kind': options['kind'],
      'player': player,
      'label': options['kind'] + ' settings',
      'selectable': false,
      'default': false,
      mode: 'disabled'
    };

    // CaptionSettingsMenuItem has no concept of 'selected'
    options['selectable'] = false;

    _TextTrackMenuItem.call(this, player, options);
    this.addClass('vjs-texttrack-settings');
    this.controlText(', opens ' + options['kind'] + ' settings dialog');
  }

  /**
   * Handle click on menu item
   *
   * @method handleClick
   */

  CaptionSettingsMenuItem.prototype.handleClick = function handleClick() {
    this.player().getChild('textTrackSettings').show();
    this.player().getChild('textTrackSettings').el_.focus();
  };

  return CaptionSettingsMenuItem;
})(_textTrackMenuItemJs2['default']);

_componentJs2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem);
exports['default'] = CaptionSettingsMenuItem;
module.exports = exports['default'];

},{"../../component.js":67,"./text-track-menu-item.js":89}],83:[function(_dereq_,module,exports){
/**
 * @file captions-button.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _textTrackButtonJs = _dereq_('./text-track-button.js');

var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs);

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _captionSettingsMenuItemJs = _dereq_('./caption-settings-menu-item.js');

var _captionSettingsMenuItemJs2 = _interopRequireDefault(_captionSettingsMenuItemJs);

/**
 * The button component for toggling and selecting captions
 *
 * @param {Object} player  Player object
 * @param {Object=} options Object of option names and values
 * @param {Function=} ready    Ready callback function
 * @extends TextTrackButton
 * @class CaptionsButton
 */

var CaptionsButton = (function (_TextTrackButton) {
  _inherits(CaptionsButton, _TextTrackButton);

  function CaptionsButton(player, options, ready) {
    _classCallCheck(this, CaptionsButton);

    _TextTrackButton.call(this, player, options, ready);
    this.el_.setAttribute('aria-label', 'Captions Menu');
  }

  /**
   * Allow sub components to stack CSS class names
   *
   * @return {String} The constructed class name
   * @method buildCSSClass
   */

  CaptionsButton.prototype.buildCSSClass = function buildCSSClass() {
    return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  };

  /**
   * Update caption menu items
   *
   * @method update
   */

  CaptionsButton.prototype.update = function update() {
    var threshold = 2;
    _TextTrackButton.prototype.update.call(this);

    // if native, then threshold is 1 because no settings button
    if (this.player().tech_ && this.player().tech_['featuresNativeTextTracks']) {
      threshold = 1;
    }

    if (this.items && this.items.length > threshold) {
      this.show();
    } else {
      this.hide();
    }
  };

  /**
   * Create caption menu items
   *
   * @return {Array} Array of menu items
   * @method createItems
   */

  CaptionsButton.prototype.createItems = function createItems() {
    var items = [];

    if (!(this.player().tech_ && this.player().tech_['featuresNativeTextTracks'])) {
      items.push(new _captionSettingsMenuItemJs2['default'](this.player_, { 'kind': this.kind_ }));
    }

    return _TextTrackButton.prototype.createItems.call(this, items);
  };

  return CaptionsButton;
})(_textTrackButtonJs2['default']);

CaptionsButton.prototype.kind_ = 'captions';
CaptionsButton.prototype.controlText_ = 'Captions';

_componentJs2['default'].registerComponent('CaptionsButton', CaptionsButton);
exports['default'] = CaptionsButton;
module.exports = exports['default'];

},{"../../component.js":67,"./caption-settings-menu-item.js":82,"./text-track-button.js":88}],84:[function(_dereq_,module,exports){
/**
 * @file chapters-button.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _textTrackButtonJs = _dereq_('./text-track-button.js');

var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs);

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');

var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);

var _chaptersTrackMenuItemJs = _dereq_('./chapters-track-menu-item.js');

var _chaptersTrackMenuItemJs2 = _interopRequireDefault(_chaptersTrackMenuItemJs);

var _menuMenuJs = _dereq_('../../menu/menu.js');

var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs);

var _utilsDomJs = _dereq_('../../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsFnJs = _dereq_('../../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsToTitleCaseJs = _dereq_('../../utils/to-title-case.js');

var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

/**
 * The button component for toggling and selecting chapters
 * Chapters act much differently than other text tracks
 * Cues are navigation vs. other tracks of alternative languages
 *
 * @param {Object} player  Player object
 * @param {Object=} options Object of option names and values
 * @param {Function=} ready    Ready callback function
 * @extends TextTrackButton
 * @class ChaptersButton
 */

var ChaptersButton = (function (_TextTrackButton) {
  _inherits(ChaptersButton, _TextTrackButton);

  function ChaptersButton(player, options, ready) {
    _classCallCheck(this, ChaptersButton);

    _TextTrackButton.call(this, player, options, ready);
    this.el_.setAttribute('aria-label', 'Chapters Menu');
  }

  /**
   * Allow sub components to stack CSS class names
   *
   * @return {String} The constructed class name
   * @method buildCSSClass
   */

  ChaptersButton.prototype.buildCSSClass = function buildCSSClass() {
    return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  };

  /**
   * Create a menu item for each text track
   *
   * @return {Array} Array of menu items
   * @method createItems
   */

  ChaptersButton.prototype.createItems = function createItems() {
    var items = [];

    var tracks = this.player_.textTracks();

    if (!tracks) {
      return items;
    }

    for (var i = 0; i < tracks.length; i++) {
      var track = tracks[i];
      if (track['kind'] === this.kind_) {
        items.push(new _textTrackMenuItemJs2['default'](this.player_, {
          'track': track
        }));
      }
    }

    return items;
  };

  /**
   * Create menu from chapter buttons
   *
   * @return {Menu} Menu of chapter buttons
   * @method createMenu
   */

  ChaptersButton.prototype.createMenu = function createMenu() {
    var _this = this;

    var tracks = this.player_.textTracks() || [];
    var chaptersTrack = undefined;
    var items = this.items = [];

    for (var i = 0, _length = tracks.length; i < _length; i++) {
      var track = tracks[i];

      if (track['kind'] === this.kind_) {
        chaptersTrack = track;

        break;
      }
    }

    var menu = this.menu;
    if (menu === undefined) {
      menu = new _menuMenuJs2['default'](this.player_);
      var title = Dom.createEl('li', {
        className: 'vjs-menu-title',
        innerHTML: _utilsToTitleCaseJs2['default'](this.kind_),
        tabIndex: -1
      });
      menu.children_.unshift(title);
      Dom.insertElFirst(title, menu.contentEl());
    }

    if (chaptersTrack && chaptersTrack.cues == null) {
      chaptersTrack['mode'] = 'hidden';

      var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(chaptersTrack);

      if (remoteTextTrackEl) {
        remoteTextTrackEl.addEventListener('load', function (event) {
          return _this.update();
        });
      }
    }

    if (chaptersTrack && chaptersTrack.cues && chaptersTrack.cues.length > 0) {
      var cues = chaptersTrack['cues'],
          cue = undefined;

      for (var i = 0, l = cues.length; i < l; i++) {
        cue = cues[i];

        var mi = new _chaptersTrackMenuItemJs2['default'](this.player_, {
          'track': chaptersTrack,
          'cue': cue
        });

        items.push(mi);

        menu.addChild(mi);
      }

      this.addChild(menu);
    }

    if (this.items.length > 0) {
      this.show();
    }

    return menu;
  };

  return ChaptersButton;
})(_textTrackButtonJs2['default']);

ChaptersButton.prototype.kind_ = 'chapters';
ChaptersButton.prototype.controlText_ = 'Chapters';

_componentJs2['default'].registerComponent('ChaptersButton', ChaptersButton);
exports['default'] = ChaptersButton;
module.exports = exports['default'];

},{"../../component.js":67,"../../menu/menu.js":106,"../../utils/dom.js":132,"../../utils/fn.js":134,"../../utils/to-title-case.js":141,"./chapters-track-menu-item.js":85,"./text-track-button.js":88,"./text-track-menu-item.js":89,"global/window":2}],85:[function(_dereq_,module,exports){
/**
 * @file chapters-track-menu-item.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _menuMenuItemJs = _dereq_('../../menu/menu-item.js');

var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsFnJs = _dereq_('../../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

/**
 * The chapter track menu item
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends MenuItem
 * @class ChaptersTrackMenuItem
 */

var ChaptersTrackMenuItem = (function (_MenuItem) {
  _inherits(ChaptersTrackMenuItem, _MenuItem);

  function ChaptersTrackMenuItem(player, options) {
    _classCallCheck(this, ChaptersTrackMenuItem);

    var track = options['track'];
    var cue = options['cue'];
    var currentTime = player.currentTime();

    // Modify options for parent MenuItem class's init.
    options['label'] = cue.text;
    options['selected'] = cue['startTime'] <= currentTime && currentTime < cue['endTime'];
    _MenuItem.call(this, player, options);

    this.track = track;
    this.cue = cue;
    track.addEventListener('cuechange', Fn.bind(this, this.update));
  }

  /**
   * Handle click on menu item
   *
   * @method handleClick
   */

  ChaptersTrackMenuItem.prototype.handleClick = function handleClick() {
    _MenuItem.prototype.handleClick.call(this);
    this.player_.currentTime(this.cue.startTime);
    this.update(this.cue.startTime);
  };

  /**
   * Update chapter menu item
   *
   * @method update
   */

  ChaptersTrackMenuItem.prototype.update = function update() {
    var cue = this.cue;
    var currentTime = this.player_.currentTime();

    // vjs.log(currentTime, cue.startTime);
    this.selected(cue['startTime'] <= currentTime && currentTime < cue['endTime']);
  };

  return ChaptersTrackMenuItem;
})(_menuMenuItemJs2['default']);

_componentJs2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem);
exports['default'] = ChaptersTrackMenuItem;
module.exports = exports['default'];

},{"../../component.js":67,"../../menu/menu-item.js":105,"../../utils/fn.js":134}],86:[function(_dereq_,module,exports){
/**
 * @file off-text-track-menu-item.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');

var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

/**
 * A special menu item for turning of a specific type of text track
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends TextTrackMenuItem
 * @class OffTextTrackMenuItem
 */

var OffTextTrackMenuItem = (function (_TextTrackMenuItem) {
  _inherits(OffTextTrackMenuItem, _TextTrackMenuItem);

  function OffTextTrackMenuItem(player, options) {
    _classCallCheck(this, OffTextTrackMenuItem);

    // Create pseudo track info
    // Requires options['kind']
    options['track'] = {
      'kind': options['kind'],
      'player': player,
      'label': options['kind'] + ' off',
      'default': false,
      'mode': 'disabled'
    };

    // MenuItem is selectable
    options['selectable'] = true;

    _TextTrackMenuItem.call(this, player, options);
    this.selected(true);
  }

  /**
   * Handle text track change
   *
   * @param {Object} event Event object
   * @method handleTracksChange
   */

  OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
    var tracks = this.player().textTracks();
    var selected = true;

    for (var i = 0, l = tracks.length; i < l; i++) {
      var track = tracks[i];
      if (track['kind'] === this.track['kind'] && track['mode'] === 'showing') {
        selected = false;
        break;
      }
    }

    this.selected(selected);
  };

  return OffTextTrackMenuItem;
})(_textTrackMenuItemJs2['default']);

_componentJs2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem);
exports['default'] = OffTextTrackMenuItem;
module.exports = exports['default'];

},{"../../component.js":67,"./text-track-menu-item.js":89}],87:[function(_dereq_,module,exports){
/**
 * @file subtitles-button.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _textTrackButtonJs = _dereq_('./text-track-button.js');

var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs);

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

/**
 * The button component for toggling and selecting subtitles
 *
 * @param {Object} player  Player object
 * @param {Object=} options Object of option names and values
 * @param {Function=} ready    Ready callback function
 * @extends TextTrackButton
 * @class SubtitlesButton
 */

var SubtitlesButton = (function (_TextTrackButton) {
  _inherits(SubtitlesButton, _TextTrackButton);

  function SubtitlesButton(player, options, ready) {
    _classCallCheck(this, SubtitlesButton);

    _TextTrackButton.call(this, player, options, ready);
    this.el_.setAttribute('aria-label', 'Subtitles Menu');
  }

  /**
   * Allow sub components to stack CSS class names
   *
   * @return {String} The constructed class name
   * @method buildCSSClass
   */

  SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() {
    return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  };

  return SubtitlesButton;
})(_textTrackButtonJs2['default']);

SubtitlesButton.prototype.kind_ = 'subtitles';
SubtitlesButton.prototype.controlText_ = 'Subtitles';

_componentJs2['default'].registerComponent('SubtitlesButton', SubtitlesButton);
exports['default'] = SubtitlesButton;
module.exports = exports['default'];

},{"../../component.js":67,"./text-track-button.js":88}],88:[function(_dereq_,module,exports){
/**
 * @file text-track-button.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _menuMenuButtonJs = _dereq_('../../menu/menu-button.js');

var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs);

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsFnJs = _dereq_('../../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');

var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);

var _offTextTrackMenuItemJs = _dereq_('./off-text-track-menu-item.js');

var _offTextTrackMenuItemJs2 = _interopRequireDefault(_offTextTrackMenuItemJs);

/**
 * The base class for buttons that toggle specific text track types (e.g. subtitles)
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends MenuButton
 * @class TextTrackButton
 */

var TextTrackButton = (function (_MenuButton) {
  _inherits(TextTrackButton, _MenuButton);

  function TextTrackButton(player, options) {
    _classCallCheck(this, TextTrackButton);

    _MenuButton.call(this, player, options);

    var tracks = this.player_.textTracks();

    if (this.items.length <= 1) {
      this.hide();
    }

    if (!tracks) {
      return;
    }

    var updateHandler = Fn.bind(this, this.update);
    tracks.addEventListener('removetrack', updateHandler);
    tracks.addEventListener('addtrack', updateHandler);

    this.player_.on('dispose', function () {
      tracks.removeEventListener('removetrack', updateHandler);
      tracks.removeEventListener('addtrack', updateHandler);
    });
  }

  // Create a menu item for each text track

  TextTrackButton.prototype.createItems = function createItems() {
    var items = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];

    // Add an OFF menu item to turn all tracks off
    items.push(new _offTextTrackMenuItemJs2['default'](this.player_, { 'kind': this.kind_ }));

    var tracks = this.player_.textTracks();

    if (!tracks) {
      return items;
    }

    for (var i = 0; i < tracks.length; i++) {
      var track = tracks[i];

      // only add tracks that are of the appropriate kind and have a label
      if (track['kind'] === this.kind_) {
        items.push(new _textTrackMenuItemJs2['default'](this.player_, {
          // MenuItem is selectable
          'selectable': true,
          'track': track
        }));
      }
    }

    return items;
  };

  return TextTrackButton;
})(_menuMenuButtonJs2['default']);

_componentJs2['default'].registerComponent('TextTrackButton', TextTrackButton);
exports['default'] = TextTrackButton;
module.exports = exports['default'];

},{"../../component.js":67,"../../menu/menu-button.js":104,"../../utils/fn.js":134,"./off-text-track-menu-item.js":86,"./text-track-menu-item.js":89}],89:[function(_dereq_,module,exports){
/**
 * @file text-track-menu-item.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _menuMenuItemJs = _dereq_('../../menu/menu-item.js');

var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsFnJs = _dereq_('../../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

/**
 * The specific menu item type for selecting a language within a text track kind
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends MenuItem
 * @class TextTrackMenuItem
 */

var TextTrackMenuItem = (function (_MenuItem) {
  _inherits(TextTrackMenuItem, _MenuItem);

  function TextTrackMenuItem(player, options) {
    var _this = this;

    _classCallCheck(this, TextTrackMenuItem);

    var track = options['track'];
    var tracks = player.textTracks();

    // Modify options for parent MenuItem class's init.
    options['label'] = track['label'] || track['language'] || 'Unknown';
    options['selected'] = track['default'] || track['mode'] === 'showing';

    _MenuItem.call(this, player, options);

    this.track = track;

    if (tracks) {
      (function () {
        var changeHandler = Fn.bind(_this, _this.handleTracksChange);

        tracks.addEventListener('change', changeHandler);
        _this.on('dispose', function () {
          tracks.removeEventListener('change', changeHandler);
        });
      })();
    }

    // iOS7 doesn't dispatch change events to TextTrackLists when an
    // associated track's mode changes. Without something like
    // Object.observe() (also not present on iOS7), it's not
    // possible to detect changes to the mode attribute and polyfill
    // the change event. As a poor substitute, we manually dispatch
    // change events whenever the controls modify the mode.
    if (tracks && tracks.onchange === undefined) {
      (function () {
        var event = undefined;

        _this.on(['tap', 'click'], function () {
          if (typeof _globalWindow2['default'].Event !== 'object') {
            // Android 2.3 throws an Illegal Constructor error for window.Event
            try {
              event = new _globalWindow2['default'].Event('change');
            } catch (err) {}
          }

          if (!event) {
            event = _globalDocument2['default'].createEvent('Event');
            event.initEvent('change', true, true);
          }

          tracks.dispatchEvent(event);
        });
      })();
    }
  }

  /**
   * Handle click on text track
   *
   * @method handleClick
   */

  TextTrackMenuItem.prototype.handleClick = function handleClick(event) {
    var kind = this.track['kind'];
    var tracks = this.player_.textTracks();

    _MenuItem.prototype.handleClick.call(this, event);

    if (!tracks) return;

    for (var i = 0; i < tracks.length; i++) {
      var track = tracks[i];

      if (track['kind'] !== kind) {
        continue;
      }

      if (track === this.track) {
        track['mode'] = 'showing';
      } else {
        track['mode'] = 'disabled';
      }
    }
  };

  /**
   * Handle text track change
   *
   * @method handleTracksChange
   */

  TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
    this.selected(this.track['mode'] === 'showing');
  };

  return TextTrackMenuItem;
})(_menuMenuItemJs2['default']);

_componentJs2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem);
exports['default'] = TextTrackMenuItem;
module.exports = exports['default'];

},{"../../component.js":67,"../../menu/menu-item.js":105,"../../utils/fn.js":134,"global/document":1,"global/window":2}],90:[function(_dereq_,module,exports){
/**
 * @file current-time-display.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsDomJs = _dereq_('../../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');

var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);

/**
 * Displays the current time
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Component
 * @class CurrentTimeDisplay
 */

var CurrentTimeDisplay = (function (_Component) {
  _inherits(CurrentTimeDisplay, _Component);

  function CurrentTimeDisplay(player, options) {
    _classCallCheck(this, CurrentTimeDisplay);

    _Component.call(this, player, options);

    this.on(player, 'timeupdate', this.updateContent);
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  CurrentTimeDisplay.prototype.createEl = function createEl() {
    var el = _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-current-time vjs-time-control vjs-control'
    });

    this.contentEl_ = Dom.createEl('div', {
      className: 'vjs-current-time-display',
      // label the current time for screen reader users
      innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00'
    }, {
      // tell screen readers not to automatically read the time as it changes
      'aria-live': 'off'
    });

    el.appendChild(this.contentEl_);
    return el;
  };

  /**
   * Update current time display
   *
   * @method updateContent
   */

  CurrentTimeDisplay.prototype.updateContent = function updateContent() {
    // Allows for smooth scrubbing, when player can't keep up.
    var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
    var localizedText = this.localize('Current Time');
    var formattedTime = _utilsFormatTimeJs2['default'](time, this.player_.duration());
    if (formattedTime !== this.formattedTime_) {
      this.formattedTime_ = formattedTime;
      this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
    }
  };

  return CurrentTimeDisplay;
})(_componentJs2['default']);

_componentJs2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
exports['default'] = CurrentTimeDisplay;
module.exports = exports['default'];

},{"../../component.js":67,"../../utils/dom.js":132,"../../utils/format-time.js":135}],91:[function(_dereq_,module,exports){
/**
 * @file duration-display.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsDomJs = _dereq_('../../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');

var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);

/**
 * Displays the duration
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Component
 * @class DurationDisplay
 */

var DurationDisplay = (function (_Component) {
  _inherits(DurationDisplay, _Component);

  function DurationDisplay(player, options) {
    _classCallCheck(this, DurationDisplay);

    _Component.call(this, player, options);

    // this might need to be changed to 'durationchange' instead of 'timeupdate' eventually,
    // however the durationchange event fires before this.player_.duration() is set,
    // so the value cannot be written out using this method.
    // Once the order of durationchange and this.player_.duration() being set is figured out,
    // this can be updated.
    this.on(player, 'timeupdate', this.updateContent);
    this.on(player, 'loadedmetadata', this.updateContent);
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  DurationDisplay.prototype.createEl = function createEl() {
    var el = _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-duration vjs-time-control vjs-control'
    });

    this.contentEl_ = Dom.createEl('div', {
      className: 'vjs-duration-display',
      // label the duration time for screen reader users
      innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00'
    }, {
      // tell screen readers not to automatically read the time as it changes
      'aria-live': 'off'
    });

    el.appendChild(this.contentEl_);
    return el;
  };

  /**
   * Update duration time display
   *
   * @method updateContent
   */

  DurationDisplay.prototype.updateContent = function updateContent() {
    var duration = this.player_.duration();
    if (duration && this.duration_ !== duration) {
      this.duration_ = duration;
      var localizedText = this.localize('Duration Time');
      var formattedTime = _utilsFormatTimeJs2['default'](duration);
      this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime; // label the duration time for screen reader users
    }
  };

  return DurationDisplay;
})(_componentJs2['default']);

_componentJs2['default'].registerComponent('DurationDisplay', DurationDisplay);
exports['default'] = DurationDisplay;
module.exports = exports['default'];

},{"../../component.js":67,"../../utils/dom.js":132,"../../utils/format-time.js":135}],92:[function(_dereq_,module,exports){
/**
 * @file remaining-time-display.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsDomJs = _dereq_('../../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');

var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);

/**
 * Displays the time left in the video
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Component
 * @class RemainingTimeDisplay
 */

var RemainingTimeDisplay = (function (_Component) {
  _inherits(RemainingTimeDisplay, _Component);

  function RemainingTimeDisplay(player, options) {
    _classCallCheck(this, RemainingTimeDisplay);

    _Component.call(this, player, options);

    this.on(player, 'timeupdate', this.updateContent);
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  RemainingTimeDisplay.prototype.createEl = function createEl() {
    var el = _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-remaining-time vjs-time-control vjs-control'
    });

    this.contentEl_ = Dom.createEl('div', {
      className: 'vjs-remaining-time-display',
      // label the remaining time for screen reader users
      innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00'
    }, {
      // tell screen readers not to automatically read the time as it changes
      'aria-live': 'off'
    });

    el.appendChild(this.contentEl_);
    return el;
  };

  /**
   * Update remaining time display
   *
   * @method updateContent
   */

  RemainingTimeDisplay.prototype.updateContent = function updateContent() {
    if (this.player_.duration()) {
      var localizedText = this.localize('Remaining Time');
      var formattedTime = _utilsFormatTimeJs2['default'](this.player_.remainingTime());
      if (formattedTime !== this.formattedTime_) {
        this.formattedTime_ = formattedTime;
        this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime;
      }
    }

    // Allows for smooth scrubbing, when player can't keep up.
    // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
    // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration());
  };

  return RemainingTimeDisplay;
})(_componentJs2['default']);

_componentJs2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
exports['default'] = RemainingTimeDisplay;
module.exports = exports['default'];

},{"../../component.js":67,"../../utils/dom.js":132,"../../utils/format-time.js":135}],93:[function(_dereq_,module,exports){
/**
 * @file time-divider.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

/**
 * The separator between the current time and duration.
 * Can be hidden if it's not needed in the design.
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Component
 * @class TimeDivider
 */

var TimeDivider = (function (_Component) {
  _inherits(TimeDivider, _Component);

  function TimeDivider() {
    _classCallCheck(this, TimeDivider);

    _Component.apply(this, arguments);
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  TimeDivider.prototype.createEl = function createEl() {
    return _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-time-control vjs-time-divider',
      innerHTML: '<div><span>/</span></div>'
    });
  };

  return TimeDivider;
})(_componentJs2['default']);

_componentJs2['default'].registerComponent('TimeDivider', TimeDivider);
exports['default'] = TimeDivider;
module.exports = exports['default'];

},{"../../component.js":67}],94:[function(_dereq_,module,exports){
/**
 * @file volume-bar.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _sliderSliderJs = _dereq_('../../slider/slider.js');

var _sliderSliderJs2 = _interopRequireDefault(_sliderSliderJs);

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsFnJs = _dereq_('../../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

// Required children

var _volumeLevelJs = _dereq_('./volume-level.js');

var _volumeLevelJs2 = _interopRequireDefault(_volumeLevelJs);

/**
 * The bar that contains the volume level and can be clicked on to adjust the level
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Slider
 * @class VolumeBar
 */

var VolumeBar = (function (_Slider) {
  _inherits(VolumeBar, _Slider);

  function VolumeBar(player, options) {
    _classCallCheck(this, VolumeBar);

    _Slider.call(this, player, options);
    this.on(player, 'volumechange', this.updateARIAAttributes);
    player.ready(Fn.bind(this, this.updateARIAAttributes));
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  VolumeBar.prototype.createEl = function createEl() {
    return _Slider.prototype.createEl.call(this, 'div', {
      className: 'vjs-volume-bar vjs-slider-bar'
    }, {
      'aria-label': 'volume level'
    });
  };

  /**
   * Handle mouse move on volume bar
   *
   * @method handleMouseMove
   */

  VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) {
    this.checkMuted();
    this.player_.volume(this.calculateDistance(event));
  };

  VolumeBar.prototype.checkMuted = function checkMuted() {
    if (this.player_.muted()) {
      this.player_.muted(false);
    }
  };

  /**
   * Get percent of volume level
   *
   * @retun {Number} Volume level percent
   * @method getPercent
   */

  VolumeBar.prototype.getPercent = function getPercent() {
    if (this.player_.muted()) {
      return 0;
    } else {
      return this.player_.volume();
    }
  };

  /**
   * Increase volume level for keyboard users
   *
   * @method stepForward
   */

  VolumeBar.prototype.stepForward = function stepForward() {
    this.checkMuted();
    this.player_.volume(this.player_.volume() + 0.1);
  };

  /**
   * Decrease volume level for keyboard users
   *
   * @method stepBack
   */

  VolumeBar.prototype.stepBack = function stepBack() {
    this.checkMuted();
    this.player_.volume(this.player_.volume() - 0.1);
  };

  /**
   * Update ARIA accessibility attributes
   *
   * @method updateARIAAttributes
   */

  VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes() {
    // Current value of volume bar as a percentage
    var volume = (this.player_.volume() * 100).toFixed(2);
    this.el_.setAttribute('aria-valuenow', volume);
    this.el_.setAttribute('aria-valuetext', volume + '%');
  };

  return VolumeBar;
})(_sliderSliderJs2['default']);

VolumeBar.prototype.options_ = {
  children: ['volumeLevel'],
  'barName': 'volumeLevel'
};

VolumeBar.prototype.playerEvent = 'volumechange';

_componentJs2['default'].registerComponent('VolumeBar', VolumeBar);
exports['default'] = VolumeBar;
module.exports = exports['default'];

},{"../../component.js":67,"../../slider/slider.js":114,"../../utils/fn.js":134,"./volume-level.js":96}],95:[function(_dereq_,module,exports){
/**
 * @file volume-control.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

// Required children

var _volumeBarJs = _dereq_('./volume-bar.js');

var _volumeBarJs2 = _interopRequireDefault(_volumeBarJs);

/**
 * The component for controlling the volume level
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Component
 * @class VolumeControl
 */

var VolumeControl = (function (_Component) {
  _inherits(VolumeControl, _Component);

  function VolumeControl(player, options) {
    _classCallCheck(this, VolumeControl);

    _Component.call(this, player, options);

    // hide volume controls when they're not supported by the current tech
    if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
      this.addClass('vjs-hidden');
    }
    this.on(player, 'loadstart', function () {
      if (player.tech_['featuresVolumeControl'] === false) {
        this.addClass('vjs-hidden');
      } else {
        this.removeClass('vjs-hidden');
      }
    });
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  VolumeControl.prototype.createEl = function createEl() {
    return _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-volume-control vjs-control'
    });
  };

  return VolumeControl;
})(_componentJs2['default']);

VolumeControl.prototype.options_ = {
  children: ['volumeBar']
};

_componentJs2['default'].registerComponent('VolumeControl', VolumeControl);
exports['default'] = VolumeControl;
module.exports = exports['default'];

},{"../../component.js":67,"./volume-bar.js":94}],96:[function(_dereq_,module,exports){
/**
 * @file volume-level.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

/**
 * Shows volume level
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Component
 * @class VolumeLevel
 */

var VolumeLevel = (function (_Component) {
  _inherits(VolumeLevel, _Component);

  function VolumeLevel() {
    _classCallCheck(this, VolumeLevel);

    _Component.apply(this, arguments);
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  VolumeLevel.prototype.createEl = function createEl() {
    return _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-volume-level',
      innerHTML: '<span class="vjs-control-text"></span>'
    });
  };

  return VolumeLevel;
})(_componentJs2['default']);

_componentJs2['default'].registerComponent('VolumeLevel', VolumeLevel);
exports['default'] = VolumeLevel;
module.exports = exports['default'];

},{"../../component.js":67}],97:[function(_dereq_,module,exports){
/**
 * @file volume-menu-button.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _utilsFnJs = _dereq_('../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _componentJs = _dereq_('../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _popupPopupJs = _dereq_('../popup/popup.js');

var _popupPopupJs2 = _interopRequireDefault(_popupPopupJs);

var _popupPopupButtonJs = _dereq_('../popup/popup-button.js');

var _popupPopupButtonJs2 = _interopRequireDefault(_popupPopupButtonJs);

var _muteToggleJs = _dereq_('./mute-toggle.js');

var _muteToggleJs2 = _interopRequireDefault(_muteToggleJs);

var _volumeControlVolumeBarJs = _dereq_('./volume-control/volume-bar.js');

var _volumeControlVolumeBarJs2 = _interopRequireDefault(_volumeControlVolumeBarJs);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

/**
 * Button for volume popup
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends PopupButton
 * @class VolumeMenuButton
 */

var VolumeMenuButton = (function (_PopupButton) {
  _inherits(VolumeMenuButton, _PopupButton);

  function VolumeMenuButton(player) {
    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

    _classCallCheck(this, VolumeMenuButton);

    // Default to inline
    if (options.inline === undefined) {
      options.inline = true;
    }

    // If the vertical option isn't passed at all, default to true.
    if (options.vertical === undefined) {
      // If an inline volumeMenuButton is used, we should default to using
      // a horizontal slider for obvious reasons.
      if (options.inline) {
        options.vertical = false;
      } else {
        options.vertical = true;
      }
    }

    // The vertical option needs to be set on the volumeBar as well,
    // since that will need to be passed along to the VolumeBar constructor
    options.volumeBar = options.volumeBar || {};
    options.volumeBar.vertical = !!options.vertical;

    _PopupButton.call(this, player, options);

    // Same listeners as MuteToggle
    this.on(player, 'volumechange', this.volumeUpdate);
    this.on(player, 'loadstart', this.volumeUpdate);

    // hide mute toggle if the current tech doesn't support volume control
    function updateVisibility() {
      if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
        this.addClass('vjs-hidden');
      } else {
        this.removeClass('vjs-hidden');
      }
    }

    updateVisibility.call(this);
    this.on(player, 'loadstart', updateVisibility);

    this.on(this.volumeBar, ['slideractive', 'focus'], function () {
      this.addClass('vjs-slider-active');
    });

    this.on(this.volumeBar, ['sliderinactive', 'blur'], function () {
      this.removeClass('vjs-slider-active');
    });

    this.on(this.volumeBar, ['focus'], function () {
      this.addClass('vjs-lock-showing');
    });

    this.on(this.volumeBar, ['blur'], function () {
      this.removeClass('vjs-lock-showing');
    });
  }

  /**
   * Allow sub components to stack CSS class names
   *
   * @return {String} The constructed class name
   * @method buildCSSClass
   */

  VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() {
    var orientationClass = '';
    if (!!this.options_.vertical) {
      orientationClass = 'vjs-volume-menu-button-vertical';
    } else {
      orientationClass = 'vjs-volume-menu-button-horizontal';
    }

    return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass;
  };

  /**
   * Allow sub components to stack CSS class names
   *
   * @return {Popup} The volume popup button
   * @method createPopup
   */

  VolumeMenuButton.prototype.createPopup = function createPopup() {
    var popup = new _popupPopupJs2['default'](this.player_, {
      contentElType: 'div'
    });

    var vb = new _volumeControlVolumeBarJs2['default'](this.player_, this.options_.volumeBar);

    popup.addChild(vb);

    this.menuContent = popup;
    this.volumeBar = vb;

    this.attachVolumeBarEvents();

    return popup;
  };

  /**
   * Handle click on volume popup and calls super
   *
   * @method handleClick
   */

  VolumeMenuButton.prototype.handleClick = function handleClick() {
    _muteToggleJs2['default'].prototype.handleClick.call(this);
    _PopupButton.prototype.handleClick.call(this);
  };

  VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() {
    this.menuContent.on(['mousedown', 'touchdown'], Fn.bind(this, this.handleMouseDown));
  };

  VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) {
    this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
    this.on(_globalDocument2['default'], ['mouseup', 'touchend'], this.handleMouseUp);
  };

  VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) {
    this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
  };

  return VolumeMenuButton;
})(_popupPopupButtonJs2['default']);

VolumeMenuButton.prototype.volumeUpdate = _muteToggleJs2['default'].prototype.update;
VolumeMenuButton.prototype.controlText_ = 'Mute';

_componentJs2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton);
exports['default'] = VolumeMenuButton;
module.exports = exports['default'];

},{"../component.js":67,"../popup/popup-button.js":110,"../popup/popup.js":111,"../utils/fn.js":134,"./mute-toggle.js":71,"./volume-control/volume-bar.js":94,"global/document":1}],98:[function(_dereq_,module,exports){
/**
 * @file error-display.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _component = _dereq_('./component');

var _component2 = _interopRequireDefault(_component);

var _modalDialog = _dereq_('./modal-dialog');

var _modalDialog2 = _interopRequireDefault(_modalDialog);

var _utilsDom = _dereq_('./utils/dom');

var Dom = _interopRequireWildcard(_utilsDom);

var _utilsMergeOptions = _dereq_('./utils/merge-options');

var _utilsMergeOptions2 = _interopRequireDefault(_utilsMergeOptions);

/**
 * Display that an error has occurred making the video unplayable.
 *
 * @extends ModalDialog
 * @class ErrorDisplay
 */

var ErrorDisplay = (function (_ModalDialog) {
  _inherits(ErrorDisplay, _ModalDialog);

  /**
   * Constructor for error display modal.
   *
   * @param  {Player} player
   * @param  {Object} [options]
   */

  function ErrorDisplay(player, options) {
    _classCallCheck(this, ErrorDisplay);

    _ModalDialog.call(this, player, options);
    this.on(player, 'error', this.open);
  }

  /**
   * Include the old class for backward-compatibility.
   *
   * This can be removed in 6.0.
   *
   * @method buildCSSClass
   * @deprecated
   * @return {String}
   */

  ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() {
    return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this);
  };

  /**
   * Generates the modal content based on the player error.
   *
   * @return {String|Null}
   */

  ErrorDisplay.prototype.content = function content() {
    var error = this.player().error();
    return error ? this.localize(error.message) : '';
  };

  return ErrorDisplay;
})(_modalDialog2['default']);

ErrorDisplay.prototype.options_ = _utilsMergeOptions2['default'](_modalDialog2['default'].prototype.options_, {
  fillAlways: true,
  temporary: false,
  uncloseable: true
});

_component2['default'].registerComponent('ErrorDisplay', ErrorDisplay);
exports['default'] = ErrorDisplay;
module.exports = exports['default'];

},{"./component":67,"./modal-dialog":107,"./utils/dom":132,"./utils/merge-options":138}],99:[function(_dereq_,module,exports){
/**
 * @file event-target.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

var _utilsEventsJs = _dereq_('./utils/events.js');

var Events = _interopRequireWildcard(_utilsEventsJs);

var EventTarget = function EventTarget() {};

EventTarget.prototype.allowedEvents_ = {};

EventTarget.prototype.on = function (type, fn) {
  // Remove the addEventListener alias before calling Events.on
  // so we don't get into an infinite type loop
  var ael = this.addEventListener;
  this.addEventListener = Function.prototype;
  Events.on(this, type, fn);
  this.addEventListener = ael;
};
EventTarget.prototype.addEventListener = EventTarget.prototype.on;

EventTarget.prototype.off = function (type, fn) {
  Events.off(this, type, fn);
};
EventTarget.prototype.removeEventListener = EventTarget.prototype.off;

EventTarget.prototype.one = function (type, fn) {
  Events.one(this, type, fn);
};

EventTarget.prototype.trigger = function (event) {
  var type = event.type || event;

  if (typeof event === 'string') {
    event = {
      type: type
    };
  }
  event = Events.fixEvent(event);

  if (this.allowedEvents_[type] && this['on' + type]) {
    this['on' + type](event);
  }

  Events.trigger(this, event);
};
// The standard DOM EventTarget.dispatchEvent() is aliased to trigger()
EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;

exports['default'] = EventTarget;
module.exports = exports['default'];

},{"./utils/events.js":133}],100:[function(_dereq_,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _utilsLog = _dereq_('./utils/log');

var _utilsLog2 = _interopRequireDefault(_utilsLog);

/*
 * @file extend.js
 *
 * A combination of node inherits and babel's inherits (after transpile).
 * Both work the same but node adds `super_` to the subClass
 * and Bable adds the superClass as __proto__. Both seem useful.
 */
var _inherits = function _inherits(subClass, superClass) {
  if (typeof superClass !== 'function' && superClass !== null) {
    throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
  }

  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: {
      value: subClass,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });

  if (superClass) {
    // node
    subClass.super_ = superClass;
  }
};

/*
 * Function for subclassing using the same inheritance that
 * videojs uses internally
 * ```js
 * var Button = videojs.getComponent('Button');
 * ```
 * ```js
 * var MyButton = videojs.extend(Button, {
 *   constructor: function(player, options) {
 *     Button.call(this, player, options);
 *   },
 *   onClick: function() {
 *     // doSomething
 *   }
 * });
 * ```
 */
var extendFn = function extendFn(superClass) {
  var subClassMethods = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

  var subClass = function subClass() {
    superClass.apply(this, arguments);
  };
  var methods = {};

  if (typeof subClassMethods === 'object') {
    if (typeof subClassMethods.init === 'function') {
      _utilsLog2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.');
      subClassMethods.constructor = subClassMethods.init;
    }
    if (subClassMethods.constructor !== Object.prototype.constructor) {
      subClass = subClassMethods.constructor;
    }
    methods = subClassMethods;
  } else if (typeof subClassMethods === 'function') {
    subClass = subClassMethods;
  }

  _inherits(subClass, superClass);

  // Extend subObj's prototype with functions and other properties from props
  for (var name in methods) {
    if (methods.hasOwnProperty(name)) {
      subClass.prototype[name] = methods[name];
    }
  }

  return subClass;
};

exports['default'] = extendFn;
module.exports = exports['default'];

},{"./utils/log":137}],101:[function(_dereq_,module,exports){
/**
 * @file fullscreen-api.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

/*
 * Store the browser-specific methods for the fullscreen API
 * @type {Object|undefined}
 * @private
 */
var FullscreenApi = {};

// browser API methods
// map approach from Screenful.js - https://github.com/sindresorhus/screenfull.js
var apiMap = [
// Spec: https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'],
// WebKit
['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'],
// Old WebKit (Safari 5.1)
['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'],
// Mozilla
['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'],
// Microsoft
['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']];

var specApi = apiMap[0];
var browserApi = undefined;

// determine the supported set of functions
for (var i = 0; i < apiMap.length; i++) {
  // check for exitFullscreen function
  if (apiMap[i][1] in _globalDocument2['default']) {
    browserApi = apiMap[i];
    break;
  }
}

// map the browser API names to the spec API names
if (browserApi) {
  for (var i = 0; i < browserApi.length; i++) {
    FullscreenApi[specApi[i]] = browserApi[i];
  }
}

exports['default'] = FullscreenApi;
module.exports = exports['default'];

},{"global/document":1}],102:[function(_dereq_,module,exports){
/**
 * @file loading-spinner.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _component = _dereq_('./component');

var _component2 = _interopRequireDefault(_component);

/* Loading Spinner
================================================================================ */
/**
 * Loading spinner for waiting events
 *
 * @extends Component
 * @class LoadingSpinner
 */

var LoadingSpinner = (function (_Component) {
  _inherits(LoadingSpinner, _Component);

  function LoadingSpinner() {
    _classCallCheck(this, LoadingSpinner);

    _Component.apply(this, arguments);
  }

  /**
   * Create the component's DOM element
   *
   * @method createEl
   */

  LoadingSpinner.prototype.createEl = function createEl() {
    return _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-loading-spinner',
      dir: 'ltr'
    });
  };

  return LoadingSpinner;
})(_component2['default']);

_component2['default'].registerComponent('LoadingSpinner', LoadingSpinner);
exports['default'] = LoadingSpinner;
module.exports = exports['default'];

},{"./component":67}],103:[function(_dereq_,module,exports){
/**
 * @file media-error.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _objectAssign = _dereq_('object.assign');

var _objectAssign2 = _interopRequireDefault(_objectAssign);

/*
 * Custom MediaError to mimic the HTML5 MediaError
 *
 * @param {Number} code The media error code
 */
var MediaError = function MediaError(code) {
  if (typeof code === 'number') {
    this.code = code;
  } else if (typeof code === 'string') {
    // default code is zero, so this is a custom error
    this.message = code;
  } else if (typeof code === 'object') {
    // object
    _objectAssign2['default'](this, code);
  }

  if (!this.message) {
    this.message = MediaError.defaultMessages[this.code] || '';
  }
};

/*
 * The error code that refers two one of the defined
 * MediaError types
 *
 * @type {Number}
 */
MediaError.prototype.code = 0;

/*
 * An optional message to be shown with the error.
 * Message is not part of the HTML5 video spec
 * but allows for more informative custom errors.
 *
 * @type {String}
 */
MediaError.prototype.message = '';

/*
 * An optional status code that can be set by plugins
 * to allow even more detail about the error.
 * For example the HLS plugin might provide the specific
 * HTTP status code that was returned when the error
 * occurred, then allowing a custom error overlay
 * to display more information.
 *
 * @type {Array}
 */
MediaError.prototype.status = null;

MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', // = 0
'MEDIA_ERR_ABORTED', // = 1
'MEDIA_ERR_NETWORK', // = 2
'MEDIA_ERR_DECODE', // = 3
'MEDIA_ERR_SRC_NOT_SUPPORTED', // = 4
'MEDIA_ERR_ENCRYPTED' // = 5
];

MediaError.defaultMessages = {
  1: 'You aborted the media playback',
  2: 'A network error caused the media download to fail part-way.',
  3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.',
  4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.',
  5: 'The media is encrypted and we do not have the keys to decrypt it.'
};

// Add types as properties on MediaError
// e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) {
  MediaError[MediaError.errorTypes[errNum]] = errNum;
  // values should be accessible on both the class and instance
  MediaError.prototype[MediaError.errorTypes[errNum]] = errNum;
}

exports['default'] = MediaError;
module.exports = exports['default'];

},{"object.assign":45}],104:[function(_dereq_,module,exports){
/**
 * @file menu-button.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _clickableComponentJs = _dereq_('../clickable-component.js');

var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);

var _componentJs = _dereq_('../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _menuJs = _dereq_('./menu.js');

var _menuJs2 = _interopRequireDefault(_menuJs);

var _utilsDomJs = _dereq_('../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsFnJs = _dereq_('../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js');

var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);

/**
 * A button class with a popup menu
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Button
 * @class MenuButton
 */

var MenuButton = (function (_ClickableComponent) {
  _inherits(MenuButton, _ClickableComponent);

  function MenuButton(player) {
    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

    _classCallCheck(this, MenuButton);

    _ClickableComponent.call(this, player, options);

    this.update();

    this.el_.setAttribute('aria-haspopup', true);
    this.el_.setAttribute('role', 'menuitem');
    this.on('keydown', this.handleSubmenuKeyPress);
  }

  /**
   * Update menu
   *
   * @method update
   */

  MenuButton.prototype.update = function update() {
    var menu = this.createMenu();

    if (this.menu) {
      this.removeChild(this.menu);
    }

    this.menu = menu;
    this.addChild(menu);

    /**
     * Track the state of the menu button
     *
     * @type {Boolean}
     * @private
     */
    this.buttonPressed_ = false;
    this.el_.setAttribute('aria-expanded', false);

    if (this.items && this.items.length === 0) {
      this.hide();
    } else if (this.items && this.items.length > 1) {
      this.show();
    }
  };

  /**
   * Create menu
   *
   * @return {Menu} The constructed menu
   * @method createMenu
   */

  MenuButton.prototype.createMenu = function createMenu() {
    var menu = new _menuJs2['default'](this.player_);

    // Add a title list item to the top
    if (this.options_.title) {
      var title = Dom.createEl('li', {
        className: 'vjs-menu-title',
        innerHTML: _utilsToTitleCaseJs2['default'](this.options_.title),
        tabIndex: -1
      });
      menu.children_.unshift(title);
      Dom.insertElFirst(title, menu.contentEl());
    }

    this.items = this['createItems']();

    if (this.items) {
      // Add menu items to the menu
      for (var i = 0; i < this.items.length; i++) {
        menu.addItem(this.items[i]);
      }
    }

    return menu;
  };

  /**
   * Create the list of menu items. Specific to each subclass.
   *
   * @method createItems
   */

  MenuButton.prototype.createItems = function createItems() {};

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  MenuButton.prototype.createEl = function createEl() {
    return _ClickableComponent.prototype.createEl.call(this, 'div', {
      className: this.buildCSSClass()
    });
  };

  /**
   * Allow sub components to stack CSS class names
   *
   * @return {String} The constructed class name
   * @method buildCSSClass
   */

  MenuButton.prototype.buildCSSClass = function buildCSSClass() {
    var menuButtonClass = 'vjs-menu-button';

    // If the inline option is passed, we want to use different styles altogether.
    if (this.options_.inline === true) {
      menuButtonClass += '-inline';
    } else {
      menuButtonClass += '-popup';
    }

    return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
  };

  /**
   * When you click the button it adds focus, which
   * will show the menu indefinitely.
   * So we'll remove focus when the mouse leaves the button.
   * Focus is needed for tab navigation.
   * Allow sub components to stack CSS class names
   *
   * @method handleClick
   */

  MenuButton.prototype.handleClick = function handleClick() {
    this.one('mouseout', Fn.bind(this, function () {
      this.menu.unlockShowing();
      this.el_.blur();
    }));
    if (this.buttonPressed_) {
      this.unpressButton();
    } else {
      this.pressButton();
    }
  };

  /**
   * Handle key press on menu
   *
   * @param {Object} event Key press event
   * @method handleKeyPress
   */

  MenuButton.prototype.handleKeyPress = function handleKeyPress(event) {

    // Escape (27) key or Tab (9) key unpress the 'button'
    if (event.which === 27 || event.which === 9) {
      if (this.buttonPressed_) {
        this.unpressButton();
      }
      // Don't preventDefault for Tab key - we still want to lose focus
      if (event.which !== 9) {
        event.preventDefault();
      }
      // Up (38) key or Down (40) key press the 'button'
    } else if (event.which === 38 || event.which === 40) {
        if (!this.buttonPressed_) {
          this.pressButton();
          event.preventDefault();
        }
      } else {
        _ClickableComponent.prototype.handleKeyPress.call(this, event);
      }
  };

  /**
   * Handle key press on submenu
   *
   * @param {Object} event Key press event
   * @method handleSubmenuKeyPress
   */

  MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) {

    // Escape (27) key or Tab (9) key unpress the 'button'
    if (event.which === 27 || event.which === 9) {
      if (this.buttonPressed_) {
        this.unpressButton();
      }
      // Don't preventDefault for Tab key - we still want to lose focus
      if (event.which !== 9) {
        event.preventDefault();
      }
    }
  };

  /**
   * Makes changes based on button pressed
   *
   * @method pressButton
   */

  MenuButton.prototype.pressButton = function pressButton() {
    this.buttonPressed_ = true;
    this.menu.lockShowing();
    this.el_.setAttribute('aria-expanded', true);
    this.menu.focus(); // set the focus into the submenu
  };

  /**
   * Makes changes based on button unpressed
   *
   * @method unpressButton
   */

  MenuButton.prototype.unpressButton = function unpressButton() {
    this.buttonPressed_ = false;
    this.menu.unlockShowing();
    this.el_.setAttribute('aria-expanded', false);
    this.el_.focus(); // Set focus back to this menu button
  };

  return MenuButton;
})(_clickableComponentJs2['default']);

_componentJs2['default'].registerComponent('MenuButton', MenuButton);
exports['default'] = MenuButton;
module.exports = exports['default'];

},{"../clickable-component.js":65,"../component.js":67,"../utils/dom.js":132,"../utils/fn.js":134,"../utils/to-title-case.js":141,"./menu.js":106}],105:[function(_dereq_,module,exports){
/**
 * @file menu-item.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _clickableComponentJs = _dereq_('../clickable-component.js');

var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);

var _componentJs = _dereq_('../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _objectAssign = _dereq_('object.assign');

var _objectAssign2 = _interopRequireDefault(_objectAssign);

/**
 * The component for a menu item. `<li>`
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Button
 * @class MenuItem
 */

var MenuItem = (function (_ClickableComponent) {
  _inherits(MenuItem, _ClickableComponent);

  function MenuItem(player, options) {
    _classCallCheck(this, MenuItem);

    _ClickableComponent.call(this, player, options);

    this.selectable = options['selectable'];

    this.selected(options['selected']);

    if (this.selectable) {
      // TODO: May need to be either menuitemcheckbox or menuitemradio,
      //       and may need logical grouping of menu items.
      this.el_.setAttribute('role', 'menuitemcheckbox');
    } else {
      this.el_.setAttribute('role', 'menuitem');
    }
  }

  /**
   * Create the component's DOM element
   *
   * @param {String=} type Desc
   * @param {Object=} props Desc
   * @return {Element}
   * @method createEl
   */

  MenuItem.prototype.createEl = function createEl(type, props, attrs) {
    return _ClickableComponent.prototype.createEl.call(this, 'li', _objectAssign2['default']({
      className: 'vjs-menu-item',
      innerHTML: this.localize(this.options_['label']),
      tabIndex: -1
    }, props), attrs);
  };

  /**
   * Handle a click on the menu item, and set it to selected
   *
   * @method handleClick
   */

  MenuItem.prototype.handleClick = function handleClick() {
    this.selected(true);
  };

  /**
   * Set this menu item as selected or not
   *
   * @param  {Boolean} selected
   * @method selected
   */

  MenuItem.prototype.selected = function selected(_selected) {
    if (this.selectable) {
      if (_selected) {
        this.addClass('vjs-selected');
        this.el_.setAttribute('aria-checked', true);
        // aria-checked isn't fully supported by browsers/screen readers,
        // so indicate selected state to screen reader in the control text.
        this.controlText(', selected');
      } else {
        this.removeClass('vjs-selected');
        this.el_.setAttribute('aria-checked', false);
        // Indicate un-selected state to screen reader
        // Note that a space clears out the selected state text
        this.controlText(' ');
      }
    }
  };

  return MenuItem;
})(_clickableComponentJs2['default']);

_componentJs2['default'].registerComponent('MenuItem', MenuItem);
exports['default'] = MenuItem;
module.exports = exports['default'];

},{"../clickable-component.js":65,"../component.js":67,"object.assign":45}],106:[function(_dereq_,module,exports){
/**
 * @file menu.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsDomJs = _dereq_('../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsFnJs = _dereq_('../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsEventsJs = _dereq_('../utils/events.js');

var Events = _interopRequireWildcard(_utilsEventsJs);

/**
 * The Menu component is used to build pop up menus, including subtitle and
 * captions selection menus.
 *
 * @extends Component
 * @class Menu
 */

var Menu = (function (_Component) {
  _inherits(Menu, _Component);

  function Menu(player, options) {
    _classCallCheck(this, Menu);

    _Component.call(this, player, options);

    this.focusedChild_ = -1;

    this.on('keydown', this.handleKeyPress);
  }

  /**
   * Add a menu item to the menu
   *
   * @param {Object|String} component Component or component type to add
   * @method addItem
   */

  Menu.prototype.addItem = function addItem(component) {
    this.addChild(component);
    component.on('click', Fn.bind(this, function () {
      this.unlockShowing();
      //TODO: Need to set keyboard focus back to the menuButton
    }));
  };

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  Menu.prototype.createEl = function createEl() {
    var contentElType = this.options_.contentElType || 'ul';
    this.contentEl_ = Dom.createEl(contentElType, {
      className: 'vjs-menu-content'
    });
    this.contentEl_.setAttribute('role', 'menu');
    var el = _Component.prototype.createEl.call(this, 'div', {
      append: this.contentEl_,
      className: 'vjs-menu'
    });
    el.setAttribute('role', 'presentation');
    el.appendChild(this.contentEl_);

    // Prevent clicks from bubbling up. Needed for Menu Buttons,
    // where a click on the parent is significant
    Events.on(el, 'click', function (event) {
      event.preventDefault();
      event.stopImmediatePropagation();
    });

    return el;
  };

  /**
   * Handle key press for menu
   *
   * @param {Object} event Event object
   * @method handleKeyPress
   */

  Menu.prototype.handleKeyPress = function handleKeyPress(event) {
    if (event.which === 37 || event.which === 40) {
      // Left and Down Arrows
      event.preventDefault();
      this.stepForward();
    } else if (event.which === 38 || event.which === 39) {
      // Up and Right Arrows
      event.preventDefault();
      this.stepBack();
    }
  };

  /**
   * Move to next (lower) menu item for keyboard users
   *
   * @method stepForward
   */

  Menu.prototype.stepForward = function stepForward() {
    var stepChild = 0;

    if (this.focusedChild_ !== undefined) {
      stepChild = this.focusedChild_ + 1;
    }
    this.focus(stepChild);
  };

  /**
   * Move to previous (higher) menu item for keyboard users
   *
   * @method stepBack
   */

  Menu.prototype.stepBack = function stepBack() {
    var stepChild = 0;

    if (this.focusedChild_ !== undefined) {
      stepChild = this.focusedChild_ - 1;
    }
    this.focus(stepChild);
  };

  /**
   * Set focus on a menu item in the menu
   *
   * @param {Object|String} item Index of child item set focus on
   * @method focus
   */

  Menu.prototype.focus = function focus() {
    var item = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];

    var children = this.children().slice();
    var haveTitle = children.length && children[0].className && /vjs-menu-title/.test(children[0].className);

    if (haveTitle) {
      children.shift();
    }

    if (children.length > 0) {
      if (item < 0) {
        item = 0;
      } else if (item >= children.length) {
        item = children.length - 1;
      }

      this.focusedChild_ = item;

      children[item].el_.focus();
    }
  };

  return Menu;
})(_componentJs2['default']);

_componentJs2['default'].registerComponent('Menu', Menu);
exports['default'] = Menu;
module.exports = exports['default'];

},{"../component.js":67,"../utils/dom.js":132,"../utils/events.js":133,"../utils/fn.js":134}],107:[function(_dereq_,module,exports){
/**
 * @file modal-dialog.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var _utilsDom = _dereq_('./utils/dom');

var Dom = _interopRequireWildcard(_utilsDom);

var _utilsFn = _dereq_('./utils/fn');

var Fn = _interopRequireWildcard(_utilsFn);

var _utilsLog = _dereq_('./utils/log');

var _utilsLog2 = _interopRequireDefault(_utilsLog);

var _component = _dereq_('./component');

var _component2 = _interopRequireDefault(_component);

var _closeButton = _dereq_('./close-button');

var _closeButton2 = _interopRequireDefault(_closeButton);

var MODAL_CLASS_NAME = 'vjs-modal-dialog';
var ESC = 27;

/**
 * The `ModalDialog` displays over the video and its controls, which blocks
 * interaction with the player until it is closed.
 *
 * Modal dialogs include a "Close" button and will close when that button
 * is activated - or when ESC is pressed anywhere.
 *
 * @extends Component
 * @class ModalDialog
 */

var ModalDialog = (function (_Component) {
  _inherits(ModalDialog, _Component);

  /**
   * Constructor for modals.
   *
   * @param  {Player} player
   * @param  {Object} [options]
   * @param  {Mixed} [options.content=undefined]
   *         Provide customized content for this modal.
   *
   * @param  {String} [options.description]
   *         A text description for the modal, primarily for accessibility.
   *
   * @param  {Boolean} [options.fillAlways=false]
   *         Normally, modals are automatically filled only the first time
   *         they open. This tells the modal to refresh its content
   *         every time it opens.
   *
   * @param  {String} [options.label]
   *         A text label for the modal, primarily for accessibility.
   *
   * @param  {Boolean} [options.temporary=true]
   *         If `true`, the modal can only be opened once; it will be
   *         disposed as soon as it's closed.
   *
   * @param  {Boolean} [options.uncloseable=false]
   *         If `true`, the user will not be able to close the modal
   *         through the UI in the normal ways. Programmatic closing is
   *         still possible.
   *
   */

  function ModalDialog(player, options) {
    _classCallCheck(this, ModalDialog);

    _Component.call(this, player, options);
    this.opened_ = this.hasBeenOpened_ = this.hasBeenFilled_ = false;

    this.closeable(!this.options_.uncloseable);
    this.content(this.options_.content);

    // Make sure the contentEl is defined AFTER any children are initialized
    // because we only want the contents of the modal in the contentEl
    // (not the UI elements like the close button).
    this.contentEl_ = Dom.createEl('div', {
      className: MODAL_CLASS_NAME + '-content'
    }, {
      role: 'document'
    });

    this.descEl_ = Dom.createEl('p', {
      className: MODAL_CLASS_NAME + '-description vjs-offscreen',
      id: this.el().getAttribute('aria-describedby')
    });

    Dom.textContent(this.descEl_, this.description());
    this.el_.appendChild(this.descEl_);
    this.el_.appendChild(this.contentEl_);
  }

  /*
   * Modal dialog default options.
   *
   * @type {Object}
   * @private
   */

  /**
   * Create the modal's DOM element
   *
   * @method createEl
   * @return {Element}
   */

  ModalDialog.prototype.createEl = function createEl() {
    return _Component.prototype.createEl.call(this, 'div', {
      className: this.buildCSSClass(),
      tabIndex: -1
    }, {
      'aria-describedby': this.id() + '_description',
      'aria-hidden': 'true',
      'aria-label': this.label(),
      role: 'dialog'
    });
  };

  /**
   * Build the modal's CSS class.
   *
   * @method buildCSSClass
   * @return {String}
   */

  ModalDialog.prototype.buildCSSClass = function buildCSSClass() {
    return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this);
  };

  /**
   * Handles key presses on the document, looking for ESC, which closes
   * the modal.
   *
   * @method handleKeyPress
   * @param  {Event} e
   */

  ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) {
    if (e.which === ESC && this.closeable()) {
      this.close();
    }
  };

  /**
   * Returns the label string for this modal. Primarily used for accessibility.
   *
   * @return {String}
   */

  ModalDialog.prototype.label = function label() {
    return this.options_.label || this.localize('Modal Window');
  };

  /**
   * Returns the description string for this modal. Primarily used for
   * accessibility.
   *
   * @return {String}
   */

  ModalDialog.prototype.description = function description() {
    var desc = this.options_.description || this.localize('This is a modal window.');

    // Append a universal closeability message if the modal is closeable.
    if (this.closeable()) {
      desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.');
    }

    return desc;
  };

  /**
   * Opens the modal.
   *
   * @method open
   * @return {ModalDialog}
   */

  ModalDialog.prototype.open = function open() {
    if (!this.opened_) {
      var player = this.player();

      this.trigger('beforemodalopen');
      this.opened_ = true;

      // Fill content if the modal has never opened before and
      // never been filled.
      if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) {
        this.fill();
      }

      // If the player was playing, pause it and take note of its previously
      // playing state.
      this.wasPlaying_ = !player.paused();

      if (this.wasPlaying_) {
        player.pause();
      }

      if (this.closeable()) {
        this.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
      }

      player.controls(false);
      this.show();
      this.el().setAttribute('aria-hidden', 'false');
      this.trigger('modalopen');
      this.hasBeenOpened_ = true;
    }
    return this;
  };

  /**
   * Whether or not the modal is opened currently.
   *
   * @method opened
   * @param  {Boolean} [value]
   *         If given, it will open (`true`) or close (`false`) the modal.
   *
   * @return {Boolean}
   */

  ModalDialog.prototype.opened = function opened(value) {
    if (typeof value === 'boolean') {
      this[value ? 'open' : 'close']();
    }
    return this.opened_;
  };

  /**
   * Closes the modal.
   *
   * @method close
   * @return {ModalDialog}
   */

  ModalDialog.prototype.close = function close() {
    if (this.opened_) {
      var player = this.player();

      this.trigger('beforemodalclose');
      this.opened_ = false;

      if (this.wasPlaying_) {
        player.play();
      }

      if (this.closeable()) {
        this.off(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
      }

      player.controls(true);
      this.hide();
      this.el().setAttribute('aria-hidden', 'true');
      this.trigger('modalclose');

      if (this.options_.temporary) {
        this.dispose();
      }
    }
    return this;
  };

  /**
   * Whether or not the modal is closeable via the UI.
   *
   * @method closeable
   * @param  {Boolean} [value]
   *         If given as a Boolean, it will set the `closeable` option.
   *
   * @return {Boolean}
   */

  ModalDialog.prototype.closeable = function closeable(value) {
    if (typeof value === 'boolean') {
      var closeable = this.closeable_ = !!value;
      var _close = this.getChild('closeButton');

      // If this is being made closeable and has no close button, add one.
      if (closeable && !_close) {

        // The close button should be a child of the modal - not its
        // content element, so temporarily change the content element.
        var temp = this.contentEl_;
        this.contentEl_ = this.el_;
        _close = this.addChild('closeButton');
        this.contentEl_ = temp;
        this.on(_close, 'close', this.close);
      }

      // If this is being made uncloseable and has a close button, remove it.
      if (!closeable && _close) {
        this.off(_close, 'close', this.close);
        this.removeChild(_close);
        _close.dispose();
      }
    }
    return this.closeable_;
  };

  /**
   * Fill the modal's content element with the modal's "content" option.
   *
   * The content element will be emptied before this change takes place.
   *
   * @method fill
   * @return {ModalDialog}
   */

  ModalDialog.prototype.fill = function fill() {
    return this.fillWith(this.content());
  };

  /**
   * Fill the modal's content element with arbitrary content.
   *
   * The content element will be emptied before this change takes place.
   *
   * @method fillWith
   * @param  {Mixed} [content]
   *         The same rules apply to this as apply to the `content` option.
   *
   * @return {ModalDialog}
   */

  ModalDialog.prototype.fillWith = function fillWith(content) {
    var contentEl = this.contentEl();
    var parentEl = contentEl.parentNode;
    var nextSiblingEl = contentEl.nextSibling;

    this.trigger('beforemodalfill');
    this.hasBeenFilled_ = true;

    // Detach the content element from the DOM before performing
    // manipulation to avoid modifying the live DOM multiple times.
    parentEl.removeChild(contentEl);
    this.empty();
    Dom.insertContent(contentEl, content);
    this.trigger('modalfill');

    // Re-inject the re-filled content element.
    if (nextSiblingEl) {
      parentEl.insertBefore(contentEl, nextSiblingEl);
    } else {
      parentEl.appendChild(contentEl);
    }

    return this;
  };

  /**
   * Empties the content element.
   *
   * This happens automatically anytime the modal is filled.
   *
   * @method empty
   * @return {ModalDialog}
   */

  ModalDialog.prototype.empty = function empty() {
    this.trigger('beforemodalempty');
    Dom.emptyEl(this.contentEl());
    this.trigger('modalempty');
    return this;
  };

  /**
   * Gets or sets the modal content, which gets normalized before being
   * rendered into the DOM.
   *
   * This does not update the DOM or fill the modal, but it is called during
   * that process.
   *
   * @method content
   * @param  {Mixed} [value]
   *         If defined, sets the internal content value to be used on the
   *         next call(s) to `fill`. This value is normalized before being
   *         inserted. To "clear" the internal content value, pass `null`.
   *
   * @return {Mixed}
   */

  ModalDialog.prototype.content = function content(value) {
    if (typeof value !== 'undefined') {
      this.content_ = value;
    }
    return this.content_;
  };

  return ModalDialog;
})(_component2['default']);

ModalDialog.prototype.options_ = {
  temporary: true
};

_component2['default'].registerComponent('ModalDialog', ModalDialog);
exports['default'] = ModalDialog;
module.exports = exports['default'];

},{"./close-button":66,"./component":67,"./utils/dom":132,"./utils/fn":134,"./utils/log":137,"global/document":1}],108:[function(_dereq_,module,exports){
/**
 * @file player.js
 */
// Subclasses Component
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('./component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

var _utilsEventsJs = _dereq_('./utils/events.js');

var Events = _interopRequireWildcard(_utilsEventsJs);

var _utilsDomJs = _dereq_('./utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsFnJs = _dereq_('./utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsGuidJs = _dereq_('./utils/guid.js');

var Guid = _interopRequireWildcard(_utilsGuidJs);

var _utilsBrowserJs = _dereq_('./utils/browser.js');

var browser = _interopRequireWildcard(_utilsBrowserJs);

var _utilsLogJs = _dereq_('./utils/log.js');

var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);

var _utilsToTitleCaseJs = _dereq_('./utils/to-title-case.js');

var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);

var _utilsTimeRangesJs = _dereq_('./utils/time-ranges.js');

var _utilsBufferJs = _dereq_('./utils/buffer.js');

var _utilsStylesheetJs = _dereq_('./utils/stylesheet.js');

var stylesheet = _interopRequireWildcard(_utilsStylesheetJs);

var _fullscreenApiJs = _dereq_('./fullscreen-api.js');

var _fullscreenApiJs2 = _interopRequireDefault(_fullscreenApiJs);

var _mediaErrorJs = _dereq_('./media-error.js');

var _mediaErrorJs2 = _interopRequireDefault(_mediaErrorJs);

var _safeJsonParseTuple = _dereq_('safe-json-parse/tuple');

var _safeJsonParseTuple2 = _interopRequireDefault(_safeJsonParseTuple);

var _objectAssign = _dereq_('object.assign');

var _objectAssign2 = _interopRequireDefault(_objectAssign);

var _utilsMergeOptionsJs = _dereq_('./utils/merge-options.js');

var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);

var _tracksTextTrackListConverterJs = _dereq_('./tracks/text-track-list-converter.js');

var _tracksTextTrackListConverterJs2 = _interopRequireDefault(_tracksTextTrackListConverterJs);

// Include required child components (importing also registers them)

var _techLoaderJs = _dereq_('./tech/loader.js');

var _techLoaderJs2 = _interopRequireDefault(_techLoaderJs);

var _posterImageJs = _dereq_('./poster-image.js');

var _posterImageJs2 = _interopRequireDefault(_posterImageJs);

var _tracksTextTrackDisplayJs = _dereq_('./tracks/text-track-display.js');

var _tracksTextTrackDisplayJs2 = _interopRequireDefault(_tracksTextTrackDisplayJs);

var _loadingSpinnerJs = _dereq_('./loading-spinner.js');

var _loadingSpinnerJs2 = _interopRequireDefault(_loadingSpinnerJs);

var _bigPlayButtonJs = _dereq_('./big-play-button.js');

var _bigPlayButtonJs2 = _interopRequireDefault(_bigPlayButtonJs);

var _controlBarControlBarJs = _dereq_('./control-bar/control-bar.js');

var _controlBarControlBarJs2 = _interopRequireDefault(_controlBarControlBarJs);

var _errorDisplayJs = _dereq_('./error-display.js');

var _errorDisplayJs2 = _interopRequireDefault(_errorDisplayJs);

var _tracksTextTrackSettingsJs = _dereq_('./tracks/text-track-settings.js');

var _tracksTextTrackSettingsJs2 = _interopRequireDefault(_tracksTextTrackSettingsJs);

var _modalDialog = _dereq_('./modal-dialog');

var _modalDialog2 = _interopRequireDefault(_modalDialog);

// Require html5 tech, at least for disposing the original video tag

var _techTechJs = _dereq_('./tech/tech.js');

var _techTechJs2 = _interopRequireDefault(_techTechJs);

var _techHtml5Js = _dereq_('./tech/html5.js');

var _techHtml5Js2 = _interopRequireDefault(_techHtml5Js);

/**
 * An instance of the `Player` class is created when any of the Video.js setup methods are used to initialize a video.
 * ```js
 * var myPlayer = videojs('example_video_1');
 * ```
 * In the following example, the `data-setup` attribute tells the Video.js library to create a player instance when the library is ready.
 * ```html
 * <video id="example_video_1" data-setup='{}' controls>
 *   <source src="my-source.mp4" type="video/mp4">
 * </video>
 * ```
 * After an instance has been created it can be accessed globally using `Video('example_video_1')`.
 *
 * @param {Element} tag        The original video tag used for configuring options
 * @param {Object=} options    Object of option names and values
 * @param {Function=} ready    Ready callback function
 * @extends Component
 * @class Player
 */

var Player = (function (_Component) {
  _inherits(Player, _Component);

  /**
   * player's constructor function
   *
   * @constructs
   * @method init
   * @param {Element} tag        The original video tag used for configuring options
   * @param {Object=} options    Player options
   * @param {Function=} ready    Ready callback function
   */

  function Player(tag, options, ready) {
    var _this = this;

    _classCallCheck(this, Player);

    // Make sure tag ID exists
    tag.id = tag.id || 'vjs_video_' + Guid.newGUID();

    // Set Options
    // The options argument overrides options set in the video tag
    // which overrides globally set options.
    // This latter part coincides with the load order
    // (tag must exist before Player)
    options = _objectAssign2['default'](Player.getTagSettings(tag), options);

    // Delay the initialization of children because we need to set up
    // player properties first, and can't use `this` before `super()`
    options.initChildren = false;

    // Same with creating the element
    options.createEl = false;

    // we don't want the player to report touch activity on itself
    // see enableTouchActivity in Component
    options.reportTouchActivity = false;

    // Run base component initializing with new options
    _Component.call(this, null, options, ready);

    // if the global option object was accidentally blown away by
    // someone, bail early with an informative error
    if (!this.options_ || !this.options_.techOrder || !this.options_.techOrder.length) {
      throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?');
    }

    this.tag = tag; // Store the original tag used to set options

    // Store the tag attributes used to restore html5 element
    this.tagAttributes = tag && Dom.getElAttributes(tag);

    // Update current language
    this.language(this.options_.language);

    // Update Supported Languages
    if (options.languages) {
      (function () {
        // Normalise player option languages to lowercase
        var languagesToLower = {};

        Object.getOwnPropertyNames(options.languages).forEach(function (name) {
          languagesToLower[name.toLowerCase()] = options.languages[name];
        });
        _this.languages_ = languagesToLower;
      })();
    } else {
      this.languages_ = Player.prototype.options_.languages;
    }

    // Cache for video property values.
    this.cache_ = {};

    // Set poster
    this.poster_ = options.poster || '';

    // Set controls
    this.controls_ = !!options.controls;

    // Original tag settings stored in options
    // now remove immediately so native controls don't flash.
    // May be turned back on by HTML5 tech if nativeControlsForTouch is true
    tag.controls = false;

    /*
     * Store the internal state of scrubbing
     *
     * @private
     * @return {Boolean} True if the user is scrubbing
     */
    this.scrubbing_ = false;

    this.el_ = this.createEl();

    // We also want to pass the original player options to each component and plugin
    // as well so they don't need to reach back into the player for options later.
    // We also need to do another copy of this.options_ so we don't end up with
    // an infinite loop.
    var playerOptionsCopy = _utilsMergeOptionsJs2['default'](this.options_);

    // Load plugins
    if (options.plugins) {
      (function () {
        var plugins = options.plugins;

        Object.getOwnPropertyNames(plugins).forEach(function (name) {
          if (typeof this[name] === 'function') {
            this[name](plugins[name]);
          } else {
            _utilsLogJs2['default'].error('Unable to find plugin:', name);
          }
        }, _this);
      })();
    }

    this.options_.playerOptions = playerOptionsCopy;

    this.initChildren();

    // Set isAudio based on whether or not an audio tag was used
    this.isAudio(tag.nodeName.toLowerCase() === 'audio');

    // Update controls className. Can't do this when the controls are initially
    // set because the element doesn't exist yet.
    if (this.controls()) {
      this.addClass('vjs-controls-enabled');
    } else {
      this.addClass('vjs-controls-disabled');
    }

    if (this.isAudio()) {
      this.addClass('vjs-audio');
    }

    if (this.flexNotSupported_()) {
      this.addClass('vjs-no-flex');
    }

    // TODO: Make this smarter. Toggle user state between touching/mousing
    // using events, since devices can have both touch and mouse events.
    // if (browser.TOUCH_ENABLED) {
    //   this.addClass('vjs-touch-enabled');
    // }

    // iOS Safari has broken hover handling
    if (!browser.IS_IOS) {
      this.addClass('vjs-workinghover');
    }

    // Make player easily findable by ID
    Player.players[this.id_] = this;

    // When the player is first initialized, trigger activity so components
    // like the control bar show themselves if needed
    this.userActive(true);
    this.reportUserActivity();
    this.listenForUserActivity_();

    this.on('fullscreenchange', this.handleFullscreenChange_);
    this.on('stageclick', this.handleStageClick_);
  }

  /*
   * Global player list
   *
   * @type {Object}
   */

  /**
   * Destroys the video player and does any necessary cleanup
   * ```js
   *     myPlayer.dispose();
   * ```
   * This is especially helpful if you are dynamically adding and removing videos
   * to/from the DOM.
   *
   * @method dispose
   */

  Player.prototype.dispose = function dispose() {
    this.trigger('dispose');
    // prevent dispose from being called twice
    this.off('dispose');

    if (this.styleEl_ && this.styleEl_.parentNode) {
      this.styleEl_.parentNode.removeChild(this.styleEl_);
    }

    // Kill reference to this player
    Player.players[this.id_] = null;
    if (this.tag && this.tag.player) {
      this.tag.player = null;
    }
    if (this.el_ && this.el_.player) {
      this.el_.player = null;
    }

    if (this.tech_) {
      this.tech_.dispose();
    }

    _Component.prototype.dispose.call(this);
  };

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  Player.prototype.createEl = function createEl() {
    var el = this.el_ = _Component.prototype.createEl.call(this, 'div');
    var tag = this.tag;

    // Remove width/height attrs from tag so CSS can make it 100% width/height
    tag.removeAttribute('width');
    tag.removeAttribute('height');

    // Copy over all the attributes from the tag, including ID and class
    // ID will now reference player box, not the video tag
    var attrs = Dom.getElAttributes(tag);

    Object.getOwnPropertyNames(attrs).forEach(function (attr) {
      // workaround so we don't totally break IE7
      // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7
      if (attr === 'class') {
        el.className = attrs[attr];
      } else {
        el.setAttribute(attr, attrs[attr]);
      }
    });

    // Update tag id/class for use as HTML5 playback tech
    // Might think we should do this after embedding in container so .vjs-tech class
    // doesn't flash 100% width/height, but class only applies with .video-js parent
    tag.playerId = tag.id;
    tag.id += '_html5_api';
    tag.className = 'vjs-tech';

    // Make player findable on elements
    tag.player = el.player = this;
    // Default state of video is paused
    this.addClass('vjs-paused');

    // Add a style element in the player that we'll use to set the width/height
    // of the player in a way that's still overrideable by CSS, just like the
    // video element
    this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions');
    var defaultsStyleEl = Dom.$('.vjs-styles-defaults');
    var head = Dom.$('head');
    head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild);

    // Pass in the width/height/aspectRatio options which will update the style el
    this.width(this.options_.width);
    this.height(this.options_.height);
    this.fluid(this.options_.fluid);
    this.aspectRatio(this.options_.aspectRatio);

    // insertElFirst seems to cause the networkState to flicker from 3 to 2, so
    // keep track of the original for later so we can know if the source originally failed
    tag.initNetworkState_ = tag.networkState;

    // Wrap video tag in div (el/box) container
    if (tag.parentNode) {
      tag.parentNode.insertBefore(el, tag);
    }

    // insert the tag as the first child of the player element
    // then manually add it to the children array so that this.addChild
    // will work properly for other components
    Dom.insertElFirst(tag, el); // Breaks iPhone, fixed in HTML5 setup.
    this.children_.unshift(tag);

    this.el_ = el;

    return el;
  };

  /**
   * Get/set player width
   *
   * @param {Number=} value Value for width
   * @return {Number} Width when getting
   * @method width
   */

  Player.prototype.width = function width(value) {
    return this.dimension('width', value);
  };

  /**
   * Get/set player height
   *
   * @param {Number=} value Value for height
   * @return {Number} Height when getting
   * @method height
   */

  Player.prototype.height = function height(value) {
    return this.dimension('height', value);
  };

  /**
   * Get/set dimension for player
   *
   * @param {String} dimension Either width or height
   * @param {Number=} value Value for dimension
   * @return {Component}
   * @method dimension
   */

  Player.prototype.dimension = function dimension(_dimension, value) {
    var privDimension = _dimension + '_';

    if (value === undefined) {
      return this[privDimension] || 0;
    }

    if (value === '') {
      // If an empty string is given, reset the dimension to be automatic
      this[privDimension] = undefined;
    } else {
      var parsedVal = parseFloat(value);

      if (isNaN(parsedVal)) {
        _utilsLogJs2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension);
        return this;
      }

      this[privDimension] = parsedVal;
    }

    this.updateStyleEl_();
    return this;
  };

  /**
   * Add/remove the vjs-fluid class
   *
   * @param {Boolean} bool Value of true adds the class, value of false removes the class
   * @method fluid
   */

  Player.prototype.fluid = function fluid(bool) {
    if (bool === undefined) {
      return !!this.fluid_;
    }

    this.fluid_ = !!bool;

    if (bool) {
      this.addClass('vjs-fluid');
    } else {
      this.removeClass('vjs-fluid');
    }
  };

  /**
   * Get/Set the aspect ratio
   *
   * @param {String=} ratio Aspect ratio for player
   * @return aspectRatio
   * @method aspectRatio
   */

  Player.prototype.aspectRatio = function aspectRatio(ratio) {
    if (ratio === undefined) {
      return this.aspectRatio_;
    }

    // Check for width:height format
    if (!/^\d+\:\d+$/.test(ratio)) {
      throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.');
    }
    this.aspectRatio_ = ratio;

    // We're assuming if you set an aspect ratio you want fluid mode,
    // because in fixed mode you could calculate width and height yourself.
    this.fluid(true);

    this.updateStyleEl_();
  };

  /**
   * Update styles of the player element (height, width and aspect ratio)
   *
   * @method updateStyleEl_
   */

  Player.prototype.updateStyleEl_ = function updateStyleEl_() {
    var width = undefined;
    var height = undefined;
    var aspectRatio = undefined;
    var idClass = undefined;

    // The aspect ratio is either used directly or to calculate width and height.
    if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') {
      // Use any aspectRatio that's been specifically set
      aspectRatio = this.aspectRatio_;
    } else if (this.videoWidth()) {
      // Otherwise try to get the aspect ratio from the video metadata
      aspectRatio = this.videoWidth() + ':' + this.videoHeight();
    } else {
      // Or use a default. The video element's is 2:1, but 16:9 is more common.
      aspectRatio = '16:9';
    }

    // Get the ratio as a decimal we can use to calculate dimensions
    var ratioParts = aspectRatio.split(':');
    var ratioMultiplier = ratioParts[1] / ratioParts[0];

    if (this.width_ !== undefined) {
      // Use any width that's been specifically set
      width = this.width_;
    } else if (this.height_ !== undefined) {
      // Or calulate the width from the aspect ratio if a height has been set
      width = this.height_ / ratioMultiplier;
    } else {
      // Or use the video's metadata, or use the video el's default of 300
      width = this.videoWidth() || 300;
    }

    if (this.height_ !== undefined) {
      // Use any height that's been specifically set
      height = this.height_;
    } else {
      // Otherwise calculate the height from the ratio and the width
      height = width * ratioMultiplier;
    }

    // Ensure the CSS class is valid by starting with an alpha character
    if (/^[^a-zA-Z]/.test(this.id())) {
      idClass = 'dimensions-' + this.id();
    } else {
      idClass = this.id() + '-dimensions';
    }

    // Ensure the right class is still on the player for the style element
    this.addClass(idClass);

    stylesheet.setTextContent(this.styleEl_, '\n      .' + idClass + ' {\n        width: ' + width + 'px;\n        height: ' + height + 'px;\n      }\n\n      .' + idClass + '.vjs-fluid {\n        padding-top: ' + ratioMultiplier * 100 + '%;\n      }\n    ');
  };

  /**
   * Load the Media Playback Technology (tech)
   * Load/Create an instance of playback technology including element and API methods
   * And append playback element in player div.
   *
   * @param {String} techName Name of the playback technology
   * @param {String} source Video source
   * @method loadTech_
   * @private
   */

  Player.prototype.loadTech_ = function loadTech_(techName, source) {

    // Pause and remove current playback technology
    if (this.tech_) {
      this.unloadTech_();
    }

    // get rid of the HTML5 video tag as soon as we are using another tech
    if (techName !== 'Html5' && this.tag) {
      _techTechJs2['default'].getTech('Html5').disposeMediaElement(this.tag);
      this.tag.player = null;
      this.tag = null;
    }

    this.techName_ = techName;

    // Turn off API access because we're loading a new tech that might load asynchronously
    this.isReady_ = false;

    // Grab tech-specific options from player options and add source and parent element to use.
    var techOptions = _objectAssign2['default']({
      'nativeControlsForTouch': this.options_.nativeControlsForTouch,
      'source': source,
      'playerId': this.id(),
      'techId': this.id() + '_' + techName + '_api',
      'textTracks': this.textTracks_,
      'autoplay': this.options_.autoplay,
      'preload': this.options_.preload,
      'loop': this.options_.loop,
      'muted': this.options_.muted,
      'poster': this.poster(),
      'language': this.language(),
      'vtt.js': this.options_['vtt.js']
    }, this.options_[techName.toLowerCase()]);

    if (this.tag) {
      techOptions.tag = this.tag;
    }

    if (source) {
      this.currentType_ = source.type;
      if (source.src === this.cache_.src && this.cache_.currentTime > 0) {
        techOptions.startTime = this.cache_.currentTime;
      }

      this.cache_.src = source.src;
    }

    // Initialize tech instance
    var techComponent = _techTechJs2['default'].getTech(techName);
    // Support old behavior of techs being registered as components.
    // Remove once that deprecated behavior is removed.
    if (!techComponent) {
      techComponent = _componentJs2['default'].getComponent(techName);
    }
    this.tech_ = new techComponent(techOptions);

    // player.triggerReady is always async, so don't need this to be async
    this.tech_.ready(Fn.bind(this, this.handleTechReady_), true);

    _tracksTextTrackListConverterJs2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_);

    // Listen to all HTML5-defined events and trigger them on the player
    this.on(this.tech_, 'loadstart', this.handleTechLoadStart_);
    this.on(this.tech_, 'waiting', this.handleTechWaiting_);
    this.on(this.tech_, 'canplay', this.handleTechCanPlay_);
    this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_);
    this.on(this.tech_, 'playing', this.handleTechPlaying_);
    this.on(this.tech_, 'ended', this.handleTechEnded_);
    this.on(this.tech_, 'seeking', this.handleTechSeeking_);
    this.on(this.tech_, 'seeked', this.handleTechSeeked_);
    this.on(this.tech_, 'play', this.handleTechPlay_);
    this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_);
    this.on(this.tech_, 'pause', this.handleTechPause_);
    this.on(this.tech_, 'progress', this.handleTechProgress_);
    this.on(this.tech_, 'durationchange', this.handleTechDurationChange_);
    this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_);
    this.on(this.tech_, 'error', this.handleTechError_);
    this.on(this.tech_, 'suspend', this.handleTechSuspend_);
    this.on(this.tech_, 'abort', this.handleTechAbort_);
    this.on(this.tech_, 'emptied', this.handleTechEmptied_);
    this.on(this.tech_, 'stalled', this.handleTechStalled_);
    this.on(this.tech_, 'loadedmetadata', this.handleTechLoadedMetaData_);
    this.on(this.tech_, 'loadeddata', this.handleTechLoadedData_);
    this.on(this.tech_, 'timeupdate', this.handleTechTimeUpdate_);
    this.on(this.tech_, 'ratechange', this.handleTechRateChange_);
    this.on(this.tech_, 'volumechange', this.handleTechVolumeChange_);
    this.on(this.tech_, 'texttrackchange', this.handleTechTextTrackChange_);
    this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_);
    this.on(this.tech_, 'posterchange', this.handleTechPosterChange_);

    this.usingNativeControls(this.techGet_('controls'));

    if (this.controls() && !this.usingNativeControls()) {
      this.addTechControlsListeners_();
    }

    // Add the tech element in the DOM if it was not already there
    // Make sure to not insert the original video element if using Html5
    if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) {
      Dom.insertElFirst(this.tech_.el(), this.el());
    }

    // Get rid of the original video tag reference after the first tech is loaded
    if (this.tag) {
      this.tag.player = null;
      this.tag = null;
    }
  };

  /**
   * Unload playback technology
   *
   * @method unloadTech_
   * @private
   */

  Player.prototype.unloadTech_ = function unloadTech_() {
    // Save the current text tracks so that we can reuse the same text tracks with the next tech
    this.textTracks_ = this.textTracks();
    this.textTracksJson_ = _tracksTextTrackListConverterJs2['default'].textTracksToJson(this.tech_);

    this.isReady_ = false;

    this.tech_.dispose();

    this.tech_ = false;
  };

  /**
   * Return a reference to the current tech.
   * It will only return a reference to the tech if given an object with the
   * `IWillNotUseThisInPlugins` property on it. This is try and prevent misuse
   * of techs by plugins.
   *
   * @param {Object}
   * @return {Object} The Tech
   * @method tech
   */

  Player.prototype.tech = function tech(safety) {
    if (safety && safety.IWillNotUseThisInPlugins) {
      return this.tech_;
    }
    var errorText = '\n      Please make sure that you are not using this inside of a plugin.\n      To disable this alert and error, please pass in an object with\n      `IWillNotUseThisInPlugins` to the `tech` method. See\n      https://github.com/videojs/video.js/issues/2617 for more info.\n    ';
    _globalWindow2['default'].alert(errorText);
    throw new Error(errorText);
  };

  /**
   * Set up click and touch listeners for the playback element
   *
   * On desktops, a click on the video itself will toggle playback,
   * on a mobile device a click on the video toggles controls.
   * (toggling controls is done by toggling the user state between active and
   * inactive)
   * A tap can signal that a user has become active, or has become inactive
   * e.g. a quick tap on an iPhone movie should reveal the controls. Another
   * quick tap should hide them again (signaling the user is in an inactive
   * viewing state)
   * In addition to this, we still want the user to be considered inactive after
   * a few seconds of inactivity.
   * Note: the only part of iOS interaction we can't mimic with this setup
   * is a touch and hold on the video element counting as activity in order to
   * keep the controls showing, but that shouldn't be an issue. A touch and hold
   * on any controls will still keep the user active
   *
   * @private
   * @method addTechControlsListeners_
   */

  Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() {
    // Make sure to remove all the previous listeners in case we are called multiple times.
    this.removeTechControlsListeners_();

    // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
    // trigger mousedown/up.
    // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object
    // Any touch events are set to block the mousedown event from happening
    this.on(this.tech_, 'mousedown', this.handleTechClick_);

    // If the controls were hidden we don't want that to change without a tap event
    // so we'll check if the controls were already showing before reporting user
    // activity
    this.on(this.tech_, 'touchstart', this.handleTechTouchStart_);
    this.on(this.tech_, 'touchmove', this.handleTechTouchMove_);
    this.on(this.tech_, 'touchend', this.handleTechTouchEnd_);

    // The tap listener needs to come after the touchend listener because the tap
    // listener cancels out any reportedUserActivity when setting userActive(false)
    this.on(this.tech_, 'tap', this.handleTechTap_);
  };

  /**
   * Remove the listeners used for click and tap controls. This is needed for
   * toggling to controls disabled, where a tap/touch should do nothing.
   *
   * @method removeTechControlsListeners_
   * @private
   */

  Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() {
    // We don't want to just use `this.off()` because there might be other needed
    // listeners added by techs that extend this.
    this.off(this.tech_, 'tap', this.handleTechTap_);
    this.off(this.tech_, 'touchstart', this.handleTechTouchStart_);
    this.off(this.tech_, 'touchmove', this.handleTechTouchMove_);
    this.off(this.tech_, 'touchend', this.handleTechTouchEnd_);
    this.off(this.tech_, 'mousedown', this.handleTechClick_);
  };

  /**
   * Player waits for the tech to be ready
   *
   * @method handleTechReady_
   * @private
   */

  Player.prototype.handleTechReady_ = function handleTechReady_() {
    this.triggerReady();

    // Keep the same volume as before
    if (this.cache_.volume) {
      this.techCall_('setVolume', this.cache_.volume);
    }

    // Look if the tech found a higher resolution poster while loading
    this.handleTechPosterChange_();

    // Update the duration if available
    this.handleTechDurationChange_();

    // Chrome and Safari both have issues with autoplay.
    // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
    // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
    // This fixes both issues. Need to wait for API, so it updates displays correctly
    if (this.src() && this.tag && this.options_.autoplay && this.paused()) {
      delete this.tag.poster; // Chrome Fix. Fixed in Chrome v16.
      this.play();
    }
  };

  /**
   * Fired when the user agent begins looking for media data
   *
   * @private
   * @method handleTechLoadStart_
   */

  Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() {
    // TODO: Update to use `emptied` event instead. See #1277.

    this.removeClass('vjs-ended');

    // reset the error state
    this.error(null);

    // If it's already playing we want to trigger a firstplay event now.
    // The firstplay event relies on both the play and loadstart events
    // which can happen in any order for a new source
    if (!this.paused()) {
      this.trigger('loadstart');
      this.trigger('firstplay');
    } else {
      // reset the hasStarted state
      this.hasStarted(false);
      this.trigger('loadstart');
    }
  };

  /**
   * Add/remove the vjs-has-started class
   *
   * @param {Boolean} hasStarted The value of true adds the class the value of false remove the class
   * @return {Boolean} Boolean value if has started
   * @private
   * @method hasStarted
   */

  Player.prototype.hasStarted = function hasStarted(_hasStarted) {
    if (_hasStarted !== undefined) {
      // only update if this is a new value
      if (this.hasStarted_ !== _hasStarted) {
        this.hasStarted_ = _hasStarted;
        if (_hasStarted) {
          this.addClass('vjs-has-started');
          // trigger the firstplay event if this newly has played
          this.trigger('firstplay');
        } else {
          this.removeClass('vjs-has-started');
        }
      }
      return this;
    }
    return !!this.hasStarted_;
  };

  /**
   * Fired whenever the media begins or resumes playback
   *
   * @private
   * @method handleTechPlay_
   */

  Player.prototype.handleTechPlay_ = function handleTechPlay_() {
    this.removeClass('vjs-ended');
    this.removeClass('vjs-paused');
    this.addClass('vjs-playing');

    // hide the poster when the user hits play
    // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play
    this.hasStarted(true);

    this.trigger('play');
  };

  /**
   * Fired whenever the media begins waiting
   *
   * @private
   * @method handleTechWaiting_
   */

  Player.prototype.handleTechWaiting_ = function handleTechWaiting_() {
    var _this2 = this;

    this.addClass('vjs-waiting');
    this.trigger('waiting');
    this.one('timeupdate', function () {
      return _this2.removeClass('vjs-waiting');
    });
  };

  /**
   * A handler for events that signal that waiting has ended
   * which is not consistent between browsers. See #1351
   *
   * @private
   * @method handleTechCanPlay_
   */

  Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() {
    this.removeClass('vjs-waiting');
    this.trigger('canplay');
  };

  /**
   * A handler for events that signal that waiting has ended
   * which is not consistent between browsers. See #1351
   *
   * @private
   * @method handleTechCanPlayThrough_
   */

  Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() {
    this.removeClass('vjs-waiting');
    this.trigger('canplaythrough');
  };

  /**
   * A handler for events that signal that waiting has ended
   * which is not consistent between browsers. See #1351
   *
   * @private
   * @method handleTechPlaying_
   */

  Player.prototype.handleTechPlaying_ = function handleTechPlaying_() {
    this.removeClass('vjs-waiting');
    this.trigger('playing');
  };

  /**
   * Fired whenever the player is jumping to a new time
   *
   * @private
   * @method handleTechSeeking_
   */

  Player.prototype.handleTechSeeking_ = function handleTechSeeking_() {
    this.addClass('vjs-seeking');
    this.trigger('seeking');
  };

  /**
   * Fired when the player has finished jumping to a new time
   *
   * @private
   * @method handleTechSeeked_
   */

  Player.prototype.handleTechSeeked_ = function handleTechSeeked_() {
    this.removeClass('vjs-seeking');
    this.trigger('seeked');
  };

  /**
   * Fired the first time a video is played
   * Not part of the HLS spec, and we're not sure if this is the best
   * implementation yet, so use sparingly. If you don't have a reason to
   * prevent playback, use `myPlayer.one('play');` instead.
   *
   * @private
   * @method handleTechFirstPlay_
   */

  Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() {
    //If the first starttime attribute is specified
    //then we will start at the given offset in seconds
    if (this.options_.starttime) {
      this.currentTime(this.options_.starttime);
    }

    this.addClass('vjs-has-started');
    this.trigger('firstplay');
  };

  /**
   * Fired whenever the media has been paused
   *
   * @private
   * @method handleTechPause_
   */

  Player.prototype.handleTechPause_ = function handleTechPause_() {
    this.removeClass('vjs-playing');
    this.addClass('vjs-paused');
    this.trigger('pause');
  };

  /**
   * Fired while the user agent is downloading media data
   *
   * @private
   * @method handleTechProgress_
   */

  Player.prototype.handleTechProgress_ = function handleTechProgress_() {
    this.trigger('progress');
  };

  /**
   * Fired when the end of the media resource is reached (currentTime == duration)
   *
   * @private
   * @method handleTechEnded_
   */

  Player.prototype.handleTechEnded_ = function handleTechEnded_() {
    this.addClass('vjs-ended');
    if (this.options_.loop) {
      this.currentTime(0);
      this.play();
    } else if (!this.paused()) {
      this.pause();
    }

    this.trigger('ended');
  };

  /**
   * Fired when the duration of the media resource is first known or changed
   *
   * @private
   * @method handleTechDurationChange_
   */

  Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() {
    this.duration(this.techGet_('duration'));
  };

  /**
   * Handle a click on the media element to play/pause
   *
   * @param {Object=} event Event object
   * @private
   * @method handleTechClick_
   */

  Player.prototype.handleTechClick_ = function handleTechClick_(event) {
    // We're using mousedown to detect clicks thanks to Flash, but mousedown
    // will also be triggered with right-clicks, so we need to prevent that
    if (event.button !== 0) return;

    // When controls are disabled a click should not toggle playback because
    // the click is considered a control
    if (this.controls()) {
      if (this.paused()) {
        this.play();
      } else {
        this.pause();
      }
    }
  };

  /**
   * Handle a tap on the media element. It will toggle the user
   * activity state, which hides and shows the controls.
   *
   * @private
   * @method handleTechTap_
   */

  Player.prototype.handleTechTap_ = function handleTechTap_() {
    this.userActive(!this.userActive());
  };

  /**
   * Handle touch to start
   *
   * @private
   * @method handleTechTouchStart_
   */

  Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() {
    this.userWasActive = this.userActive();
  };

  /**
   * Handle touch to move
   *
   * @private
   * @method handleTechTouchMove_
   */

  Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() {
    if (this.userWasActive) {
      this.reportUserActivity();
    }
  };

  /**
   * Handle touch to end
   *
   * @private
   * @method handleTechTouchEnd_
   */

  Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) {
    // Stop the mouse events from also happening
    event.preventDefault();
  };

  /**
   * Fired when the player switches in or out of fullscreen mode
   *
   * @private
   * @method handleFullscreenChange_
   */

  Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() {
    if (this.isFullscreen()) {
      this.addClass('vjs-fullscreen');
    } else {
      this.removeClass('vjs-fullscreen');
    }
  };

  /**
   * native click events on the SWF aren't triggered on IE11, Win8.1RT
   * use stageclick events triggered from inside the SWF instead
   *
   * @private
   * @method handleStageClick_
   */

  Player.prototype.handleStageClick_ = function handleStageClick_() {
    this.reportUserActivity();
  };

  /**
   * Handle Tech Fullscreen Change
   *
   * @private
   * @method handleTechFullscreenChange_
   */

  Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) {
    if (data) {
      this.isFullscreen(data.isFullscreen);
    }
    this.trigger('fullscreenchange');
  };

  /**
   * Fires when an error occurred during the loading of an audio/video
   *
   * @private
   * @method handleTechError_
   */

  Player.prototype.handleTechError_ = function handleTechError_() {
    var error = this.tech_.error();
    this.error(error && error.code);
  };

  /**
   * Fires when the browser is intentionally not getting media data
   *
   * @private
   * @method handleTechSuspend_
   */

  Player.prototype.handleTechSuspend_ = function handleTechSuspend_() {
    this.trigger('suspend');
  };

  /**
   * Fires when the loading of an audio/video is aborted
   *
   * @private
   * @method handleTechAbort_
   */

  Player.prototype.handleTechAbort_ = function handleTechAbort_() {
    this.trigger('abort');
  };

  /**
   * Fires when the current playlist is empty
   *
   * @private
   * @method handleTechEmptied_
   */

  Player.prototype.handleTechEmptied_ = function handleTechEmptied_() {
    this.trigger('emptied');
  };

  /**
   * Fires when the browser is trying to get media data, but data is not available
   *
   * @private
   * @method handleTechStalled_
   */

  Player.prototype.handleTechStalled_ = function handleTechStalled_() {
    this.trigger('stalled');
  };

  /**
   * Fires when the browser has loaded meta data for the audio/video
   *
   * @private
   * @method handleTechLoadedMetaData_
   */

  Player.prototype.handleTechLoadedMetaData_ = function handleTechLoadedMetaData_() {
    this.trigger('loadedmetadata');
  };

  /**
   * Fires when the browser has loaded the current frame of the audio/video
   *
   * @private
   * @method handleTechLoadedData_
   */

  Player.prototype.handleTechLoadedData_ = function handleTechLoadedData_() {
    this.trigger('loadeddata');
  };

  /**
   * Fires when the current playback position has changed
   *
   * @private
   * @method handleTechTimeUpdate_
   */

  Player.prototype.handleTechTimeUpdate_ = function handleTechTimeUpdate_() {
    this.trigger('timeupdate');
  };

  /**
   * Fires when the playing speed of the audio/video is changed
   *
   * @private
   * @method handleTechRateChange_
   */

  Player.prototype.handleTechRateChange_ = function handleTechRateChange_() {
    this.trigger('ratechange');
  };

  /**
   * Fires when the volume has been changed
   *
   * @private
   * @method handleTechVolumeChange_
   */

  Player.prototype.handleTechVolumeChange_ = function handleTechVolumeChange_() {
    this.trigger('volumechange');
  };

  /**
   * Fires when the text track has been changed
   *
   * @private
   * @method handleTechTextTrackChange_
   */

  Player.prototype.handleTechTextTrackChange_ = function handleTechTextTrackChange_() {
    this.trigger('texttrackchange');
  };

  /**
   * Get object for cached values.
   *
   * @return {Object}
   * @method getCache
   */

  Player.prototype.getCache = function getCache() {
    return this.cache_;
  };

  /**
   * Pass values to the playback tech
   *
   * @param {String=} method Method
   * @param {Object=} arg Argument
   * @private
   * @method techCall_
   */

  Player.prototype.techCall_ = function techCall_(method, arg) {
    // If it's not ready yet, call method when it is
    if (this.tech_ && !this.tech_.isReady_) {
      this.tech_.ready(function () {
        this[method](arg);
      }, true);

      // Otherwise call method now
    } else {
        try {
          this.tech_[method](arg);
        } catch (e) {
          _utilsLogJs2['default'](e);
          throw e;
        }
      }
  };

  /**
   * Get calls can't wait for the tech, and sometimes don't need to.
   *
   * @param {String} method Tech method
   * @return {Method}
   * @private
   * @method techGet_
   */

  Player.prototype.techGet_ = function techGet_(method) {
    if (this.tech_ && this.tech_.isReady_) {

      // Flash likes to die and reload when you hide or reposition it.
      // In these cases the object methods go away and we get errors.
      // When that happens we'll catch the errors and inform tech that it's not ready any more.
      try {
        return this.tech_[method]();
      } catch (e) {
        // When building additional tech libs, an expected method may not be defined yet
        if (this.tech_[method] === undefined) {
          _utilsLogJs2['default']('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e);
        } else {
          // When a method isn't available on the object it throws a TypeError
          if (e.name === 'TypeError') {
            _utilsLogJs2['default']('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e);
            this.tech_.isReady_ = false;
          } else {
            _utilsLogJs2['default'](e);
          }
        }
        throw e;
      }
    }

    return;
  };

  /**
   * start media playback
   * ```js
   *     myPlayer.play();
   * ```
   *
   * @return {Player} self
   * @method play
   */

  Player.prototype.play = function play() {
    this.techCall_('play');
    return this;
  };

  /**
   * Pause the video playback
   * ```js
   *     myPlayer.pause();
   * ```
   *
   * @return {Player} self
   * @method pause
   */

  Player.prototype.pause = function pause() {
    this.techCall_('pause');
    return this;
  };

  /**
   * Check if the player is paused
   * ```js
   *     var isPaused = myPlayer.paused();
   *     var isPlaying = !myPlayer.paused();
   * ```
   *
   * @return {Boolean} false if the media is currently playing, or true otherwise
   * @method paused
   */

  Player.prototype.paused = function paused() {
    // The initial state of paused should be true (in Safari it's actually false)
    return this.techGet_('paused') === false ? false : true;
  };

  /**
   * Returns whether or not the user is "scrubbing". Scrubbing is when the user
   * has clicked the progress bar handle and is dragging it along the progress bar.
   *
   * @param  {Boolean} isScrubbing   True/false the user is scrubbing
   * @return {Boolean}               The scrubbing status when getting
   * @return {Object}                The player when setting
   * @method scrubbing
   */

  Player.prototype.scrubbing = function scrubbing(isScrubbing) {
    if (isScrubbing !== undefined) {
      this.scrubbing_ = !!isScrubbing;

      if (isScrubbing) {
        this.addClass('vjs-scrubbing');
      } else {
        this.removeClass('vjs-scrubbing');
      }

      return this;
    }

    return this.scrubbing_;
  };

  /**
   * Get or set the current time (in seconds)
   * ```js
   *     // get
   *     var whereYouAt = myPlayer.currentTime();
   *     // set
   *     myPlayer.currentTime(120); // 2 minutes into the video
   * ```
   *
   * @param  {Number|String=} seconds The time to seek to
   * @return {Number}        The time in seconds, when not setting
   * @return {Player}    self, when the current time is set
   * @method currentTime
   */

  Player.prototype.currentTime = function currentTime(seconds) {
    if (seconds !== undefined) {

      this.techCall_('setCurrentTime', seconds);

      return this;
    }

    // cache last currentTime and return. default to 0 seconds
    //
    // Caching the currentTime is meant to prevent a massive amount of reads on the tech's
    // currentTime when scrubbing, but may not provide much performance benefit afterall.
    // Should be tested. Also something has to read the actual current time or the cache will
    // never get updated.
    return this.cache_.currentTime = this.techGet_('currentTime') || 0;
  };

  /**
   * Get the length in time of the video in seconds
   * ```js
   *     var lengthOfVideo = myPlayer.duration();
   * ```
   * **NOTE**: The video must have started loading before the duration can be
   * known, and in the case of Flash, may not be known until the video starts
   * playing.
   *
   * @param {Number} seconds Duration when setting
   * @return {Number} The duration of the video in seconds when getting
   * @method duration
   */

  Player.prototype.duration = function duration(seconds) {
    if (seconds === undefined) {
      return this.cache_.duration || 0;
    }

    seconds = parseFloat(seconds) || 0;

    // Standardize on Inifity for signaling video is live
    if (seconds < 0) {
      seconds = Infinity;
    }

    if (seconds !== this.cache_.duration) {
      // Cache the last set value for optimized scrubbing (esp. Flash)
      this.cache_.duration = seconds;

      if (seconds === Infinity) {
        this.addClass('vjs-live');
      } else {
        this.removeClass('vjs-live');
      }

      this.trigger('durationchange');
    }

    return this;
  };

  /**
   * Calculates how much time is left.
   * ```js
   *     var timeLeft = myPlayer.remainingTime();
   * ```
   * Not a native video element function, but useful
   *
   * @return {Number} The time remaining in seconds
   * @method remainingTime
   */

  Player.prototype.remainingTime = function remainingTime() {
    return this.duration() - this.currentTime();
  };

  // http://dev.w3.org/html5/spec/video.html#dom-media-buffered
  // Buffered returns a timerange object.
  // Kind of like an array of portions of the video that have been downloaded.

  /**
   * Get a TimeRange object with the times of the video that have been downloaded
   * If you just want the percent of the video that's been downloaded,
   * use bufferedPercent.
   * ```js
   *     // Number of different ranges of time have been buffered. Usually 1.
   *     numberOfRanges = bufferedTimeRange.length,
   *     // Time in seconds when the first range starts. Usually 0.
   *     firstRangeStart = bufferedTimeRange.start(0),
   *     // Time in seconds when the first range ends
   *     firstRangeEnd = bufferedTimeRange.end(0),
   *     // Length in seconds of the first time range
   *     firstRangeLength = firstRangeEnd - firstRangeStart;
   * ```
   *
   * @return {Object} A mock TimeRange object (following HTML spec)
   * @method buffered
   */

  Player.prototype.buffered = function buffered() {
    var buffered = this.techGet_('buffered');

    if (!buffered || !buffered.length) {
      buffered = _utilsTimeRangesJs.createTimeRange(0, 0);
    }

    return buffered;
  };

  /**
   * Get the percent (as a decimal) of the video that's been downloaded
   * ```js
   *     var howMuchIsDownloaded = myPlayer.bufferedPercent();
   * ```
   * 0 means none, 1 means all.
   * (This method isn't in the HTML5 spec, but it's very convenient)
   *
   * @return {Number} A decimal between 0 and 1 representing the percent
   * @method bufferedPercent
   */

  Player.prototype.bufferedPercent = function bufferedPercent() {
    return _utilsBufferJs.bufferedPercent(this.buffered(), this.duration());
  };

  /**
   * Get the ending time of the last buffered time range
   * This is used in the progress bar to encapsulate all time ranges.
   *
   * @return {Number} The end of the last buffered time range
   * @method bufferedEnd
   */

  Player.prototype.bufferedEnd = function bufferedEnd() {
    var buffered = this.buffered(),
        duration = this.duration(),
        end = buffered.end(buffered.length - 1);

    if (end > duration) {
      end = duration;
    }

    return end;
  };

  /**
   * Get or set the current volume of the media
   * ```js
   *     // get
   *     var howLoudIsIt = myPlayer.volume();
   *     // set
   *     myPlayer.volume(0.5); // Set volume to half
   * ```
   * 0 is off (muted), 1.0 is all the way up, 0.5 is half way.
   *
   * @param  {Number} percentAsDecimal The new volume as a decimal percent
   * @return {Number}              The current volume when getting
   * @return {Player}              self when setting
   * @method volume
   */

  Player.prototype.volume = function volume(percentAsDecimal) {
    var vol = undefined;

    if (percentAsDecimal !== undefined) {
      vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); // Force value to between 0 and 1
      this.cache_.volume = vol;
      this.techCall_('setVolume', vol);

      return this;
    }

    // Default to 1 when returning current volume.
    vol = parseFloat(this.techGet_('volume'));
    return isNaN(vol) ? 1 : vol;
  };

  /**
   * Get the current muted state, or turn mute on or off
   * ```js
   *     // get
   *     var isVolumeMuted = myPlayer.muted();
   *     // set
   *     myPlayer.muted(true); // mute the volume
   * ```
   *
   * @param  {Boolean=} muted True to mute, false to unmute
   * @return {Boolean} True if mute is on, false if not when getting
   * @return {Player} self when setting mute
   * @method muted
   */

  Player.prototype.muted = function muted(_muted) {
    if (_muted !== undefined) {
      this.techCall_('setMuted', _muted);
      return this;
    }
    return this.techGet_('muted') || false; // Default to false
  };

  // Check if current tech can support native fullscreen
  // (e.g. with built in controls like iOS, so not our flash swf)
  /**
   * Check to see if fullscreen is supported
   *
   * @return {Boolean}
   * @method supportsFullScreen
   */

  Player.prototype.supportsFullScreen = function supportsFullScreen() {
    return this.techGet_('supportsFullScreen') || false;
  };

  /**
   * Check if the player is in fullscreen mode
   * ```js
   *     // get
   *     var fullscreenOrNot = myPlayer.isFullscreen();
   *     // set
   *     myPlayer.isFullscreen(true); // tell the player it's in fullscreen
   * ```
   * NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official
   * property and instead document.fullscreenElement is used. But isFullscreen is
   * still a valuable property for internal player workings.
   *
   * @param  {Boolean=} isFS Update the player's fullscreen state
   * @return {Boolean} true if fullscreen false if not when getting
   * @return {Player} self when setting
   * @method isFullscreen
   */

  Player.prototype.isFullscreen = function isFullscreen(isFS) {
    if (isFS !== undefined) {
      this.isFullscreen_ = !!isFS;
      return this;
    }
    return !!this.isFullscreen_;
  };

  /**
   * Increase the size of the video to full screen
   * ```js
   *     myPlayer.requestFullscreen();
   * ```
   * In some browsers, full screen is not supported natively, so it enters
   * "full window mode", where the video fills the browser window.
   * In browsers and devices that support native full screen, sometimes the
   * browser's default controls will be shown, and not the Video.js custom skin.
   * This includes most mobile devices (iOS, Android) and older versions of
   * Safari.
   *
   * @return {Player} self
   * @method requestFullscreen
   */

  Player.prototype.requestFullscreen = function requestFullscreen() {
    var fsApi = _fullscreenApiJs2['default'];

    this.isFullscreen(true);

    if (fsApi.requestFullscreen) {
      // the browser supports going fullscreen at the element level so we can
      // take the controls fullscreen as well as the video

      // Trigger fullscreenchange event after change
      // We have to specifically add this each time, and remove
      // when canceling fullscreen. Otherwise if there's multiple
      // players on a page, they would all be reacting to the same fullscreen
      // events
      Events.on(_globalDocument2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) {
        this.isFullscreen(_globalDocument2['default'][fsApi.fullscreenElement]);

        // If cancelling fullscreen, remove event listener.
        if (this.isFullscreen() === false) {
          Events.off(_globalDocument2['default'], fsApi.fullscreenchange, documentFullscreenChange);
        }

        this.trigger('fullscreenchange');
      }));

      this.el_[fsApi.requestFullscreen]();
    } else if (this.tech_.supportsFullScreen()) {
      // we can't take the video.js controls fullscreen but we can go fullscreen
      // with native controls
      this.techCall_('enterFullScreen');
    } else {
      // fullscreen isn't supported so we'll just stretch the video element to
      // fill the viewport
      this.enterFullWindow();
      this.trigger('fullscreenchange');
    }

    return this;
  };

  /**
   * Return the video to its normal size after having been in full screen mode
   * ```js
   *     myPlayer.exitFullscreen();
   * ```
   *
   * @return {Player} self
   * @method exitFullscreen
   */

  Player.prototype.exitFullscreen = function exitFullscreen() {
    var fsApi = _fullscreenApiJs2['default'];
    this.isFullscreen(false);

    // Check for browser element fullscreen support
    if (fsApi.requestFullscreen) {
      _globalDocument2['default'][fsApi.exitFullscreen]();
    } else if (this.tech_.supportsFullScreen()) {
      this.techCall_('exitFullScreen');
    } else {
      this.exitFullWindow();
      this.trigger('fullscreenchange');
    }

    return this;
  };

  /**
   * When fullscreen isn't supported we can stretch the video container to as wide as the browser will let us.
   *
   * @method enterFullWindow
   */

  Player.prototype.enterFullWindow = function enterFullWindow() {
    this.isFullWindow = true;

    // Storing original doc overflow value to return to when fullscreen is off
    this.docOrigOverflow = _globalDocument2['default'].documentElement.style.overflow;

    // Add listener for esc key to exit fullscreen
    Events.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey));

    // Hide any scroll bars
    _globalDocument2['default'].documentElement.style.overflow = 'hidden';

    // Apply fullscreen styles
    Dom.addElClass(_globalDocument2['default'].body, 'vjs-full-window');

    this.trigger('enterFullWindow');
  };

  /**
   * Check for call to either exit full window or full screen on ESC key
   *
   * @param {String} event Event to check for key press
   * @method fullWindowOnEscKey
   */

  Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) {
    if (event.keyCode === 27) {
      if (this.isFullscreen() === true) {
        this.exitFullscreen();
      } else {
        this.exitFullWindow();
      }
    }
  };

  /**
   * Exit full window
   *
   * @method exitFullWindow
   */

  Player.prototype.exitFullWindow = function exitFullWindow() {
    this.isFullWindow = false;
    Events.off(_globalDocument2['default'], 'keydown', this.fullWindowOnEscKey);

    // Unhide scroll bars.
    _globalDocument2['default'].documentElement.style.overflow = this.docOrigOverflow;

    // Remove fullscreen styles
    Dom.removeElClass(_globalDocument2['default'].body, 'vjs-full-window');

    // Resize the box, controller, and poster to original sizes
    // this.positionAll();
    this.trigger('exitFullWindow');
  };

  /**
   * Check whether the player can play a given mimetype
   *
   * @param {String} type The mimetype to check
   * @return {String} 'probably', 'maybe', or '' (empty string)
   * @method canPlayType
   */

  Player.prototype.canPlayType = function canPlayType(type) {
    var can = undefined;

    // Loop through each playback technology in the options order
    for (var i = 0, j = this.options_.techOrder; i < j.length; i++) {
      var techName = _utilsToTitleCaseJs2['default'](j[i]);
      var tech = _techTechJs2['default'].getTech(techName);

      // Support old behavior of techs being registered as components.
      // Remove once that deprecated behavior is removed.
      if (!tech) {
        tech = _componentJs2['default'].getComponent(techName);
      }

      // Check if the current tech is defined before continuing
      if (!tech) {
        _utilsLogJs2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
        continue;
      }

      // Check if the browser supports this technology
      if (tech.isSupported()) {
        can = tech.canPlayType(type);

        if (can) {
          return can;
        }
      }
    }

    return '';
  };

  /**
   * Select source based on tech-order or source-order
   * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise,
   * defaults to tech-order selection
   *
   * @param {Array} sources The sources for a media asset
   * @return {Object|Boolean} Object of source and tech order, otherwise false
   * @method selectSource
   */

  Player.prototype.selectSource = function selectSource(sources) {
    // Get only the techs specified in `techOrder` that exist and are supported by the
    // current platform
    var techs = this.options_.techOrder.map(_utilsToTitleCaseJs2['default']).map(function (techName) {
      // `Component.getComponent(...)` is for support of old behavior of techs
      // being registered as components.
      // Remove once that deprecated behavior is removed.
      return [techName, _techTechJs2['default'].getTech(techName) || _componentJs2['default'].getComponent(techName)];
    }).filter(function (_ref) {
      var techName = _ref[0];
      var tech = _ref[1];

      // Check if the current tech is defined before continuing
      if (tech) {
        // Check if the browser supports this technology
        return tech.isSupported();
      }

      _utilsLogJs2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
      return false;
    });

    // Iterate over each `innerArray` element once per `outerArray` element and execute
    // `tester` with both. If `tester` returns a non-falsy value, exit early and return
    // that value.
    var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) {
      var found = undefined;

      outerArray.some(function (outerChoice) {
        return innerArray.some(function (innerChoice) {
          found = tester(outerChoice, innerChoice);

          if (found) {
            return true;
          }
        });
      });

      return found;
    };

    var foundSourceAndTech = undefined;
    var flip = function flip(fn) {
      return function (a, b) {
        return fn(b, a);
      };
    };
    var finder = function finder(_ref2, source) {
      var techName = _ref2[0];
      var tech = _ref2[1];

      if (tech.canPlaySource(source)) {
        return { source: source, tech: techName };
      }
    };

    // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources
    // to select from them based on their priority.
    if (this.options_.sourceOrder) {
      // Source-first ordering
      foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder));
    } else {
      // Tech-first ordering
      foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder);
    }

    return foundSourceAndTech || false;
  };

  /**
   * The source function updates the video source
   * There are three types of variables you can pass as the argument.
   * **URL String**: A URL to the the video file. Use this method if you are sure
   * the current playback technology (HTML5/Flash) can support the source you
   * provide. Currently only MP4 files can be used in both HTML5 and Flash.
   * ```js
   *     myPlayer.src("http://www.example.com/path/to/video.mp4");
   * ```
   * **Source Object (or element):* * A javascript object containing information
   * about the source file. Use this method if you want the player to determine if
   * it can support the file using the type information.
   * ```js
   *     myPlayer.src({ type: "video/mp4", src: "http://www.example.com/path/to/video.mp4" });
   * ```
   * **Array of Source Objects:* * To provide multiple versions of the source so
   * that it can be played using HTML5 across browsers you can use an array of
   * source objects. Video.js will detect which version is supported and load that
   * file.
   * ```js
   *     myPlayer.src([
   *       { type: "video/mp4", src: "http://www.example.com/path/to/video.mp4" },
   *       { type: "video/webm", src: "http://www.example.com/path/to/video.webm" },
   *       { type: "video/ogg", src: "http://www.example.com/path/to/video.ogv" }
   *     ]);
   * ```
   *
   * @param  {String|Object|Array=} source The source URL, object, or array of sources
   * @return {String} The current video source when getting
   * @return {String} The player when setting
   * @method src
   */

  Player.prototype.src = function src(source) {
    if (source === undefined) {
      return this.techGet_('src');
    }

    var currentTech = _techTechJs2['default'].getTech(this.techName_);
    // Support old behavior of techs being registered as components.
    // Remove once that deprecated behavior is removed.
    if (!currentTech) {
      currentTech = _componentJs2['default'].getComponent(this.techName_);
    }

    // case: Array of source objects to choose from and pick the best to play
    if (Array.isArray(source)) {
      this.sourceList_(source);

      // case: URL String (http://myvideo...)
    } else if (typeof source === 'string') {
        // create a source object from the string
        this.src({ src: source });

        // case: Source object { src: '', type: '' ... }
      } else if (source instanceof Object) {
          // check if the source has a type and the loaded tech cannot play the source
          // if there's no type we'll just try the current tech
          if (source.type && !currentTech.canPlaySource(source)) {
            // create a source list with the current source and send through
            // the tech loop to check for a compatible technology
            this.sourceList_([source]);
          } else {
            this.cache_.src = source.src;
            this.currentType_ = source.type || '';

            // wait until the tech is ready to set the source
            this.ready(function () {

              // The setSource tech method was added with source handlers
              // so older techs won't support it
              // We need to check the direct prototype for the case where subclasses
              // of the tech do not support source handlers
              if (currentTech.prototype.hasOwnProperty('setSource')) {
                this.techCall_('setSource', source);
              } else {
                this.techCall_('src', source.src);
              }

              if (this.options_.preload === 'auto') {
                this.load();
              }

              if (this.options_.autoplay) {
                this.play();
              }

              // Set the source synchronously if possible (#2326)
            }, true);
          }
        }

    return this;
  };

  /**
   * Handle an array of source objects
   *
   * @param  {Array} sources Array of source objects
   * @private
   * @method sourceList_
   */

  Player.prototype.sourceList_ = function sourceList_(sources) {
    var sourceTech = this.selectSource(sources);

    if (sourceTech) {
      if (sourceTech.tech === this.techName_) {
        // if this technology is already loaded, set the source
        this.src(sourceTech.source);
      } else {
        // load this technology with the chosen source
        this.loadTech_(sourceTech.tech, sourceTech.source);
      }
    } else {
      // We need to wrap this in a timeout to give folks a chance to add error event handlers
      this.setTimeout(function () {
        this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) });
      }, 0);

      // we could not find an appropriate tech, but let's still notify the delegate that this is it
      // this needs a better comment about why this is needed
      this.triggerReady();
    }
  };

  /**
   * Begin loading the src data.
   *
   * @return {Player} Returns the player
   * @method load
   */

  Player.prototype.load = function load() {
    this.techCall_('load');
    return this;
  };

  /**
   * Reset the player. Loads the first tech in the techOrder,
   * and calls `reset` on the tech`.
   *
   * @return {Player} Returns the player
   * @method reset
   */

  Player.prototype.reset = function reset() {
    this.loadTech_(_utilsToTitleCaseJs2['default'](this.options_.techOrder[0]), null);
    this.techCall_('reset');
    return this;
  };

  /**
   * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4
   * Can be used in conjuction with `currentType` to assist in rebuilding the current source object.
   *
   * @return {String} The current source
   * @method currentSrc
   */

  Player.prototype.currentSrc = function currentSrc() {
    return this.techGet_('currentSrc') || this.cache_.src || '';
  };

  /**
   * Get the current source type e.g. video/mp4
   * This can allow you rebuild the current source object so that you could load the same
   * source and tech later
   *
   * @return {String} The source MIME type
   * @method currentType
   */

  Player.prototype.currentType = function currentType() {
    return this.currentType_ || '';
  };

  /**
   * Get or set the preload attribute
   *
   * @param {Boolean} value Boolean to determine if preload should be used
   * @return {String} The preload attribute value when getting
   * @return {Player} Returns the player when setting
   * @method preload
   */

  Player.prototype.preload = function preload(value) {
    if (value !== undefined) {
      this.techCall_('setPreload', value);
      this.options_.preload = value;
      return this;
    }
    return this.techGet_('preload');
  };

  /**
   * Get or set the autoplay attribute.
   *
   * @param {Boolean} value Boolean to determine if video should autoplay
   * @return {String} The autoplay attribute value when getting
   * @return {Player} Returns the player when setting
   * @method autoplay
   */

  Player.prototype.autoplay = function autoplay(value) {
    if (value !== undefined) {
      this.techCall_('setAutoplay', value);
      this.options_.autoplay = value;
      return this;
    }
    return this.techGet_('autoplay', value);
  };

  /**
   * Get or set the loop attribute on the video element.
   *
   * @param {Boolean} value Boolean to determine if video should loop
   * @return {String} The loop attribute value when getting
   * @return {Player} Returns the player when setting
   * @method loop
   */

  Player.prototype.loop = function loop(value) {
    if (value !== undefined) {
      this.techCall_('setLoop', value);
      this.options_['loop'] = value;
      return this;
    }
    return this.techGet_('loop');
  };

  /**
   * Get or set the poster image source url
   *
   * ##### EXAMPLE:
   * ```js
   *     // get
   *     var currentPoster = myPlayer.poster();
   *     // set
   *     myPlayer.poster('http://example.com/myImage.jpg');
   * ```
   *
   * @param  {String=} src Poster image source URL
   * @return {String} poster URL when getting
   * @return {Player} self when setting
   * @method poster
   */

  Player.prototype.poster = function poster(src) {
    if (src === undefined) {
      return this.poster_;
    }

    // The correct way to remove a poster is to set as an empty string
    // other falsey values will throw errors
    if (!src) {
      src = '';
    }

    // update the internal poster variable
    this.poster_ = src;

    // update the tech's poster
    this.techCall_('setPoster', src);

    // alert components that the poster has been set
    this.trigger('posterchange');

    return this;
  };

  /**
   * Some techs (e.g. YouTube) can provide a poster source in an
   * asynchronous way. We want the poster component to use this
   * poster source so that it covers up the tech's controls.
   * (YouTube's play button). However we only want to use this
   * soruce if the player user hasn't set a poster through
   * the normal APIs.
   *
   * @private
   * @method handleTechPosterChange_
   */

  Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() {
    if (!this.poster_ && this.tech_ && this.tech_.poster) {
      this.poster_ = this.tech_.poster() || '';

      // Let components know the poster has changed
      this.trigger('posterchange');
    }
  };

  /**
   * Get or set whether or not the controls are showing.
   *
   * @param  {Boolean} bool Set controls to showing or not
   * @return {Boolean}    Controls are showing
   * @method controls
   */

  Player.prototype.controls = function controls(bool) {
    if (bool !== undefined) {
      bool = !!bool; // force boolean
      // Don't trigger a change event unless it actually changed
      if (this.controls_ !== bool) {
        this.controls_ = bool;

        if (this.usingNativeControls()) {
          this.techCall_('setControls', bool);
        }

        if (bool) {
          this.removeClass('vjs-controls-disabled');
          this.addClass('vjs-controls-enabled');
          this.trigger('controlsenabled');

          if (!this.usingNativeControls()) {
            this.addTechControlsListeners_();
          }
        } else {
          this.removeClass('vjs-controls-enabled');
          this.addClass('vjs-controls-disabled');
          this.trigger('controlsdisabled');

          if (!this.usingNativeControls()) {
            this.removeTechControlsListeners_();
          }
        }
      }
      return this;
    }
    return !!this.controls_;
  };

  /**
   * Toggle native controls on/off. Native controls are the controls built into
   * devices (e.g. default iPhone controls), Flash, or other techs
   * (e.g. Vimeo Controls)
   * **This should only be set by the current tech, because only the tech knows
   * if it can support native controls**
   *
   * @param  {Boolean} bool    True signals that native controls are on
   * @return {Player}      Returns the player
   * @private
   * @method usingNativeControls
   */

  Player.prototype.usingNativeControls = function usingNativeControls(bool) {
    if (bool !== undefined) {
      bool = !!bool; // force boolean
      // Don't trigger a change event unless it actually changed
      if (this.usingNativeControls_ !== bool) {
        this.usingNativeControls_ = bool;
        if (bool) {
          this.addClass('vjs-using-native-controls');

          /**
            * player is using the native device controls
           *
            * @event usingnativecontrols
            * @memberof Player
            * @instance
            * @private
            */
          this.trigger('usingnativecontrols');
        } else {
          this.removeClass('vjs-using-native-controls');

          /**
            * player is using the custom HTML controls
           *
            * @event usingcustomcontrols
            * @memberof Player
            * @instance
            * @private
            */
          this.trigger('usingcustomcontrols');
        }
      }
      return this;
    }
    return !!this.usingNativeControls_;
  };

  /**
   * Set or get the current MediaError
   *
   * @param  {*} err A MediaError or a String/Number to be turned into a MediaError
   * @return {MediaError|null}     when getting
   * @return {Player}              when setting
   * @method error
   */

  Player.prototype.error = function error(err) {
    if (err === undefined) {
      return this.error_ || null;
    }

    // restoring to default
    if (err === null) {
      this.error_ = err;
      this.removeClass('vjs-error');
      this.errorDisplay.close();
      return this;
    }

    // error instance
    if (err instanceof _mediaErrorJs2['default']) {
      this.error_ = err;
    } else {
      this.error_ = new _mediaErrorJs2['default'](err);
    }

    // add the vjs-error classname to the player
    this.addClass('vjs-error');

    // log the name of the error type and any message
    // ie8 just logs "[object object]" if you just log the error object
    _utilsLogJs2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaErrorJs2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_);

    // fire an error event on the player
    this.trigger('error');

    return this;
  };

  /**
   * Returns whether or not the player is in the "ended" state.
   *
   * @return {Boolean} True if the player is in the ended state, false if not.
   * @method ended
   */

  Player.prototype.ended = function ended() {
    return this.techGet_('ended');
  };

  /**
   * Returns whether or not the player is in the "seeking" state.
   *
   * @return {Boolean} True if the player is in the seeking state, false if not.
   * @method seeking
   */

  Player.prototype.seeking = function seeking() {
    return this.techGet_('seeking');
  };

  /**
   * Returns the TimeRanges of the media that are currently available
   * for seeking to.
   *
   * @return {TimeRanges} the seekable intervals of the media timeline
   * @method seekable
   */

  Player.prototype.seekable = function seekable() {
    return this.techGet_('seekable');
  };

  /**
   * Report user activity
   *
   * @param {Object} event Event object
   * @method reportUserActivity
   */

  Player.prototype.reportUserActivity = function reportUserActivity(event) {
    this.userActivity_ = true;
  };

  /**
   * Get/set if user is active
   *
   * @param {Boolean} bool Value when setting
   * @return {Boolean} Value if user is active user when getting
   * @method userActive
   */

  Player.prototype.userActive = function userActive(bool) {
    if (bool !== undefined) {
      bool = !!bool;
      if (bool !== this.userActive_) {
        this.userActive_ = bool;
        if (bool) {
          // If the user was inactive and is now active we want to reset the
          // inactivity timer
          this.userActivity_ = true;
          this.removeClass('vjs-user-inactive');
          this.addClass('vjs-user-active');
          this.trigger('useractive');
        } else {
          // We're switching the state to inactive manually, so erase any other
          // activity
          this.userActivity_ = false;

          // Chrome/Safari/IE have bugs where when you change the cursor it can
          // trigger a mousemove event. This causes an issue when you're hiding
          // the cursor when the user is inactive, and a mousemove signals user
          // activity. Making it impossible to go into inactive mode. Specifically
          // this happens in fullscreen when we really need to hide the cursor.
          //
          // When this gets resolved in ALL browsers it can be removed
          // https://code.google.com/p/chromium/issues/detail?id=103041
          if (this.tech_) {
            this.tech_.one('mousemove', function (e) {
              e.stopPropagation();
              e.preventDefault();
            });
          }

          this.removeClass('vjs-user-active');
          this.addClass('vjs-user-inactive');
          this.trigger('userinactive');
        }
      }
      return this;
    }
    return this.userActive_;
  };

  /**
   * Listen for user activity based on timeout value
   *
   * @private
   * @method listenForUserActivity_
   */

  Player.prototype.listenForUserActivity_ = function listenForUserActivity_() {
    var mouseInProgress = undefined,
        lastMoveX = undefined,
        lastMoveY = undefined;

    var handleActivity = Fn.bind(this, this.reportUserActivity);

    var handleMouseMove = function handleMouseMove(e) {
      // #1068 - Prevent mousemove spamming
      // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970
      if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) {
        lastMoveX = e.screenX;
        lastMoveY = e.screenY;
        handleActivity();
      }
    };

    var handleMouseDown = function handleMouseDown() {
      handleActivity();
      // For as long as the they are touching the device or have their mouse down,
      // we consider them active even if they're not moving their finger or mouse.
      // So we want to continue to update that they are active
      this.clearInterval(mouseInProgress);
      // Setting userActivity=true now and setting the interval to the same time
      // as the activityCheck interval (250) should ensure we never miss the
      // next activityCheck
      mouseInProgress = this.setInterval(handleActivity, 250);
    };

    var handleMouseUp = function handleMouseUp(event) {
      handleActivity();
      // Stop the interval that maintains activity if the mouse/touch is down
      this.clearInterval(mouseInProgress);
    };

    // Any mouse movement will be considered user activity
    this.on('mousedown', handleMouseDown);
    this.on('mousemove', handleMouseMove);
    this.on('mouseup', handleMouseUp);

    // Listen for keyboard navigation
    // Shouldn't need to use inProgress interval because of key repeat
    this.on('keydown', handleActivity);
    this.on('keyup', handleActivity);

    // Run an interval every 250 milliseconds instead of stuffing everything into
    // the mousemove/touchmove function itself, to prevent performance degradation.
    // `this.reportUserActivity` simply sets this.userActivity_ to true, which
    // then gets picked up by this loop
    // http://ejohn.org/blog/learning-from-twitter/
    var inactivityTimeout = undefined;
    var activityCheck = this.setInterval(function () {
      // Check to see if mouse/touch activity has happened
      if (this.userActivity_) {
        // Reset the activity tracker
        this.userActivity_ = false;

        // If the user state was inactive, set the state to active
        this.userActive(true);

        // Clear any existing inactivity timeout to start the timer over
        this.clearTimeout(inactivityTimeout);

        var timeout = this.options_['inactivityTimeout'];
        if (timeout > 0) {
          // In <timeout> milliseconds, if no more activity has occurred the
          // user will be considered inactive
          inactivityTimeout = this.setTimeout(function () {
            // Protect against the case where the inactivityTimeout can trigger just
            // before the next user activity is picked up by the activityCheck loop
            // causing a flicker
            if (!this.userActivity_) {
              this.userActive(false);
            }
          }, timeout);
        }
      }
    }, 250);
  };

  /**
   * Gets or sets the current playback rate.  A playback rate of
   * 1.0 represents normal speed and 0.5 would indicate half-speed
   * playback, for instance.
   * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate
   *
   * @param  {Number} rate    New playback rate to set.
   * @return {Number}         Returns the new playback rate when setting
   * @return {Number}         Returns the current playback rate when getting
   * @method playbackRate
   */

  Player.prototype.playbackRate = function playbackRate(rate) {
    if (rate !== undefined) {
      this.techCall_('setPlaybackRate', rate);
      return this;
    }

    if (this.tech_ && this.tech_['featuresPlaybackRate']) {
      return this.techGet_('playbackRate');
    } else {
      return 1.0;
    }
  };

  /**
   * Gets or sets the audio flag
   *
   * @param  {Boolean} bool    True signals that this is an audio player.
   * @return {Boolean}         Returns true if player is audio, false if not when getting
   * @return {Player}      Returns the player if setting
   * @private
   * @method isAudio
   */

  Player.prototype.isAudio = function isAudio(bool) {
    if (bool !== undefined) {
      this.isAudio_ = !!bool;
      return this;
    }

    return !!this.isAudio_;
  };

  /**
   * Returns the current state of network activity for the element, from
   * the codes in the list below.
   * - NETWORK_EMPTY (numeric value 0)
   *   The element has not yet been initialised. All attributes are in
   *   their initial states.
   * - NETWORK_IDLE (numeric value 1)
   *   The element's resource selection algorithm is active and has
   *   selected a resource, but it is not actually using the network at
   *   this time.
   * - NETWORK_LOADING (numeric value 2)
   *   The user agent is actively trying to download data.
   * - NETWORK_NO_SOURCE (numeric value 3)
   *   The element's resource selection algorithm is active, but it has
   *   not yet found a resource to use.
   *
   * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states
   * @return {Number} the current network activity state
   * @method networkState
   */

  Player.prototype.networkState = function networkState() {
    return this.techGet_('networkState');
  };

  /**
   * Returns a value that expresses the current state of the element
   * with respect to rendering the current playback position, from the
   * codes in the list below.
   * - HAVE_NOTHING (numeric value 0)
   *   No information regarding the media resource is available.
   * - HAVE_METADATA (numeric value 1)
   *   Enough of the resource has been obtained that the duration of the
   *   resource is available.
   * - HAVE_CURRENT_DATA (numeric value 2)
   *   Data for the immediate current playback position is available.
   * - HAVE_FUTURE_DATA (numeric value 3)
   *   Data for the immediate current playback position is available, as
   *   well as enough data for the user agent to advance the current
   *   playback position in the direction of playback.
   * - HAVE_ENOUGH_DATA (numeric value 4)
   *   The user agent estimates that enough data is available for
   *   playback to proceed uninterrupted.
   *
   * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate
   * @return {Number} the current playback rendering state
   * @method readyState
   */

  Player.prototype.readyState = function readyState() {
    return this.techGet_('readyState');
  };

  /*
    * Text tracks are tracks of timed text events.
    * Captions - text displayed over the video for the hearing impaired
    * Subtitles - text displayed over the video for those who don't understand language in the video
    * Chapters - text displayed in a menu allowing the user to jump to particular points (chapters) in the video
    * Descriptions (not supported yet) - audio descriptions that are read back to the user by a screen reading device
    */

  /**
   * Get an array of associated text tracks. captions, subtitles, chapters, descriptions
   * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks
   *
   * @return {Array}           Array of track objects
   * @method textTracks
   */

  Player.prototype.textTracks = function textTracks() {
    // cannot use techGet_ directly because it checks to see whether the tech is ready.
    // Flash is unlikely to be ready in time but textTracks should still work.
    return this.tech_ && this.tech_['textTracks']();
  };

  /**
   * Get an array of remote text tracks
   *
   * @return {Array}
   * @method remoteTextTracks
   */

  Player.prototype.remoteTextTracks = function remoteTextTracks() {
    return this.tech_ && this.tech_['remoteTextTracks']();
  };

  /**
   * Get an array of remote html track elements
   *
   * @return {HTMLTrackElement[]}
   * @method remoteTextTrackEls
   */

  Player.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
    return this.tech_ && this.tech_['remoteTextTrackEls']();
  };

  /**
   * Add a text track
   * In addition to the W3C settings we allow adding additional info through options.
   * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack
   *
   * @param {String}  kind        Captions, subtitles, chapters, descriptions, or metadata
   * @param {String=} label       Optional label
   * @param {String=} language    Optional language
   * @method addTextTrack
   */

  Player.prototype.addTextTrack = function addTextTrack(kind, label, language) {
    return this.tech_ && this.tech_['addTextTrack'](kind, label, language);
  };

  /**
   * Add a remote text track
   *
   * @param {Object} options    Options for remote text track
   * @method addRemoteTextTrack
   */

  Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options) {
    return this.tech_ && this.tech_['addRemoteTextTrack'](options);
  };

  /**
   * Remove a remote text track
   *
   * @param {Object} track    Remote text track to remove
   * @method removeRemoteTextTrack
   */

  Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
    this.tech_ && this.tech_['removeRemoteTextTrack'](track);
  };

  /**
   * Get video width
   *
   * @return {Number} Video width
   * @method videoWidth
   */

  Player.prototype.videoWidth = function videoWidth() {
    return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0;
  };

  /**
   * Get video height
   *
   * @return {Number} Video height
   * @method videoHeight
   */

  Player.prototype.videoHeight = function videoHeight() {
    return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0;
  };

  // Methods to add support for
  // initialTime: function(){ return this.techCall_('initialTime'); },
  // startOffsetTime: function(){ return this.techCall_('startOffsetTime'); },
  // played: function(){ return this.techCall_('played'); },
  // videoTracks: function(){ return this.techCall_('videoTracks'); },
  // audioTracks: function(){ return this.techCall_('audioTracks'); },
  // defaultPlaybackRate: function(){ return this.techCall_('defaultPlaybackRate'); },
  // defaultMuted: function(){ return this.techCall_('defaultMuted'); }

  /**
   * The player's language code
   * NOTE: The language should be set in the player options if you want the
   * the controls to be built with a specific language. Changing the lanugage
   * later will not update controls text.
   *
   * @param {String} code  The locale string
   * @return {String}      The locale string when getting
   * @return {Player}      self when setting
   * @method language
   */

  Player.prototype.language = function language(code) {
    if (code === undefined) {
      return this.language_;
    }

    this.language_ = ('' + code).toLowerCase();
    return this;
  };

  /**
   * Get the player's language dictionary
   * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time
   * Languages specified directly in the player options have precedence
   *
   * @return {Array} Array of languages
   * @method languages
   */

  Player.prototype.languages = function languages() {
    return _utilsMergeOptionsJs2['default'](Player.prototype.options_.languages, this.languages_);
  };

  /**
   * Converts track info to JSON
   *
   * @return {Object} JSON object of options
   * @method toJSON
   */

  Player.prototype.toJSON = function toJSON() {
    var options = _utilsMergeOptionsJs2['default'](this.options_);
    var tracks = options.tracks;

    options.tracks = [];

    for (var i = 0; i < tracks.length; i++) {
      var track = tracks[i];

      // deep merge tracks and null out player so no circular references
      track = _utilsMergeOptionsJs2['default'](track);
      track.player = undefined;
      options.tracks[i] = track;
    }

    return options;
  };

  /**
   * Creates a simple modal dialog (an instance of the `ModalDialog`
   * component) that immediately overlays the player with arbitrary
   * content and removes itself when closed.
   *
   * @param {String|Function|Element|Array|Null} content
   *        Same as `ModalDialog#content`'s param of the same name.
   *
   *        The most straight-forward usage is to provide a string or DOM
   *        element.
   *
   * @param {Object} [options]
   *        Extra options which will be passed on to the `ModalDialog`.
   *
   * @return {ModalDialog}
   */

  Player.prototype.createModal = function createModal(content, options) {
    var player = this;

    options = options || {};
    options.content = content || '';

    var modal = new _modalDialog2['default'](player, options);

    player.addChild(modal);
    modal.on('dispose', function () {
      player.removeChild(modal);
    });

    return modal.open();
  };

  /**
   * Gets tag settings
   *
   * @param {Element} tag The player tag
   * @return {Array} An array of sources and track objects
   * @static
   * @method getTagSettings
   */

  Player.getTagSettings = function getTagSettings(tag) {
    var baseOptions = {
      'sources': [],
      'tracks': []
    };

    var tagOptions = Dom.getElAttributes(tag);
    var dataSetup = tagOptions['data-setup'];

    // Check if data-setup attr exists.
    if (dataSetup !== null) {
      // Parse options JSON

      var _safeParseTuple = _safeJsonParseTuple2['default'](dataSetup || '{}');

      var err = _safeParseTuple[0];
      var data = _safeParseTuple[1];

      if (err) {
        _utilsLogJs2['default'].error(err);
      }
      _objectAssign2['default'](tagOptions, data);
    }

    _objectAssign2['default'](baseOptions, tagOptions);

    // Get tag children settings
    if (tag.hasChildNodes()) {
      var children = tag.childNodes;

      for (var i = 0, j = children.length; i < j; i++) {
        var child = children[i];
        // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/
        var childName = child.nodeName.toLowerCase();
        if (childName === 'source') {
          baseOptions.sources.push(Dom.getElAttributes(child));
        } else if (childName === 'track') {
          baseOptions.tracks.push(Dom.getElAttributes(child));
        }
      }
    }

    return baseOptions;
  };

  return Player;
})(_componentJs2['default']);

Player.players = {};

var navigator = _globalWindow2['default'].navigator;
/*
 * Player instance options, surfaced using options
 * options = Player.prototype.options_
 * Make changes in options, not here.
 *
 * @type {Object}
 * @private
 */
Player.prototype.options_ = {
  // Default order of fallback technology
  techOrder: ['html5', 'flash'],
  // techOrder: ['flash','html5'],

  html5: {},
  flash: {},

  // defaultVolume: 0.85,
  defaultVolume: 0.00, // The freakin seaguls are driving me crazy!

  // default inactivity timeout
  inactivityTimeout: 2000,

  // default playback rates
  playbackRates: [],
  // Add playback rate selection by adding rates
  // 'playbackRates': [0.5, 1, 1.5, 2],

  // Included control sets
  children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'],

  language: _globalDocument2['default'].getElementsByTagName('html')[0].getAttribute('lang') || navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language || 'en',

  // locales and their language translations
  languages: {},

  // Default message to show when a video cannot be played.
  notSupportedMessage: 'No compatible source was found for this media.'
};

/**
 * Fired when the player has initial duration and dimension information
 *
 * @event loadedmetadata
 */
Player.prototype.handleLoadedMetaData_;

/**
 * Fired when the player has downloaded data at the current playback position
 *
 * @event loadeddata
 */
Player.prototype.handleLoadedData_;

/**
 * Fired when the user is active, e.g. moves the mouse over the player
 *
 * @event useractive
 */
Player.prototype.handleUserActive_;

/**
 * Fired when the user is inactive, e.g. a short delay after the last mouse move or control interaction
 *
 * @event userinactive
 */
Player.prototype.handleUserInactive_;

/**
 * Fired when the current playback position has changed *
 * During playback this is fired every 15-250 milliseconds, depending on the
 * playback technology in use.
 *
 * @event timeupdate
 */
Player.prototype.handleTimeUpdate_;

/**
 * Fired when video playback ends
 *
 * @event ended
 */
Player.prototype.handleTechEnded_;

/**
 * Fired when the volume changes
 *
 * @event volumechange
 */
Player.prototype.handleVolumeChange_;

/**
 * Fired when an error occurs
 *
 * @event error
 */
Player.prototype.handleError_;

Player.prototype.flexNotSupported_ = function () {
  var elem = _globalDocument2['default'].createElement('i');

  // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more
  // common flex features that we can rely on when checking for flex support.
  return !('flexBasis' in elem.style || 'webkitFlexBasis' in elem.style || 'mozFlexBasis' in elem.style || 'msFlexBasis' in elem.style || 'msFlexOrder' in elem.style) /* IE10-specific (2012 flex spec)  */;
};

_componentJs2['default'].registerComponent('Player', Player);
exports['default'] = Player;
module.exports = exports['default'];
// If empty string, make it a parsable json object.

},{"./big-play-button.js":63,"./component.js":67,"./control-bar/control-bar.js":68,"./error-display.js":98,"./fullscreen-api.js":101,"./loading-spinner.js":102,"./media-error.js":103,"./modal-dialog":107,"./poster-image.js":112,"./tech/html5.js":117,"./tech/loader.js":118,"./tech/tech.js":119,"./tracks/text-track-display.js":123,"./tracks/text-track-list-converter.js":125,"./tracks/text-track-settings.js":127,"./utils/browser.js":129,"./utils/buffer.js":130,"./utils/dom.js":132,"./utils/events.js":133,"./utils/fn.js":134,"./utils/guid.js":136,"./utils/log.js":137,"./utils/merge-options.js":138,"./utils/stylesheet.js":139,"./utils/time-ranges.js":140,"./utils/to-title-case.js":141,"global/document":1,"global/window":2,"object.assign":45,"safe-json-parse/tuple":54}],109:[function(_dereq_,module,exports){
/**
 * @file plugins.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _playerJs = _dereq_('./player.js');

var _playerJs2 = _interopRequireDefault(_playerJs);

/**
 * The method for registering a video.js plugin
 *
 * @param  {String} name The name of the plugin
 * @param  {Function} init The function that is run when the player inits
 * @method plugin
 */
var plugin = function plugin(name, init) {
  _playerJs2['default'].prototype[name] = init;
};

exports['default'] = plugin;
module.exports = exports['default'];

},{"./player.js":108}],110:[function(_dereq_,module,exports){
/**
 * @file popup-button.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _clickableComponentJs = _dereq_('../clickable-component.js');

var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);

var _componentJs = _dereq_('../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _popupJs = _dereq_('./popup.js');

var _popupJs2 = _interopRequireDefault(_popupJs);

var _utilsDomJs = _dereq_('../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsFnJs = _dereq_('../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js');

var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);

/**
 * A button class with a popup control
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends ClickableComponent
 * @class PopupButton
 */

var PopupButton = (function (_ClickableComponent) {
  _inherits(PopupButton, _ClickableComponent);

  function PopupButton(player) {
    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

    _classCallCheck(this, PopupButton);

    _ClickableComponent.call(this, player, options);

    this.update();
  }

  /**
   * Update popup
   *
   * @method update
   */

  PopupButton.prototype.update = function update() {
    var popup = this.createPopup();

    if (this.popup) {
      this.removeChild(this.popup);
    }

    this.popup = popup;
    this.addChild(popup);

    if (this.items && this.items.length === 0) {
      this.hide();
    } else if (this.items && this.items.length > 1) {
      this.show();
    }
  };

  /**
   * Create popup - Override with specific functionality for component
   *
   * @return {Popup} The constructed popup
   * @method createPopup
   */

  PopupButton.prototype.createPopup = function createPopup() {};

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  PopupButton.prototype.createEl = function createEl() {
    return _ClickableComponent.prototype.createEl.call(this, 'div', {
      className: this.buildCSSClass()
    });
  };

  /**
   * Allow sub components to stack CSS class names
   *
   * @return {String} The constructed class name
   * @method buildCSSClass
   */

  PopupButton.prototype.buildCSSClass = function buildCSSClass() {
    var menuButtonClass = 'vjs-menu-button';

    // If the inline option is passed, we want to use different styles altogether.
    if (this.options_.inline === true) {
      menuButtonClass += '-inline';
    } else {
      menuButtonClass += '-popup';
    }

    return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
  };

  return PopupButton;
})(_clickableComponentJs2['default']);

_componentJs2['default'].registerComponent('PopupButton', PopupButton);
exports['default'] = PopupButton;
module.exports = exports['default'];

},{"../clickable-component.js":65,"../component.js":67,"../utils/dom.js":132,"../utils/fn.js":134,"../utils/to-title-case.js":141,"./popup.js":111}],111:[function(_dereq_,module,exports){
/**
 * @file popup.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsDomJs = _dereq_('../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsFnJs = _dereq_('../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsEventsJs = _dereq_('../utils/events.js');

var Events = _interopRequireWildcard(_utilsEventsJs);

/**
 * The Popup component is used to build pop up controls.
 *
 * @extends Component
 * @class Popup
 */

var Popup = (function (_Component) {
  _inherits(Popup, _Component);

  function Popup() {
    _classCallCheck(this, Popup);

    _Component.apply(this, arguments);
  }

  /**
   * Add a popup item to the popup
   *
   * @param {Object|String} component Component or component type to add
   * @method addItem
   */

  Popup.prototype.addItem = function addItem(component) {
    this.addChild(component);
    component.on('click', Fn.bind(this, function () {
      this.unlockShowing();
    }));
  };

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  Popup.prototype.createEl = function createEl() {
    var contentElType = this.options_.contentElType || 'ul';
    this.contentEl_ = Dom.createEl(contentElType, {
      className: 'vjs-menu-content'
    });
    var el = _Component.prototype.createEl.call(this, 'div', {
      append: this.contentEl_,
      className: 'vjs-menu'
    });
    el.appendChild(this.contentEl_);

    // Prevent clicks from bubbling up. Needed for Popup Buttons,
    // where a click on the parent is significant
    Events.on(el, 'click', function (event) {
      event.preventDefault();
      event.stopImmediatePropagation();
    });

    return el;
  };

  return Popup;
})(_componentJs2['default']);

_componentJs2['default'].registerComponent('Popup', Popup);
exports['default'] = Popup;
module.exports = exports['default'];

},{"../component.js":67,"../utils/dom.js":132,"../utils/events.js":133,"../utils/fn.js":134}],112:[function(_dereq_,module,exports){
/**
 * @file poster-image.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _clickableComponentJs = _dereq_('./clickable-component.js');

var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);

var _componentJs = _dereq_('./component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsFnJs = _dereq_('./utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsDomJs = _dereq_('./utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsBrowserJs = _dereq_('./utils/browser.js');

var browser = _interopRequireWildcard(_utilsBrowserJs);

/**
 * The component that handles showing the poster image.
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Button
 * @class PosterImage
 */

var PosterImage = (function (_ClickableComponent) {
  _inherits(PosterImage, _ClickableComponent);

  function PosterImage(player, options) {
    _classCallCheck(this, PosterImage);

    _ClickableComponent.call(this, player, options);

    this.update();
    player.on('posterchange', Fn.bind(this, this.update));
  }

  /**
   * Clean up the poster image
   *
   * @method dispose
   */

  PosterImage.prototype.dispose = function dispose() {
    this.player().off('posterchange', this.update);
    _ClickableComponent.prototype.dispose.call(this);
  };

  /**
   * Create the poster's image element
   *
   * @return {Element}
   * @method createEl
   */

  PosterImage.prototype.createEl = function createEl() {
    var el = Dom.createEl('div', {
      className: 'vjs-poster',

      // Don't want poster to be tabbable.
      tabIndex: -1
    });

    // To ensure the poster image resizes while maintaining its original aspect
    // ratio, use a div with `background-size` when available. For browsers that
    // do not support `background-size` (e.g. IE8), fall back on using a regular
    // img element.
    if (!browser.BACKGROUND_SIZE_SUPPORTED) {
      this.fallbackImg_ = Dom.createEl('img');
      el.appendChild(this.fallbackImg_);
    }

    return el;
  };

  /**
   * Event handler for updates to the player's poster source
   *
   * @method update
   */

  PosterImage.prototype.update = function update() {
    var url = this.player().poster();

    this.setSrc(url);

    // If there's no poster source we should display:none on this component
    // so it's not still clickable or right-clickable
    if (url) {
      this.show();
    } else {
      this.hide();
    }
  };

  /**
   * Set the poster source depending on the display method
   *
   * @param {String} url The URL to the poster source
   * @method setSrc
   */

  PosterImage.prototype.setSrc = function setSrc(url) {
    if (this.fallbackImg_) {
      this.fallbackImg_.src = url;
    } else {
      var backgroundImage = '';
      // Any falsey values should stay as an empty string, otherwise
      // this will throw an extra error
      if (url) {
        backgroundImage = 'url("' + url + '")';
      }

      this.el_.style.backgroundImage = backgroundImage;
    }
  };

  /**
   * Event handler for clicks on the poster image
   *
   * @method handleClick
   */

  PosterImage.prototype.handleClick = function handleClick() {
    // We don't want a click to trigger playback when controls are disabled
    // but CSS should be hiding the poster to prevent that from happening
    if (this.player_.paused()) {
      this.player_.play();
    } else {
      this.player_.pause();
    }
  };

  return PosterImage;
})(_clickableComponentJs2['default']);

_componentJs2['default'].registerComponent('PosterImage', PosterImage);
exports['default'] = PosterImage;
module.exports = exports['default'];

},{"./clickable-component.js":65,"./component.js":67,"./utils/browser.js":129,"./utils/dom.js":132,"./utils/fn.js":134}],113:[function(_dereq_,module,exports){
/**
 * @file setup.js
 *
 * Functions for automatically setting up a player
 * based on the data-setup attribute of the video tag
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

var _utilsEventsJs = _dereq_('./utils/events.js');

var Events = _interopRequireWildcard(_utilsEventsJs);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

var _windowLoaded = false;
var videojs = undefined;

// Automatically set up any tags that have a data-setup attribute
var autoSetup = function autoSetup() {
  // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack*
  // var vids = Array.prototype.slice.call(document.getElementsByTagName('video'));
  // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio'));
  // var mediaEls = vids.concat(audios);

  // Because IE8 doesn't support calling slice on a node list, we need to loop through each list of elements
  // to build up a new, combined list of elements.
  var vids = _globalDocument2['default'].getElementsByTagName('video');
  var audios = _globalDocument2['default'].getElementsByTagName('audio');
  var mediaEls = [];
  if (vids && vids.length > 0) {
    for (var i = 0, e = vids.length; i < e; i++) {
      mediaEls.push(vids[i]);
    }
  }
  if (audios && audios.length > 0) {
    for (var i = 0, e = audios.length; i < e; i++) {
      mediaEls.push(audios[i]);
    }
  }

  // Check if any media elements exist
  if (mediaEls && mediaEls.length > 0) {

    for (var i = 0, e = mediaEls.length; i < e; i++) {
      var mediaEl = mediaEls[i];

      // Check if element exists, has getAttribute func.
      // IE seems to consider typeof el.getAttribute == 'object' instead of 'function' like expected, at least when loading the player immediately.
      if (mediaEl && mediaEl.getAttribute) {

        // Make sure this player hasn't already been set up.
        if (mediaEl['player'] === undefined) {
          var options = mediaEl.getAttribute('data-setup');

          // Check if data-setup attr exists.
          // We only auto-setup if they've added the data-setup attr.
          if (options !== null) {
            // Create new video.js instance.
            var player = videojs(mediaEl);
          }
        }

        // If getAttribute isn't defined, we need to wait for the DOM.
      } else {
          autoSetupTimeout(1);
          break;
        }
    }

    // No videos were found, so keep looping unless page is finished loading.
  } else if (!_windowLoaded) {
      autoSetupTimeout(1);
    }
};

// Pause to let the DOM keep processing
var autoSetupTimeout = function autoSetupTimeout(wait, vjs) {
  if (vjs) {
    videojs = vjs;
  }

  setTimeout(autoSetup, wait);
};

if (_globalDocument2['default'].readyState === 'complete') {
  _windowLoaded = true;
} else {
  Events.one(_globalWindow2['default'], 'load', function () {
    _windowLoaded = true;
  });
}

var hasLoaded = function hasLoaded() {
  return _windowLoaded;
};

exports.autoSetup = autoSetup;
exports.autoSetupTimeout = autoSetupTimeout;
exports.hasLoaded = hasLoaded;

},{"./utils/events.js":133,"global/document":1,"global/window":2}],114:[function(_dereq_,module,exports){
/**
 * @file slider.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _utilsDomJs = _dereq_('../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var _objectAssign = _dereq_('object.assign');

var _objectAssign2 = _interopRequireDefault(_objectAssign);

/**
 * The base functionality for sliders like the volume bar and seek bar
 *
 * @param {Player|Object} player
 * @param {Object=} options
 * @extends Component
 * @class Slider
 */

var Slider = (function (_Component) {
  _inherits(Slider, _Component);

  function Slider(player, options) {
    _classCallCheck(this, Slider);

    _Component.call(this, player, options);

    // Set property names to bar to match with the child Slider class is looking for
    this.bar = this.getChild(this.options_.barName);

    // Set a horizontal or vertical class on the slider depending on the slider type
    this.vertical(!!this.options_.vertical);

    this.on('mousedown', this.handleMouseDown);
    this.on('touchstart', this.handleMouseDown);
    this.on('focus', this.handleFocus);
    this.on('blur', this.handleBlur);
    this.on('click', this.handleClick);

    this.on(player, 'controlsvisible', this.update);
    this.on(player, this.playerEvent, this.update);
  }

  /**
   * Create the component's DOM element
   *
   * @param {String} type Type of element to create
   * @param {Object=} props List of properties in Object form
   * @return {Element}
   * @method createEl
   */

  Slider.prototype.createEl = function createEl(type) {
    var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
    var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];

    // Add the slider element class to all sub classes
    props.className = props.className + ' vjs-slider';
    props = _objectAssign2['default']({
      tabIndex: 0
    }, props);

    attributes = _objectAssign2['default']({
      'role': 'slider',
      'aria-valuenow': 0,
      'aria-valuemin': 0,
      'aria-valuemax': 100,
      tabIndex: 0
    }, attributes);

    return _Component.prototype.createEl.call(this, type, props, attributes);
  };

  /**
   * Handle mouse down on slider
   *
   * @param {Object} event Mouse down event object
   * @method handleMouseDown
   */

  Slider.prototype.handleMouseDown = function handleMouseDown(event) {
    event.preventDefault();
    Dom.blockTextSelection();

    this.addClass('vjs-sliding');
    this.trigger('slideractive');

    this.on(_globalDocument2['default'], 'mousemove', this.handleMouseMove);
    this.on(_globalDocument2['default'], 'mouseup', this.handleMouseUp);
    this.on(_globalDocument2['default'], 'touchmove', this.handleMouseMove);
    this.on(_globalDocument2['default'], 'touchend', this.handleMouseUp);

    this.handleMouseMove(event);
  };

  /**
   * To be overridden by a subclass
   *
   * @method handleMouseMove
   */

  Slider.prototype.handleMouseMove = function handleMouseMove() {};

  /**
   * Handle mouse up on Slider
   *
   * @method handleMouseUp
   */

  Slider.prototype.handleMouseUp = function handleMouseUp() {
    Dom.unblockTextSelection();

    this.removeClass('vjs-sliding');
    this.trigger('sliderinactive');

    this.off(_globalDocument2['default'], 'mousemove', this.handleMouseMove);
    this.off(_globalDocument2['default'], 'mouseup', this.handleMouseUp);
    this.off(_globalDocument2['default'], 'touchmove', this.handleMouseMove);
    this.off(_globalDocument2['default'], 'touchend', this.handleMouseUp);

    this.update();
  };

  /**
   * Update slider
   *
   * @method update
   */

  Slider.prototype.update = function update() {
    // In VolumeBar init we have a setTimeout for update that pops and update to the end of the
    // execution stack. The player is destroyed before then update will cause an error
    if (!this.el_) return;

    // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.
    // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.
    // var progress =  (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration();
    var progress = this.getPercent();
    var bar = this.bar;

    // If there's no bar...
    if (!bar) return;

    // Protect against no duration and other division issues
    if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) {
      progress = 0;
    }

    // Convert to a percentage for setting
    var percentage = (progress * 100).toFixed(2) + '%';

    // Set the new bar width or height
    if (this.vertical()) {
      bar.el().style.height = percentage;
    } else {
      bar.el().style.width = percentage;
    }
  };

  /**
   * Calculate distance for slider
   *
   * @param {Object} event Event object
   * @method calculateDistance
   */

  Slider.prototype.calculateDistance = function calculateDistance(event) {
    var position = Dom.getPointerPosition(this.el_, event);
    if (this.vertical()) {
      return position.y;
    }
    return position.x;
  };

  /**
   * Handle on focus for slider
   *
   * @method handleFocus
   */

  Slider.prototype.handleFocus = function handleFocus() {
    this.on(_globalDocument2['default'], 'keydown', this.handleKeyPress);
  };

  /**
   * Handle key press for slider
   *
   * @param {Object} event Event object
   * @method handleKeyPress
   */

  Slider.prototype.handleKeyPress = function handleKeyPress(event) {
    if (event.which === 37 || event.which === 40) {
      // Left and Down Arrows
      event.preventDefault();
      this.stepBack();
    } else if (event.which === 38 || event.which === 39) {
      // Up and Right Arrows
      event.preventDefault();
      this.stepForward();
    }
  };

  /**
   * Handle on blur for slider
   *
   * @method handleBlur
   */

  Slider.prototype.handleBlur = function handleBlur() {
    this.off(_globalDocument2['default'], 'keydown', this.handleKeyPress);
  };

  /**
   * Listener for click events on slider, used to prevent clicks
   *   from bubbling up to parent elements like button menus.
   *
   * @param {Object} event Event object
   * @method handleClick
   */

  Slider.prototype.handleClick = function handleClick(event) {
    event.stopImmediatePropagation();
    event.preventDefault();
  };

  /**
   * Get/set if slider is horizontal for vertical
   *
   * @param {Boolean} bool True if slider is vertical, false is horizontal
   * @return {Boolean} True if slider is vertical, false is horizontal
   * @method vertical
   */

  Slider.prototype.vertical = function vertical(bool) {
    if (bool === undefined) {
      return this.vertical_ || false;
    }

    this.vertical_ = !!bool;

    if (this.vertical_) {
      this.addClass('vjs-slider-vertical');
    } else {
      this.addClass('vjs-slider-horizontal');
    }

    return this;
  };

  return Slider;
})(_componentJs2['default']);

_componentJs2['default'].registerComponent('Slider', Slider);
exports['default'] = Slider;
module.exports = exports['default'];

},{"../component.js":67,"../utils/dom.js":132,"global/document":1,"object.assign":45}],115:[function(_dereq_,module,exports){
/**
 * @file flash-rtmp.js
 */
'use strict';

exports.__esModule = true;
function FlashRtmpDecorator(Flash) {
  Flash.streamingFormats = {
    'rtmp/mp4': 'MP4',
    'rtmp/flv': 'FLV'
  };

  Flash.streamFromParts = function (connection, stream) {
    return connection + '&' + stream;
  };

  Flash.streamToParts = function (src) {
    var parts = {
      connection: '',
      stream: ''
    };

    if (!src) return parts;

    // Look for the normal URL separator we expect, '&'.
    // If found, we split the URL into two pieces around the
    // first '&'.
    var connEnd = src.search(/&(?!\w+=)/);
    var streamBegin = undefined;
    if (connEnd !== -1) {
      streamBegin = connEnd + 1;
    } else {
      // If there's not a '&', we use the last '/' as the delimiter.
      connEnd = streamBegin = src.lastIndexOf('/') + 1;
      if (connEnd === 0) {
        // really, there's not a '/'?
        connEnd = streamBegin = src.length;
      }
    }
    parts.connection = src.substring(0, connEnd);
    parts.stream = src.substring(streamBegin, src.length);

    return parts;
  };

  Flash.isStreamingType = function (srcType) {
    return srcType in Flash.streamingFormats;
  };

  // RTMP has four variations, any string starting
  // with one of these protocols should be valid
  Flash.RTMP_RE = /^rtmp[set]?:\/\//i;

  Flash.isStreamingSrc = function (src) {
    return Flash.RTMP_RE.test(src);
  };

  /**
   * A source handler for RTMP urls
   * @type {Object}
   */
  Flash.rtmpSourceHandler = {};

  /**
   * Check if Flash can play the given videotype
   * @param  {String} type    The mimetype to check
   * @return {String}         'probably', 'maybe', or '' (empty string)
   */
  Flash.rtmpSourceHandler.canPlayType = function (type) {
    if (Flash.isStreamingType(type)) {
      return 'maybe';
    }

    return '';
  };

  /**
   * Check if Flash can handle the source natively
   * @param  {Object} source  The source object
   * @return {String}         'probably', 'maybe', or '' (empty string)
   */
  Flash.rtmpSourceHandler.canHandleSource = function (source) {
    var can = Flash.rtmpSourceHandler.canPlayType(source.type);

    if (can) {
      return can;
    }

    if (Flash.isStreamingSrc(source.src)) {
      return 'maybe';
    }

    return '';
  };

  /**
   * Pass the source to the flash object
   * Adaptive source handlers will have more complicated workflows before passing
   * video data to the video element
   * @param  {Object} source    The source object
   * @param  {Flash} tech   The instance of the Flash tech
   */
  Flash.rtmpSourceHandler.handleSource = function (source, tech) {
    var srcParts = Flash.streamToParts(source.src);

    tech['setRtmpConnection'](srcParts.connection);
    tech['setRtmpStream'](srcParts.stream);
  };

  // Register the native source handler
  Flash.registerSourceHandler(Flash.rtmpSourceHandler);

  return Flash;
}

exports['default'] = FlashRtmpDecorator;
module.exports = exports['default'];

},{}],116:[function(_dereq_,module,exports){
/**
 * @file flash.js
 * VideoJS-SWF - Custom Flash Player with HTML5-ish API
 * https://github.com/zencoder/video-js-swf
 * Not using setupTriggers. Using global onEvent func to distribute events
 */

'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _tech = _dereq_('./tech');

var _tech2 = _interopRequireDefault(_tech);

var _utilsDomJs = _dereq_('../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsUrlJs = _dereq_('../utils/url.js');

var Url = _interopRequireWildcard(_utilsUrlJs);

var _utilsTimeRangesJs = _dereq_('../utils/time-ranges.js');

var _flashRtmp = _dereq_('./flash-rtmp');

var _flashRtmp2 = _interopRequireDefault(_flashRtmp);

var _component = _dereq_('../component');

var _component2 = _interopRequireDefault(_component);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

var _objectAssign = _dereq_('object.assign');

var _objectAssign2 = _interopRequireDefault(_objectAssign);

var navigator = _globalWindow2['default'].navigator;
/**
 * Flash Media Controller - Wrapper for fallback SWF API
 *
 * @param {Object=} options Object of option names and values
 * @param {Function=} ready Ready callback function
 * @extends Tech
 * @class Flash
 */

var Flash = (function (_Tech) {
  _inherits(Flash, _Tech);

  function Flash(options, ready) {
    _classCallCheck(this, Flash);

    _Tech.call(this, options, ready);

    // Set the source when ready
    if (options.source) {
      this.ready(function () {
        this.setSource(options.source);
      }, true);
    }

    // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers
    // This allows resetting the playhead when we catch the reload
    if (options.startTime) {
      this.ready(function () {
        this.load();
        this.play();
        this.currentTime(options.startTime);
      }, true);
    }

    // Add global window functions that the swf expects
    // A 4.x workflow we weren't able to solve for in 5.0
    // because of the need to hard code these functions
    // into the swf for security reasons
    _globalWindow2['default'].videojs = _globalWindow2['default'].videojs || {};
    _globalWindow2['default'].videojs.Flash = _globalWindow2['default'].videojs.Flash || {};
    _globalWindow2['default'].videojs.Flash.onReady = Flash.onReady;
    _globalWindow2['default'].videojs.Flash.onEvent = Flash.onEvent;
    _globalWindow2['default'].videojs.Flash.onError = Flash.onError;

    this.on('seeked', function () {
      this.lastSeekTarget_ = undefined;
    });
  }

  // Create setters and getters for attributes

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  Flash.prototype.createEl = function createEl() {
    var options = this.options_;

    // If video.js is hosted locally you should also set the location
    // for the hosted swf, which should be relative to the page (not video.js)
    // Otherwise this adds a CDN url.
    // The CDN also auto-adds a swf URL for that specific version.
    if (!options.swf) {
      options.swf = '//vjs.zencdn.net/swf/5.0.1/video-js.swf';
    }

    // Generate ID for swf object
    var objId = options.techId;

    // Merge default flashvars with ones passed in to init
    var flashVars = _objectAssign2['default']({

      // SWF Callback Functions
      'readyFunction': 'videojs.Flash.onReady',
      'eventProxyFunction': 'videojs.Flash.onEvent',
      'errorEventProxyFunction': 'videojs.Flash.onError',

      // Player Settings
      'autoplay': options.autoplay,
      'preload': options.preload,
      'loop': options.loop,
      'muted': options.muted

    }, options.flashVars);

    // Merge default parames with ones passed in
    var params = _objectAssign2['default']({
      'wmode': 'opaque', // Opaque is needed to overlay controls, but can affect playback performance
      'bgcolor': '#000000' // Using bgcolor prevents a white flash when the object is loading
    }, options.params);

    // Merge default attributes with ones passed in
    var attributes = _objectAssign2['default']({
      'id': objId,
      'name': objId, // Both ID and Name needed or swf to identify itself
      'class': 'vjs-tech'
    }, options.attributes);

    this.el_ = Flash.embed(options.swf, flashVars, params, attributes);
    this.el_.tech = this;

    return this.el_;
  };

  /**
   * Play for flash tech
   *
   * @method play
   */

  Flash.prototype.play = function play() {
    if (this.ended()) {
      this.setCurrentTime(0);
    }
    this.el_.vjs_play();
  };

  /**
   * Pause for flash tech
   *
   * @method pause
   */

  Flash.prototype.pause = function pause() {
    this.el_.vjs_pause();
  };

  /**
   * Get/set video
   *
   * @param {Object=} src Source object
   * @return {Object}
   * @method src
   */

  Flash.prototype.src = function src(_src) {
    if (_src === undefined) {
      return this.currentSrc();
    }

    // Setting src through `src` not `setSrc` will be deprecated
    return this.setSrc(_src);
  };

  /**
   * Set video
   *
   * @param {Object=} src Source object
   * @deprecated
   * @method setSrc
   */

  Flash.prototype.setSrc = function setSrc(src) {
    // Make sure source URL is absolute.
    src = Url.getAbsoluteURL(src);
    this.el_.vjs_src(src);

    // Currently the SWF doesn't autoplay if you load a source later.
    // e.g. Load player w/ no source, wait 2s, set src.
    if (this.autoplay()) {
      var tech = this;
      this.setTimeout(function () {
        tech.play();
      }, 0);
    }
  };

  /**
   * Returns true if the tech is currently seeking.
   * @return {boolean} true if seeking
   */

  Flash.prototype.seeking = function seeking() {
    return this.lastSeekTarget_ !== undefined;
  };

  /**
   * Set current time
   *
   * @param {Number} time Current time of video
   * @method setCurrentTime
   */

  Flash.prototype.setCurrentTime = function setCurrentTime(time) {
    var seekable = this.seekable();
    if (seekable.length) {
      // clamp to the current seekable range
      time = time > seekable.start(0) ? time : seekable.start(0);
      time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1);

      this.lastSeekTarget_ = time;
      this.trigger('seeking');
      this.el_.vjs_setProperty('currentTime', time);
      _Tech.prototype.setCurrentTime.call(this);
    }
  };

  /**
   * Get current time
   *
   * @param {Number=} time Current time of video
   * @return {Number} Current time
   * @method currentTime
   */

  Flash.prototype.currentTime = function currentTime(time) {
    // when seeking make the reported time keep up with the requested time
    // by reading the time we're seeking to
    if (this.seeking()) {
      return this.lastSeekTarget_ || 0;
    }
    return this.el_.vjs_getProperty('currentTime');
  };

  /**
   * Get current source
   *
   * @method currentSrc
   */

  Flash.prototype.currentSrc = function currentSrc() {
    if (this.currentSource_) {
      return this.currentSource_.src;
    } else {
      return this.el_.vjs_getProperty('currentSrc');
    }
  };

  /**
   * Load media into player
   *
   * @method load
   */

  Flash.prototype.load = function load() {
    this.el_.vjs_load();
  };

  /**
   * Get poster
   *
   * @method poster
   */

  Flash.prototype.poster = function poster() {
    this.el_.vjs_getProperty('poster');
  };

  /**
   * Poster images are not handled by the Flash tech so make this a no-op
   *
   * @method setPoster
   */

  Flash.prototype.setPoster = function setPoster() {};

  /**
   * Determine if can seek in media
   *
   * @return {TimeRangeObject}
   * @method seekable
   */

  Flash.prototype.seekable = function seekable() {
    var duration = this.duration();
    if (duration === 0) {
      return _utilsTimeRangesJs.createTimeRange();
    }
    return _utilsTimeRangesJs.createTimeRange(0, duration);
  };

  /**
   * Get buffered time range
   *
   * @return {TimeRangeObject}
   * @method buffered
   */

  Flash.prototype.buffered = function buffered() {
    var ranges = this.el_.vjs_getProperty('buffered');
    if (ranges.length === 0) {
      return _utilsTimeRangesJs.createTimeRange();
    }
    return _utilsTimeRangesJs.createTimeRange(ranges[0][0], ranges[0][1]);
  };

  /**
   * Get fullscreen support -
   * Flash does not allow fullscreen through javascript
   * so always returns false
   *
   * @return {Boolean} false
   * @method supportsFullScreen
   */

  Flash.prototype.supportsFullScreen = function supportsFullScreen() {
    return false; // Flash does not allow fullscreen through javascript
  };

  /**
   * Request to enter fullscreen
   * Flash does not allow fullscreen through javascript
   * so always returns false
   *
   * @return {Boolean} false
   * @method enterFullScreen
   */

  Flash.prototype.enterFullScreen = function enterFullScreen() {
    return false;
  };

  return Flash;
})(_tech2['default']);

var _api = Flash.prototype;
var _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(',');
var _readOnly = 'networkState,readyState,initialTime,duration,startOffsetTime,paused,ended,videoTracks,audioTracks,videoWidth,videoHeight'.split(',');

function _createSetter(attr) {
  var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
  _api['set' + attrUpper] = function (val) {
    return this.el_.vjs_setProperty(attr, val);
  };
}
function _createGetter(attr) {
  _api[attr] = function () {
    return this.el_.vjs_getProperty(attr);
  };
}

// Create getter and setters for all read/write attributes
for (var i = 0; i < _readWrite.length; i++) {
  _createGetter(_readWrite[i]);
  _createSetter(_readWrite[i]);
}

// Create getters for read-only attributes
for (var i = 0; i < _readOnly.length; i++) {
  _createGetter(_readOnly[i]);
}

/* Flash Support Testing -------------------------------------------------------- */

Flash.isSupported = function () {
  return Flash.version()[0] >= 10;
  // return swfobject.hasFlashPlayerVersion('10');
};

// Add Source Handler pattern functions to this tech
_tech2['default'].withSourceHandlers(Flash);

/*
 * The default native source handler.
 * This simply passes the source to the video element. Nothing fancy.
 *
 * @param  {Object} source   The source object
 * @param  {Flash} tech  The instance of the Flash tech
 */
Flash.nativeSourceHandler = {};

/**
 * Check if Flash can play the given videotype
 * @param  {String} type    The mimetype to check
 * @return {String}         'probably', 'maybe', or '' (empty string)
 */
Flash.nativeSourceHandler.canPlayType = function (type) {
  if (type in Flash.formats) {
    return 'maybe';
  }

  return '';
};

/*
 * Check Flash can handle the source natively
 *
 * @param  {Object} source  The source object
 * @return {String}         'probably', 'maybe', or '' (empty string)
 */
Flash.nativeSourceHandler.canHandleSource = function (source) {
  var type;

  function guessMimeType(src) {
    var ext = Url.getFileExtension(src);
    if (ext) {
      return 'video/' + ext;
    }
    return '';
  }

  if (!source.type) {
    type = guessMimeType(source.src);
  } else {
    // Strip code information from the type because we don't get that specific
    type = source.type.replace(/;.*/, '').toLowerCase();
  }

  return Flash.nativeSourceHandler.canPlayType(type);
};

/*
 * Pass the source to the flash object
 * Adaptive source handlers will have more complicated workflows before passing
 * video data to the video element
 *
 * @param  {Object} source    The source object
 * @param  {Flash} tech   The instance of the Flash tech
 */
Flash.nativeSourceHandler.handleSource = function (source, tech) {
  tech.setSrc(source.src);
};

/*
 * Clean up the source handler when disposing the player or switching sources..
 * (no cleanup is needed when supporting the format natively)
 */
Flash.nativeSourceHandler.dispose = function () {};

// Register the native source handler
Flash.registerSourceHandler(Flash.nativeSourceHandler);

Flash.formats = {
  'video/flv': 'FLV',
  'video/x-flv': 'FLV',
  'video/mp4': 'MP4',
  'video/m4v': 'MP4'
};

Flash.onReady = function (currSwf) {
  var el = Dom.getEl(currSwf);
  var tech = el && el.tech;

  // if there is no el then the tech has been disposed
  // and the tech element was removed from the player div
  if (tech && tech.el()) {
    // check that the flash object is really ready
    Flash.checkReady(tech);
  }
};

// The SWF isn't always ready when it says it is. Sometimes the API functions still need to be added to the object.
// If it's not ready, we set a timeout to check again shortly.
Flash.checkReady = function (tech) {
  // stop worrying if the tech has been disposed
  if (!tech.el()) {
    return;
  }

  // check if API property exists
  if (tech.el().vjs_getProperty) {
    // tell tech it's ready
    tech.triggerReady();
  } else {
    // wait longer
    this.setTimeout(function () {
      Flash['checkReady'](tech);
    }, 50);
  }
};

// Trigger events from the swf on the player
Flash.onEvent = function (swfID, eventName) {
  var tech = Dom.getEl(swfID).tech;
  tech.trigger(eventName);
};

// Log errors from the swf
Flash.onError = function (swfID, err) {
  var tech = Dom.getEl(swfID).tech;

  // trigger MEDIA_ERR_SRC_NOT_SUPPORTED
  if (err === 'srcnotfound') {
    return tech.error(4);
  }

  // trigger a custom error
  tech.error('FLASH: ' + err);
};

// Flash Version Check
Flash.version = function () {
  var version = '0,0,0';

  // IE
  try {
    version = new _globalWindow2['default'].ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];

    // other browsers
  } catch (e) {
    try {
      if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) {
        version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
      }
    } catch (err) {}
  }
  return version.split(',');
};

// Flash embedding method. Only used in non-iframe mode
Flash.embed = function (swf, flashVars, params, attributes) {
  var code = Flash.getEmbedCode(swf, flashVars, params, attributes);

  // Get element by embedding code and retrieving created element
  var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0];

  return obj;
};

Flash.getEmbedCode = function (swf, flashVars, params, attributes) {
  var objTag = '<object type="application/x-shockwave-flash" ';
  var flashVarsString = '';
  var paramsString = '';
  var attrsString = '';

  // Convert flash vars to string
  if (flashVars) {
    Object.getOwnPropertyNames(flashVars).forEach(function (key) {
      flashVarsString += key + '=' + flashVars[key] + '&amp;';
    });
  }

  // Add swf, flashVars, and other default params
  params = _objectAssign2['default']({
    'movie': swf,
    'flashvars': flashVarsString,
    'allowScriptAccess': 'always', // Required to talk to swf
    'allowNetworking': 'all' // All should be default, but having security issues.
  }, params);

  // Create param tags string
  Object.getOwnPropertyNames(params).forEach(function (key) {
    paramsString += '<param name="' + key + '" value="' + params[key] + '" />';
  });

  attributes = _objectAssign2['default']({
    // Add swf to attributes (need both for IE and Others to work)
    'data': swf,

    // Default to 100% width/height
    'width': '100%',
    'height': '100%'

  }, attributes);

  // Create Attributes string
  Object.getOwnPropertyNames(attributes).forEach(function (key) {
    attrsString += key + '="' + attributes[key] + '" ';
  });

  return '' + objTag + attrsString + '>' + paramsString + '</object>';
};

// Run Flash through the RTMP decorator
_flashRtmp2['default'](Flash);

_component2['default'].registerComponent('Flash', Flash);
_tech2['default'].registerTech('Flash', Flash);
exports['default'] = Flash;
module.exports = exports['default'];

},{"../component":67,"../utils/dom.js":132,"../utils/time-ranges.js":140,"../utils/url.js":142,"./flash-rtmp":115,"./tech":119,"global/window":2,"object.assign":45}],117:[function(_dereq_,module,exports){
/**
 * @file html5.js
 * HTML5 Media Controller - Wrapper for HTML5 Media API
 */

'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _techJs = _dereq_('./tech.js');

var _techJs2 = _interopRequireDefault(_techJs);

var _component = _dereq_('../component');

var _component2 = _interopRequireDefault(_component);

var _utilsDomJs = _dereq_('../utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsUrlJs = _dereq_('../utils/url.js');

var Url = _interopRequireWildcard(_utilsUrlJs);

var _utilsFnJs = _dereq_('../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsLogJs = _dereq_('../utils/log.js');

var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);

var _utilsBrowserJs = _dereq_('../utils/browser.js');

var browser = _interopRequireWildcard(_utilsBrowserJs);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

var _objectAssign = _dereq_('object.assign');

var _objectAssign2 = _interopRequireDefault(_objectAssign);

var _utilsMergeOptionsJs = _dereq_('../utils/merge-options.js');

var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);

/**
 * HTML5 Media Controller - Wrapper for HTML5 Media API
 *
 * @param {Object=} options Object of option names and values
 * @param {Function=} ready Ready callback function
 * @extends Tech
 * @class Html5
 */

var Html5 = (function (_Tech) {
  _inherits(Html5, _Tech);

  function Html5(options, ready) {
    _classCallCheck(this, Html5);

    _Tech.call(this, options, ready);

    var source = options.source;

    // Set the source if one is provided
    // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted)
    // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source
    // anyway so the error gets fired.
    if (source && (this.el_.currentSrc !== source.src || options.tag && options.tag.initNetworkState_ === 3)) {
      this.setSource(source);
    } else {
      this.handleLateInit_(this.el_);
    }

    if (this.el_.hasChildNodes()) {

      var nodes = this.el_.childNodes;
      var nodesLength = nodes.length;
      var removeNodes = [];

      while (nodesLength--) {
        var node = nodes[nodesLength];
        var nodeName = node.nodeName.toLowerCase();

        if (nodeName === 'track') {
          if (!this.featuresNativeTextTracks) {
            // Empty video tag tracks so the built-in player doesn't use them also.
            // This may not be fast enough to stop HTML5 browsers from reading the tags
            // so we'll need to turn off any default tracks if we're manually doing
            // captions and subtitles. videoElement.textTracks
            removeNodes.push(node);
          } else {
            // store HTMLTrackElement and TextTrack to remote list
            this.remoteTextTrackEls().addTrackElement_(node);
            this.remoteTextTracks().addTrack_(node.track);
          }
        }
      }

      for (var i = 0; i < removeNodes.length; i++) {
        this.el_.removeChild(removeNodes[i]);
      }
    }

    if (this.featuresNativeTextTracks) {
      this.handleTextTrackChange_ = Fn.bind(this, this.handleTextTrackChange);
      this.handleTextTrackAdd_ = Fn.bind(this, this.handleTextTrackAdd);
      this.handleTextTrackRemove_ = Fn.bind(this, this.handleTextTrackRemove);
      this.proxyNativeTextTracks_();
    }

    // Determine if native controls should be used
    // Our goal should be to get the custom controls on mobile solid everywhere
    // so we can remove this all together. Right now this will block custom
    // controls on touch enabled laptops like the Chrome Pixel
    if (browser.TOUCH_ENABLED && options.nativeControlsForTouch === true || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) {
      this.setControls(true);
    }

    this.triggerReady();
  }

  /* HTML5 Support Testing ---------------------------------------------------- */

  /*
  * Element for testing browser HTML5 video capabilities
  *
  * @type {Element}
  * @constant
  * @private
  */

  /**
   * Dispose of html5 media element
   *
   * @method dispose
   */

  Html5.prototype.dispose = function dispose() {
    var tt = this.el().textTracks;
    var emulatedTt = this.textTracks();

    // remove native event listeners
    if (tt && tt.removeEventListener) {
      tt.removeEventListener('change', this.handleTextTrackChange_);
      tt.removeEventListener('addtrack', this.handleTextTrackAdd_);
      tt.removeEventListener('removetrack', this.handleTextTrackRemove_);
    }

    // clearout the emulated text track list.
    var i = emulatedTt.length;

    while (i--) {
      emulatedTt.removeTrack_(emulatedTt[i]);
    }

    Html5.disposeMediaElement(this.el_);
    _Tech.prototype.dispose.call(this);
  };

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  Html5.prototype.createEl = function createEl() {
    var el = this.options_.tag;

    // Check if this browser supports moving the element into the box.
    // On the iPhone video will break if you move the element,
    // So we have to create a brand new element.
    if (!el || this['movingMediaElementInDOM'] === false) {

      // If the original tag is still there, clone and remove it.
      if (el) {
        var clone = el.cloneNode(true);
        el.parentNode.insertBefore(clone, el);
        Html5.disposeMediaElement(el);
        el = clone;
      } else {
        el = _globalDocument2['default'].createElement('video');

        // determine if native controls should be used
        var tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag);
        var attributes = _utilsMergeOptionsJs2['default']({}, tagAttributes);
        if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) {
          delete attributes.controls;
        }

        Dom.setElAttributes(el, _objectAssign2['default'](attributes, {
          id: this.options_.techId,
          'class': 'vjs-tech'
        }));
      }
    }

    // Update specific tag settings, in case they were overridden
    var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted'];
    for (var i = settingsAttrs.length - 1; i >= 0; i--) {
      var attr = settingsAttrs[i];
      var overwriteAttrs = {};
      if (typeof this.options_[attr] !== 'undefined') {
        overwriteAttrs[attr] = this.options_[attr];
      }
      Dom.setElAttributes(el, overwriteAttrs);
    }

    return el;
    // jenniisawesome = true;
  };

  // If we're loading the playback object after it has started loading
  // or playing the video (often with autoplay on) then the loadstart event
  // has already fired and we need to fire it manually because many things
  // rely on it.

  Html5.prototype.handleLateInit_ = function handleLateInit_(el) {
    var _this = this;

    if (el.networkState === 0 || el.networkState === 3) {
      // The video element hasn't started loading the source yet
      // or didn't find a source
      return;
    }

    if (el.readyState === 0) {
      var _ret = (function () {
        // NetworkState is set synchronously BUT loadstart is fired at the
        // end of the current stack, usually before setInterval(fn, 0).
        // So at this point we know loadstart may have already fired or is
        // about to fire, and either way the player hasn't seen it yet.
        // We don't want to fire loadstart prematurely here and cause a
        // double loadstart so we'll wait and see if it happens between now
        // and the next loop, and fire it if not.
        // HOWEVER, we also want to make sure it fires before loadedmetadata
        // which could also happen between now and the next loop, so we'll
        // watch for that also.
        var loadstartFired = false;
        var setLoadstartFired = function setLoadstartFired() {
          loadstartFired = true;
        };
        _this.on('loadstart', setLoadstartFired);

        var triggerLoadstart = function triggerLoadstart() {
          // We did miss the original loadstart. Make sure the player
          // sees loadstart before loadedmetadata
          if (!loadstartFired) {
            this.trigger('loadstart');
          }
        };
        _this.on('loadedmetadata', triggerLoadstart);

        _this.ready(function () {
          this.off('loadstart', setLoadstartFired);
          this.off('loadedmetadata', triggerLoadstart);

          if (!loadstartFired) {
            // We did miss the original native loadstart. Fire it now.
            this.trigger('loadstart');
          }
        });

        return {
          v: undefined
        };
      })();

      if (typeof _ret === 'object') return _ret.v;
    }

    // From here on we know that loadstart already fired and we missed it.
    // The other readyState events aren't as much of a problem if we double
    // them, so not going to go to as much trouble as loadstart to prevent
    // that unless we find reason to.
    var eventsToTrigger = ['loadstart'];

    // loadedmetadata: newly equal to HAVE_METADATA (1) or greater
    eventsToTrigger.push('loadedmetadata');

    // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater
    if (el.readyState >= 2) {
      eventsToTrigger.push('loadeddata');
    }

    // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater
    if (el.readyState >= 3) {
      eventsToTrigger.push('canplay');
    }

    // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4)
    if (el.readyState >= 4) {
      eventsToTrigger.push('canplaythrough');
    }

    // We still need to give the player time to add event listeners
    this.ready(function () {
      eventsToTrigger.forEach(function (type) {
        this.trigger(type);
      }, this);
    });
  };

  Html5.prototype.proxyNativeTextTracks_ = function proxyNativeTextTracks_() {
    var tt = this.el().textTracks;

    if (tt) {
      // Add tracks - if player is initialised after DOM loaded, textTracks
      // will not trigger addtrack
      for (var i = 0; i < tt.length; i++) {
        this.textTracks().addTrack_(tt[i]);
      }

      if (tt.addEventListener) {
        tt.addEventListener('change', this.handleTextTrackChange_);
        tt.addEventListener('addtrack', this.handleTextTrackAdd_);
        tt.addEventListener('removetrack', this.handleTextTrackRemove_);
      }
    }
  };

  Html5.prototype.handleTextTrackChange = function handleTextTrackChange(e) {
    var tt = this.textTracks();
    this.textTracks().trigger({
      type: 'change',
      target: tt,
      currentTarget: tt,
      srcElement: tt
    });
  };

  Html5.prototype.handleTextTrackAdd = function handleTextTrackAdd(e) {
    this.textTracks().addTrack_(e.track);
  };

  Html5.prototype.handleTextTrackRemove = function handleTextTrackRemove(e) {
    this.textTracks().removeTrack_(e.track);
  };

  /**
   * Play for html5 tech
   *
   * @method play
   */

  Html5.prototype.play = function play() {
    this.el_.play();
  };

  /**
   * Pause for html5 tech
   *
   * @method pause
   */

  Html5.prototype.pause = function pause() {
    this.el_.pause();
  };

  /**
   * Paused for html5 tech
   *
   * @return {Boolean}
   * @method paused
   */

  Html5.prototype.paused = function paused() {
    return this.el_.paused;
  };

  /**
   * Get current time
   *
   * @return {Number}
   * @method currentTime
   */

  Html5.prototype.currentTime = function currentTime() {
    return this.el_.currentTime;
  };

  /**
   * Set current time
   *
   * @param {Number} seconds Current time of video
   * @method setCurrentTime
   */

  Html5.prototype.setCurrentTime = function setCurrentTime(seconds) {
    try {
      this.el_.currentTime = seconds;
    } catch (e) {
      _utilsLogJs2['default'](e, 'Video is not ready. (Video.js)');
      // this.warning(VideoJS.warnings.videoNotReady);
    }
  };

  /**
   * Get duration
   *
   * @return {Number}
   * @method duration
   */

  Html5.prototype.duration = function duration() {
    return this.el_.duration || 0;
  };

  /**
   * Get a TimeRange object that represents the intersection
   * of the time ranges for which the user agent has all
   * relevant media
   *
   * @return {TimeRangeObject}
   * @method buffered
   */

  Html5.prototype.buffered = function buffered() {
    return this.el_.buffered;
  };

  /**
   * Get volume level
   *
   * @return {Number}
   * @method volume
   */

  Html5.prototype.volume = function volume() {
    return this.el_.volume;
  };

  /**
   * Set volume level
   *
   * @param {Number} percentAsDecimal Volume percent as a decimal
   * @method setVolume
   */

  Html5.prototype.setVolume = function setVolume(percentAsDecimal) {
    this.el_.volume = percentAsDecimal;
  };

  /**
   * Get if muted
   *
   * @return {Boolean}
   * @method muted
   */

  Html5.prototype.muted = function muted() {
    return this.el_.muted;
  };

  /**
   * Set muted
   *
   * @param {Boolean} If player is to be muted or note
   * @method setMuted
   */

  Html5.prototype.setMuted = function setMuted(muted) {
    this.el_.muted = muted;
  };

  /**
   * Get player width
   *
   * @return {Number}
   * @method width
   */

  Html5.prototype.width = function width() {
    return this.el_.offsetWidth;
  };

  /**
   * Get player height
   *
   * @return {Number}
   * @method height
   */

  Html5.prototype.height = function height() {
    return this.el_.offsetHeight;
  };

  /**
   * Get if there is fullscreen support
   *
   * @return {Boolean}
   * @method supportsFullScreen
   */

  Html5.prototype.supportsFullScreen = function supportsFullScreen() {
    if (typeof this.el_.webkitEnterFullScreen === 'function') {
      var userAgent = _globalWindow2['default'].navigator.userAgent;
      // Seems to be broken in Chromium/Chrome && Safari in Leopard
      if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) {
        return true;
      }
    }
    return false;
  };

  /**
   * Request to enter fullscreen
   *
   * @method enterFullScreen
   */

  Html5.prototype.enterFullScreen = function enterFullScreen() {
    var video = this.el_;

    if ('webkitDisplayingFullscreen' in video) {
      this.one('webkitbeginfullscreen', function () {
        this.one('webkitendfullscreen', function () {
          this.trigger('fullscreenchange', { isFullscreen: false });
        });

        this.trigger('fullscreenchange', { isFullscreen: true });
      });
    }

    if (video.paused && video.networkState <= video.HAVE_METADATA) {
      // attempt to prime the video element for programmatic access
      // this isn't necessary on the desktop but shouldn't hurt
      this.el_.play();

      // playing and pausing synchronously during the transition to fullscreen
      // can get iOS ~6.1 devices into a play/pause loop
      this.setTimeout(function () {
        video.pause();
        video.webkitEnterFullScreen();
      }, 0);
    } else {
      video.webkitEnterFullScreen();
    }
  };

  /**
   * Request to exit fullscreen
   *
   * @method exitFullScreen
   */

  Html5.prototype.exitFullScreen = function exitFullScreen() {
    this.el_.webkitExitFullScreen();
  };

  /**
   * Get/set video
   *
   * @param {Object=} src Source object
   * @return {Object}
   * @method src
   */

  Html5.prototype.src = function src(_src) {
    if (_src === undefined) {
      return this.el_.src;
    } else {
      // Setting src through `src` instead of `setSrc` will be deprecated
      this.setSrc(_src);
    }
  };

  /**
   * Set video
   *
   * @param {Object} src Source object
   * @deprecated
   * @method setSrc
   */

  Html5.prototype.setSrc = function setSrc(src) {
    this.el_.src = src;
  };

  /**
   * Load media into player
   *
   * @method load
   */

  Html5.prototype.load = function load() {
    this.el_.load();
  };

  /**
   * Reset the tech. Removes all sources and calls `load`.
   *
   * @method reset
   */

  Html5.prototype.reset = function reset() {
    Html5.resetMediaElement(this.el_);
  };

  /**
   * Get current source
   *
   * @return {Object}
   * @method currentSrc
   */

  Html5.prototype.currentSrc = function currentSrc() {
    if (this.currentSource_) {
      return this.currentSource_.src;
    } else {
      return this.el_.currentSrc;
    }
  };

  /**
   * Get poster
   *
   * @return {String}
   * @method poster
   */

  Html5.prototype.poster = function poster() {
    return this.el_.poster;
  };

  /**
   * Set poster
   *
   * @param {String} val URL to poster image
   * @method
   */

  Html5.prototype.setPoster = function setPoster(val) {
    this.el_.poster = val;
  };

  /**
   * Get preload attribute
   *
   * @return {String}
   * @method preload
   */

  Html5.prototype.preload = function preload() {
    return this.el_.preload;
  };

  /**
   * Set preload attribute
   *
   * @param {String} val Value for preload attribute
   * @method setPreload
   */

  Html5.prototype.setPreload = function setPreload(val) {
    this.el_.preload = val;
  };

  /**
   * Get autoplay attribute
   *
   * @return {String}
   * @method autoplay
   */

  Html5.prototype.autoplay = function autoplay() {
    return this.el_.autoplay;
  };

  /**
   * Set autoplay attribute
   *
   * @param {String} val Value for preload attribute
   * @method setAutoplay
   */

  Html5.prototype.setAutoplay = function setAutoplay(val) {
    this.el_.autoplay = val;
  };

  /**
   * Get controls attribute
   *
   * @return {String}
   * @method controls
   */

  Html5.prototype.controls = function controls() {
    return this.el_.controls;
  };

  /**
   * Set controls attribute
   *
   * @param {String} val Value for controls attribute
   * @method setControls
   */

  Html5.prototype.setControls = function setControls(val) {
    this.el_.controls = !!val;
  };

  /**
   * Get loop attribute
   *
   * @return {String}
   * @method loop
   */

  Html5.prototype.loop = function loop() {
    return this.el_.loop;
  };

  /**
   * Set loop attribute
   *
   * @param {String} val Value for loop attribute
   * @method setLoop
   */

  Html5.prototype.setLoop = function setLoop(val) {
    this.el_.loop = val;
  };

  /**
   * Get error value
   *
   * @return {String}
   * @method error
   */

  Html5.prototype.error = function error() {
    return this.el_.error;
  };

  /**
   * Get whether or not the player is in the "seeking" state
   *
   * @return {Boolean}
   * @method seeking
   */

  Html5.prototype.seeking = function seeking() {
    return this.el_.seeking;
  };

  /**
   * Get a TimeRanges object that represents the
   * ranges of the media resource to which it is possible
   * for the user agent to seek.
   *
   * @return {TimeRangeObject}
   * @method seekable
   */

  Html5.prototype.seekable = function seekable() {
    return this.el_.seekable;
  };

  /**
   * Get if video ended
   *
   * @return {Boolean}
   * @method ended
   */

  Html5.prototype.ended = function ended() {
    return this.el_.ended;
  };

  /**
   * Get the value of the muted content attribute
   * This attribute has no dynamic effect, it only
   * controls the default state of the element
   *
   * @return {Boolean}
   * @method defaultMuted
   */

  Html5.prototype.defaultMuted = function defaultMuted() {
    return this.el_.defaultMuted;
  };

  /**
   * Get desired speed at which the media resource is to play
   *
   * @return {Number}
   * @method playbackRate
   */

  Html5.prototype.playbackRate = function playbackRate() {
    return this.el_.playbackRate;
  };

  /**
   * Returns a TimeRanges object that represents the ranges of the
   * media resource that the user agent has played.
   * @return {TimeRangeObject} the range of points on the media
   * timeline that has been reached through normal playback
   * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-played
   */

  Html5.prototype.played = function played() {
    return this.el_.played;
  };

  /**
   * Set desired speed at which the media resource is to play
   *
   * @param {Number} val Speed at which the media resource is to play
   * @method setPlaybackRate
   */

  Html5.prototype.setPlaybackRate = function setPlaybackRate(val) {
    this.el_.playbackRate = val;
  };

  /**
   * Get the current state of network activity for the element, from
   * the list below
   * NETWORK_EMPTY (numeric value 0)
   * NETWORK_IDLE (numeric value 1)
   * NETWORK_LOADING (numeric value 2)
   * NETWORK_NO_SOURCE (numeric value 3)
   *
   * @return {Number}
   * @method networkState
   */

  Html5.prototype.networkState = function networkState() {
    return this.el_.networkState;
  };

  /**
   * Get a value that expresses the current state of the element
   * with respect to rendering the current playback position, from
   * the codes in the list below
   * HAVE_NOTHING (numeric value 0)
   * HAVE_METADATA (numeric value 1)
   * HAVE_CURRENT_DATA (numeric value 2)
   * HAVE_FUTURE_DATA (numeric value 3)
   * HAVE_ENOUGH_DATA (numeric value 4)
   *
   * @return {Number}
   * @method readyState
   */

  Html5.prototype.readyState = function readyState() {
    return this.el_.readyState;
  };

  /**
   * Get width of video
   *
   * @return {Number}
   * @method videoWidth
   */

  Html5.prototype.videoWidth = function videoWidth() {
    return this.el_.videoWidth;
  };

  /**
   * Get height of video
   *
   * @return {Number}
   * @method videoHeight
   */

  Html5.prototype.videoHeight = function videoHeight() {
    return this.el_.videoHeight;
  };

  /**
   * Get text tracks
   *
   * @return {TextTrackList}
   * @method textTracks
   */

  Html5.prototype.textTracks = function textTracks() {
    return _Tech.prototype.textTracks.call(this);
  };

  /**
   * Creates and returns a text track object
   *
   * @param {String} kind Text track kind (subtitles, captions, descriptions
   *                                       chapters and metadata)
   * @param {String=} label Label to identify the text track
   * @param {String=} language Two letter language abbreviation
   * @return {TextTrackObject}
   * @method addTextTrack
   */

  Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) {
    if (!this['featuresNativeTextTracks']) {
      return _Tech.prototype.addTextTrack.call(this, kind, label, language);
    }

    return this.el_.addTextTrack(kind, label, language);
  };

  /**
   * Creates a remote text track object and returns a html track element
   *
   * @param {Object} options The object should contain values for
   * kind, language, label and src (location of the WebVTT file)
   * @return {HTMLTrackElement}
   * @method addRemoteTextTrack
   */

  Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack() {
    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];

    if (!this['featuresNativeTextTracks']) {
      return _Tech.prototype.addRemoteTextTrack.call(this, options);
    }

    var htmlTrackElement = _globalDocument2['default'].createElement('track');

    if (options.kind) {
      htmlTrackElement.kind = options.kind;
    }
    if (options.label) {
      htmlTrackElement.label = options.label;
    }
    if (options.language || options.srclang) {
      htmlTrackElement.srclang = options.language || options.srclang;
    }
    if (options['default']) {
      htmlTrackElement['default'] = options['default'];
    }
    if (options.id) {
      htmlTrackElement.id = options.id;
    }
    if (options.src) {
      htmlTrackElement.src = options.src;
    }

    this.el().appendChild(htmlTrackElement);

    // store HTMLTrackElement and TextTrack to remote list
    this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
    this.remoteTextTracks().addTrack_(htmlTrackElement.track);

    return htmlTrackElement;
  };

  /**
   * Remove remote text track from TextTrackList object
   *
   * @param {TextTrackObject} track Texttrack object to remove
   * @method removeRemoteTextTrack
   */

  Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
    if (!this['featuresNativeTextTracks']) {
      return _Tech.prototype.removeRemoteTextTrack.call(this, track);
    }

    var tracks = undefined,
        i = undefined;

    var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);

    // remove HTMLTrackElement and TextTrack from remote list
    this.remoteTextTrackEls().removeTrackElement_(trackElement);
    this.remoteTextTracks().removeTrack_(track);

    tracks = this.$$('track');

    i = tracks.length;
    while (i--) {
      if (track === tracks[i] || track === tracks[i].track) {
        this.el().removeChild(tracks[i]);
      }
    }
  };

  return Html5;
})(_techJs2['default']);

Html5.TEST_VID = _globalDocument2['default'].createElement('video');
var track = _globalDocument2['default'].createElement('track');
track.kind = 'captions';
track.srclang = 'en';
track.label = 'English';
Html5.TEST_VID.appendChild(track);

/*
 * Check if HTML5 video is supported by this browser/device
 *
 * @return {Boolean}
 */
Html5.isSupported = function () {
  // IE9 with no Media Player is a LIAR! (#984)
  try {
    Html5.TEST_VID['volume'] = 0.5;
  } catch (e) {
    return false;
  }

  return !!Html5.TEST_VID.canPlayType;
};

// Add Source Handler pattern functions to this tech
_techJs2['default'].withSourceHandlers(Html5);

/*
 * The default native source handler.
 * This simply passes the source to the video element. Nothing fancy.
 *
 * @param  {Object} source   The source object
 * @param  {Html5} tech  The instance of the HTML5 tech
 */
Html5.nativeSourceHandler = {};

/*
 * Check if the video element can play the given videotype
 *
 * @param  {String} type    The mimetype to check
 * @return {String}         'probably', 'maybe', or '' (empty string)
 */
Html5.nativeSourceHandler.canPlayType = function (type) {
  // IE9 on Windows 7 without MediaPlayer throws an error here
  // https://github.com/videojs/video.js/issues/519
  try {
    return Html5.TEST_VID.canPlayType(type);
  } catch (e) {
    return '';
  }
};

/*
 * Check if the video element can handle the source natively
 *
 * @param  {Object} source  The source object
 * @return {String}         'probably', 'maybe', or '' (empty string)
 */
Html5.nativeSourceHandler.canHandleSource = function (source) {
  var match, ext;

  // If a type was provided we should rely on that
  if (source.type) {
    return Html5.nativeSourceHandler.canPlayType(source.type);
  } else if (source.src) {
    // If no type, fall back to checking 'video/[EXTENSION]'
    ext = Url.getFileExtension(source.src);

    return Html5.nativeSourceHandler.canPlayType('video/' + ext);
  }

  return '';
};

/*
 * Pass the source to the video element
 * Adaptive source handlers will have more complicated workflows before passing
 * video data to the video element
 *
 * @param  {Object} source    The source object
 * @param  {Html5} tech   The instance of the Html5 tech
 */
Html5.nativeSourceHandler.handleSource = function (source, tech) {
  tech.setSrc(source.src);
};

/*
* Clean up the source handler when disposing the player or switching sources..
* (no cleanup is needed when supporting the format natively)
*/
Html5.nativeSourceHandler.dispose = function () {};

// Register the native source handler
Html5.registerSourceHandler(Html5.nativeSourceHandler);

/*
 * Check if the volume can be changed in this browser/device.
 * Volume cannot be changed in a lot of mobile devices.
 * Specifically, it can't be changed from 1 on iOS.
 *
 * @return {Boolean}
 */
Html5.canControlVolume = function () {
  var volume = Html5.TEST_VID.volume;
  Html5.TEST_VID.volume = volume / 2 + 0.1;
  return volume !== Html5.TEST_VID.volume;
};

/*
 * Check if playbackRate is supported in this browser/device.
 *
 * @return {Number} [description]
 */
Html5.canControlPlaybackRate = function () {
  var playbackRate = Html5.TEST_VID.playbackRate;
  Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1;
  return playbackRate !== Html5.TEST_VID.playbackRate;
};

/*
 * Check to see if native text tracks are supported by this browser/device
 *
 * @return {Boolean}
 */
Html5.supportsNativeTextTracks = function () {
  var supportsTextTracks;

  // Figure out native text track support
  // If mode is a number, we cannot change it because it'll disappear from view.
  // Browsers with numeric modes include IE10 and older (<=2013) samsung android models.
  // Firefox isn't playing nice either with modifying the mode
  // TODO: Investigate firefox: https://github.com/videojs/video.js/issues/1862
  supportsTextTracks = !!Html5.TEST_VID.textTracks;
  if (supportsTextTracks && Html5.TEST_VID.textTracks.length > 0) {
    supportsTextTracks = typeof Html5.TEST_VID.textTracks[0]['mode'] !== 'number';
  }
  if (supportsTextTracks && browser.IS_FIREFOX) {
    supportsTextTracks = false;
  }
  if (supportsTextTracks && !('onremovetrack' in Html5.TEST_VID.textTracks)) {
    supportsTextTracks = false;
  }

  return supportsTextTracks;
};

/**
 * An array of events available on the Html5 tech.
 *
 * @private
 * @type {Array}
 */
Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'volumechange'];

/*
 * Set the tech's volume control support status
 *
 * @type {Boolean}
 */
Html5.prototype['featuresVolumeControl'] = Html5.canControlVolume();

/*
 * Set the tech's playbackRate support status
 *
 * @type {Boolean}
 */
Html5.prototype['featuresPlaybackRate'] = Html5.canControlPlaybackRate();

/*
 * Set the tech's status on moving the video element.
 * In iOS, if you move a video element in the DOM, it breaks video playback.
 *
 * @type {Boolean}
 */
Html5.prototype['movingMediaElementInDOM'] = !browser.IS_IOS;

/*
 * Set the the tech's fullscreen resize support status.
 * HTML video is able to automatically resize when going to fullscreen.
 * (No longer appears to be used. Can probably be removed.)
 */
Html5.prototype['featuresFullscreenResize'] = true;

/*
 * Set the tech's progress event support status
 * (this disables the manual progress events of the Tech)
 */
Html5.prototype['featuresProgressEvents'] = true;

/*
 * Sets the tech's status on native text track support
 *
 * @type {Boolean}
 */
Html5.prototype['featuresNativeTextTracks'] = Html5.supportsNativeTextTracks();

// HTML5 Feature detection and Device Fixes --------------------------------- //
var canPlayType = undefined;
var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i;
var mp4RE = /^video\/mp4/i;

Html5.patchCanPlayType = function () {
  // Android 4.0 and above can play HLS to some extent but it reports being unable to do so
  if (browser.ANDROID_VERSION >= 4.0) {
    if (!canPlayType) {
      canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType;
    }

    Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
      if (type && mpegurlRE.test(type)) {
        return 'maybe';
      }
      return canPlayType.call(this, type);
    };
  }

  // Override Android 2.2 and less canPlayType method which is broken
  if (browser.IS_OLD_ANDROID) {
    if (!canPlayType) {
      canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType;
    }

    Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
      if (type && mp4RE.test(type)) {
        return 'maybe';
      }
      return canPlayType.call(this, type);
    };
  }
};

Html5.unpatchCanPlayType = function () {
  var r = Html5.TEST_VID.constructor.prototype.canPlayType;
  Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType;
  canPlayType = null;
  return r;
};

// by default, patch the video element
Html5.patchCanPlayType();

Html5.disposeMediaElement = function (el) {
  if (!el) {
    return;
  }

  if (el.parentNode) {
    el.parentNode.removeChild(el);
  }

  // remove any child track or source nodes to prevent their loading
  while (el.hasChildNodes()) {
    el.removeChild(el.firstChild);
  }

  // remove any src reference. not setting `src=''` because that causes a warning
  // in firefox
  el.removeAttribute('src');

  // force the media element to update its loading state by calling load()
  // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793)
  if (typeof el.load === 'function') {
    // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
    (function () {
      try {
        el.load();
      } catch (e) {
        // not supported
      }
    })();
  }
};

Html5.resetMediaElement = function (el) {
  if (!el) {
    return;
  }

  var sources = el.querySelectorAll('source');
  var i = sources.length;
  while (i--) {
    el.removeChild(sources[i]);
  }

  // remove any src reference.
  // not setting `src=''` because that throws an error
  el.removeAttribute('src');

  if (typeof el.load === 'function') {
    // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
    (function () {
      try {
        el.load();
      } catch (e) {}
    })();
  }
};

_component2['default'].registerComponent('Html5', Html5);
_techJs2['default'].registerTech('Html5', Html5);
exports['default'] = Html5;
module.exports = exports['default'];

},{"../component":67,"../utils/browser.js":129,"../utils/dom.js":132,"../utils/fn.js":134,"../utils/log.js":137,"../utils/merge-options.js":138,"../utils/url.js":142,"./tech.js":119,"global/document":1,"global/window":2,"object.assign":45}],118:[function(_dereq_,module,exports){
/**
 * @file loader.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _componentJs = _dereq_('../component.js');

var _componentJs2 = _interopRequireDefault(_componentJs);

var _techJs = _dereq_('./tech.js');

var _techJs2 = _interopRequireDefault(_techJs);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js');

var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);

/**
 * The Media Loader is the component that decides which playback technology to load
 * when the player is initialized.
 *
 * @param {Object} player  Main Player
 * @param {Object=} options Object of option names and values
 * @param {Function=} ready    Ready callback function
 * @extends Component
 * @class MediaLoader
 */

var MediaLoader = (function (_Component) {
  _inherits(MediaLoader, _Component);

  function MediaLoader(player, options, ready) {
    _classCallCheck(this, MediaLoader);

    _Component.call(this, player, options, ready);

    // If there are no sources when the player is initialized,
    // load the first supported playback technology.

    if (!options.playerOptions['sources'] || options.playerOptions['sources'].length === 0) {
      for (var i = 0, j = options.playerOptions['techOrder']; i < j.length; i++) {
        var techName = _utilsToTitleCaseJs2['default'](j[i]);
        var tech = _techJs2['default'].getTech(techName);
        // Support old behavior of techs being registered as components.
        // Remove once that deprecated behavior is removed.
        if (!techName) {
          tech = _componentJs2['default'].getComponent(techName);
        }

        // Check if the browser supports this technology
        if (tech && tech.isSupported()) {
          player.loadTech_(techName);
          break;
        }
      }
    } else {
      // // Loop through playback technologies (HTML5, Flash) and check for support.
      // // Then load the best source.
      // // A few assumptions here:
      // //   All playback technologies respect preload false.
      player.src(options.playerOptions['sources']);
    }
  }

  return MediaLoader;
})(_componentJs2['default']);

_componentJs2['default'].registerComponent('MediaLoader', MediaLoader);
exports['default'] = MediaLoader;
module.exports = exports['default'];

},{"../component.js":67,"../utils/to-title-case.js":141,"./tech.js":119,"global/window":2}],119:[function(_dereq_,module,exports){
/**
 * @file tech.js
 * Media Technology Controller - Base class for media playback
 * technology controllers like Flash and HTML5
 */

'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _component = _dereq_('../component');

var _component2 = _interopRequireDefault(_component);

var _tracksHtmlTrackElement = _dereq_('../tracks/html-track-element');

var _tracksHtmlTrackElement2 = _interopRequireDefault(_tracksHtmlTrackElement);

var _tracksHtmlTrackElementList = _dereq_('../tracks/html-track-element-list');

var _tracksHtmlTrackElementList2 = _interopRequireDefault(_tracksHtmlTrackElementList);

var _utilsMergeOptionsJs = _dereq_('../utils/merge-options.js');

var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);

var _tracksTextTrack = _dereq_('../tracks/text-track');

var _tracksTextTrack2 = _interopRequireDefault(_tracksTextTrack);

var _tracksTextTrackList = _dereq_('../tracks/text-track-list');

var _tracksTextTrackList2 = _interopRequireDefault(_tracksTextTrackList);

var _utilsFnJs = _dereq_('../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsLogJs = _dereq_('../utils/log.js');

var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);

var _utilsTimeRangesJs = _dereq_('../utils/time-ranges.js');

var _utilsBufferJs = _dereq_('../utils/buffer.js');

var _mediaErrorJs = _dereq_('../media-error.js');

var _mediaErrorJs2 = _interopRequireDefault(_mediaErrorJs);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

/**
 * Base class for media (HTML5 Video, Flash) controllers
 *
 * @param {Object=} options Options object
 * @param {Function=} ready Ready callback function
 * @extends Component
 * @class Tech
 */

var Tech = (function (_Component) {
  _inherits(Tech, _Component);

  function Tech() {
    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
    var ready = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];

    _classCallCheck(this, Tech);

    // we don't want the tech to report user activity automatically.
    // This is done manually in addControlsListeners
    options.reportTouchActivity = false;
    _Component.call(this, null, options, ready);

    // keep track of whether the current source has played at all to
    // implement a very limited played()
    this.hasStarted_ = false;
    this.on('playing', function () {
      this.hasStarted_ = true;
    });
    this.on('loadstart', function () {
      this.hasStarted_ = false;
    });

    this.textTracks_ = options.textTracks;

    // Manually track progress in cases where the browser/flash player doesn't report it.
    if (!this.featuresProgressEvents) {
      this.manualProgressOn();
    }

    // Manually track timeupdates in cases where the browser/flash player doesn't report it.
    if (!this.featuresTimeupdateEvents) {
      this.manualTimeUpdatesOn();
    }

    if (options.nativeCaptions === false || options.nativeTextTracks === false) {
      this.featuresNativeTextTracks = false;
    }

    if (!this.featuresNativeTextTracks) {
      this.on('ready', this.emulateTextTracks);
    }

    this.initTextTrackListeners();

    // Turn on component tap events
    this.emitTapEvents();
  }

  /*
   * List of associated text tracks
   *
   * @type {Array}
   * @private
   */

  /* Fallbacks for unsupported event types
  ================================================================================ */
  // Manually trigger progress events based on changes to the buffered amount
  // Many flash players and older HTML5 browsers don't send progress or progress-like events
  /**
   * Turn on progress events
   *
   * @method manualProgressOn
   */

  Tech.prototype.manualProgressOn = function manualProgressOn() {
    this.on('durationchange', this.onDurationChange);

    this.manualProgress = true;

    // Trigger progress watching when a source begins loading
    this.one('ready', this.trackProgress);
  };

  /**
   * Turn off progress events
   *
   * @method manualProgressOff
   */

  Tech.prototype.manualProgressOff = function manualProgressOff() {
    this.manualProgress = false;
    this.stopTrackingProgress();

    this.off('durationchange', this.onDurationChange);
  };

  /**
   * Track progress
   *
   * @method trackProgress
   */

  Tech.prototype.trackProgress = function trackProgress() {
    this.stopTrackingProgress();
    this.progressInterval = this.setInterval(Fn.bind(this, function () {
      // Don't trigger unless buffered amount is greater than last time

      var numBufferedPercent = this.bufferedPercent();

      if (this.bufferedPercent_ !== numBufferedPercent) {
        this.trigger('progress');
      }

      this.bufferedPercent_ = numBufferedPercent;

      if (numBufferedPercent === 1) {
        this.stopTrackingProgress();
      }
    }), 500);
  };

  /**
   * Update duration
   *
   * @method onDurationChange
   */

  Tech.prototype.onDurationChange = function onDurationChange() {
    this.duration_ = this.duration();
  };

  /**
   * Create and get TimeRange object for buffering
   *
   * @return {TimeRangeObject}
   * @method buffered
   */

  Tech.prototype.buffered = function buffered() {
    return _utilsTimeRangesJs.createTimeRange(0, 0);
  };

  /**
   * Get buffered percent
   *
   * @return {Number}
   * @method bufferedPercent
   */

  Tech.prototype.bufferedPercent = function bufferedPercent() {
    return _utilsBufferJs.bufferedPercent(this.buffered(), this.duration_);
  };

  /**
   * Stops tracking progress by clearing progress interval
   *
   * @method stopTrackingProgress
   */

  Tech.prototype.stopTrackingProgress = function stopTrackingProgress() {
    this.clearInterval(this.progressInterval);
  };

  /*! Time Tracking -------------------------------------------------------------- */
  /**
   * Set event listeners for on play and pause and tracking current time
   *
   * @method manualTimeUpdatesOn
   */

  Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() {
    this.manualTimeUpdates = true;

    this.on('play', this.trackCurrentTime);
    this.on('pause', this.stopTrackingCurrentTime);
  };

  /**
   * Remove event listeners for on play and pause and tracking current time
   *
   * @method manualTimeUpdatesOff
   */

  Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() {
    this.manualTimeUpdates = false;
    this.stopTrackingCurrentTime();
    this.off('play', this.trackCurrentTime);
    this.off('pause', this.stopTrackingCurrentTime);
  };

  /**
   * Tracks current time
   *
   * @method trackCurrentTime
   */

  Tech.prototype.trackCurrentTime = function trackCurrentTime() {
    if (this.currentTimeInterval) {
      this.stopTrackingCurrentTime();
    }
    this.currentTimeInterval = this.setInterval(function () {
      this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
    }, 250); // 42 = 24 fps // 250 is what Webkit uses // FF uses 15
  };

  /**
   * Turn off play progress tracking (when paused or dragging)
   *
   * @method stopTrackingCurrentTime
   */

  Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() {
    this.clearInterval(this.currentTimeInterval);

    // #1002 - if the video ends right before the next timeupdate would happen,
    // the progress bar won't make it all the way to the end
    this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
  };

  /**
   * Turn off any manual progress or timeupdate tracking
   *
   * @method dispose
   */

  Tech.prototype.dispose = function dispose() {
    // clear out text tracks because we can't reuse them between techs
    var textTracks = this.textTracks();

    if (textTracks) {
      var i = textTracks.length;
      while (i--) {
        this.removeRemoteTextTrack(textTracks[i]);
      }
    }

    // Turn off any manual progress or timeupdate tracking
    if (this.manualProgress) {
      this.manualProgressOff();
    }

    if (this.manualTimeUpdates) {
      this.manualTimeUpdatesOff();
    }

    _Component.prototype.dispose.call(this);
  };

  /**
   * Reset the tech. Removes all sources and resets readyState.
   *
   * @method reset
   */

  Tech.prototype.reset = function reset() {};

  /**
   * When invoked without an argument, returns a MediaError object
   * representing the current error state of the player or null if
   * there is no error. When invoked with an argument, set the current
   * error state of the player.
   * @param {MediaError=} err    Optional an error object
   * @return {MediaError}        the current error object or null
   * @method error
   */

  Tech.prototype.error = function error(err) {
    if (err !== undefined) {
      if (err instanceof _mediaErrorJs2['default']) {
        this.error_ = err;
      } else {
        this.error_ = new _mediaErrorJs2['default'](err);
      }
      this.trigger('error');
    }
    return this.error_;
  };

  /**
   * Return the time ranges that have been played through for the
   * current source. This implementation is incomplete. It does not
   * track the played time ranges, only whether the source has played
   * at all or not.
   * @return {TimeRangeObject} a single time range if this video has
   * played or an empty set of ranges if not.
   * @method played
   */

  Tech.prototype.played = function played() {
    if (this.hasStarted_) {
      return _utilsTimeRangesJs.createTimeRange(0, 0);
    }
    return _utilsTimeRangesJs.createTimeRange();
  };

  /**
   * Set current time
   *
   * @method setCurrentTime
   */

  Tech.prototype.setCurrentTime = function setCurrentTime() {
    // improve the accuracy of manual timeupdates
    if (this.manualTimeUpdates) {
      this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
    }
  };

  /**
   * Initialize texttrack listeners
   *
   * @method initTextTrackListeners
   */

  Tech.prototype.initTextTrackListeners = function initTextTrackListeners() {
    var textTrackListChanges = Fn.bind(this, function () {
      this.trigger('texttrackchange');
    });

    var tracks = this.textTracks();

    if (!tracks) return;

    tracks.addEventListener('removetrack', textTrackListChanges);
    tracks.addEventListener('addtrack', textTrackListChanges);

    this.on('dispose', Fn.bind(this, function () {
      tracks.removeEventListener('removetrack', textTrackListChanges);
      tracks.removeEventListener('addtrack', textTrackListChanges);
    }));
  };

  /**
   * Emulate texttracks
   *
   * @method emulateTextTracks
   */

  Tech.prototype.emulateTextTracks = function emulateTextTracks() {
    var _this = this;

    var tracks = this.textTracks();
    if (!tracks) {
      return;
    }

    if (!_globalWindow2['default']['WebVTT'] && this.el().parentNode != null) {
      (function () {
        var script = _globalDocument2['default'].createElement('script');
        script.src = _this.options_['vtt.js'] || 'https://cdn.rawgit.com/gkatsev/vtt.js/vjs-v0.12.1/dist/vtt.min.js';
        script.onload = function () {
          _this.trigger('vttjsloaded');
        };
        script.onerror = function () {
          _this.trigger('vttjserror');
        };
        _this.on('dispose', function () {
          script.onload = null;
          script.onerror = null;
        });
        _this.el().parentNode.appendChild(script);
        _globalWindow2['default']['WebVTT'] = true;
      })();
    }

    var updateDisplay = function updateDisplay() {
      return _this.trigger('texttrackchange');
    };
    var textTracksChanges = function textTracksChanges() {
      updateDisplay();

      for (var i = 0; i < tracks.length; i++) {
        var track = tracks[i];
        track.removeEventListener('cuechange', updateDisplay);
        if (track.mode === 'showing') {
          track.addEventListener('cuechange', updateDisplay);
        }
      }
    };

    textTracksChanges();
    tracks.addEventListener('change', textTracksChanges);

    this.on('dispose', function () {
      tracks.removeEventListener('change', textTracksChanges);
    });
  };

  /*
   * Provide default methods for text tracks.
   *
   * Html5 tech overrides these.
   */

  /**
   * Get texttracks
   *
   * @returns {TextTrackList}
   * @method textTracks
   */

  Tech.prototype.textTracks = function textTracks() {
    this.textTracks_ = this.textTracks_ || new _tracksTextTrackList2['default']();
    return this.textTracks_;
  };

  /**
   * Get remote texttracks
   *
   * @returns {TextTrackList}
   * @method remoteTextTracks
   */

  Tech.prototype.remoteTextTracks = function remoteTextTracks() {
    this.remoteTextTracks_ = this.remoteTextTracks_ || new _tracksTextTrackList2['default']();
    return this.remoteTextTracks_;
  };

  /**
   * Get remote htmltrackelements
   *
   * @returns {HTMLTrackElementList}
   * @method remoteTextTrackEls
   */

  Tech.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
    this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new _tracksHtmlTrackElementList2['default']();
    return this.remoteTextTrackEls_;
  };

  /**
   * Creates and returns a remote text track object
   *
   * @param {String} kind Text track kind (subtitles, captions, descriptions
   *                                       chapters and metadata)
   * @param {String=} label Label to identify the text track
   * @param {String=} language Two letter language abbreviation
   * @return {TextTrackObject}
   * @method addTextTrack
   */

  Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) {
    if (!kind) {
      throw new Error('TextTrack kind is required but was not provided');
    }

    return createTrackHelper(this, kind, label, language);
  };

  /**
   * Creates a remote text track object and returns a emulated html track element
   *
   * @param {Object} options The object should contain values for
   * kind, language, label and src (location of the WebVTT file)
   * @return {HTMLTrackElement}
   * @method addRemoteTextTrack
   */

  Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack(options) {
    var track = _utilsMergeOptionsJs2['default'](options, {
      tech: this
    });

    var htmlTrackElement = new _tracksHtmlTrackElement2['default'](track);

    // store HTMLTrackElement and TextTrack to remote list
    this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
    this.remoteTextTracks().addTrack_(htmlTrackElement.track);

    // must come after remoteTextTracks()
    this.textTracks().addTrack_(htmlTrackElement.track);

    return htmlTrackElement;
  };

  /**
   * Remove remote texttrack
   *
   * @param {TextTrackObject} track Texttrack to remove
   * @method removeRemoteTextTrack
   */

  Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
    this.textTracks().removeTrack_(track);

    var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);

    // remove HTMLTrackElement and TextTrack from remote list
    this.remoteTextTrackEls().removeTrackElement_(trackElement);
    this.remoteTextTracks().removeTrack_(track);
  };

  /**
   * Provide a default setPoster method for techs
   * Poster support for techs should be optional, so we don't want techs to
   * break if they don't have a way to set a poster.
   *
   * @method setPoster
   */

  Tech.prototype.setPoster = function setPoster() {};

  /*
   * Check if the tech can support the given type
   *
   * The base tech does not support any type, but source handlers might
   * overwrite this.
   *
   * @param  {String} type    The mimetype to check
   * @return {String}         'probably', 'maybe', or '' (empty string)
   */

  Tech.prototype.canPlayType = function canPlayType() {
    return '';
  };

  /*
   * Return whether the argument is a Tech or not.
   * Can be passed either a Class like `Html5` or a instance like `player.tech_`
   *
   * @param {Object} component An item to check
   * @return {Boolean}         Whether it is a tech or not
   */

  Tech.isTech = function isTech(component) {
    return component.prototype instanceof Tech || component instanceof Tech || component === Tech;
  };

  /**
   * Registers a Tech
   *
   * @param {String} name Name of the Tech to register
   * @param {Object} tech The tech to register
   * @static
   * @method registerComponent
   */

  Tech.registerTech = function registerTech(name, tech) {
    if (!Tech.techs_) {
      Tech.techs_ = {};
    }

    if (!Tech.isTech(tech)) {
      throw new Error('Tech ' + name + ' must be a Tech');
    }

    Tech.techs_[name] = tech;
    return tech;
  };

  /**
   * Gets a component by name
   *
   * @param {String} name Name of the component to get
   * @return {Component}
   * @static
   * @method getComponent
   */

  Tech.getTech = function getTech(name) {
    if (Tech.techs_ && Tech.techs_[name]) {
      return Tech.techs_[name];
    }

    if (_globalWindow2['default'] && _globalWindow2['default'].videojs && _globalWindow2['default'].videojs[name]) {
      _utilsLogJs2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)');
      return _globalWindow2['default'].videojs[name];
    }
  };

  return Tech;
})(_component2['default']);

Tech.prototype.textTracks_;

var createTrackHelper = function createTrackHelper(self, kind, label, language) {
  var options = arguments.length <= 4 || arguments[4] === undefined ? {} : arguments[4];

  var tracks = self.textTracks();

  options.kind = kind;

  if (label) {
    options.label = label;
  }
  if (language) {
    options.language = language;
  }
  options.tech = self;

  var track = new _tracksTextTrack2['default'](options);
  tracks.addTrack_(track);

  return track;
};

Tech.prototype.featuresVolumeControl = true;

// Resizing plugins using request fullscreen reloads the plugin
Tech.prototype.featuresFullscreenResize = false;
Tech.prototype.featuresPlaybackRate = false;

// Optional events that we can manually mimic with timers
// currently not triggered by video-js-swf
Tech.prototype.featuresProgressEvents = false;
Tech.prototype.featuresTimeupdateEvents = false;

Tech.prototype.featuresNativeTextTracks = false;

/*
 * A functional mixin for techs that want to use the Source Handler pattern.
 *
 * ##### EXAMPLE:
 *
 *   Tech.withSourceHandlers.call(MyTech);
 *
 */
Tech.withSourceHandlers = function (_Tech) {
  /*
   * Register a source handler
   * Source handlers are scripts for handling specific formats.
   * The source handler pattern is used for adaptive formats (HLS, DASH) that
   * manually load video data and feed it into a Source Buffer (Media Source Extensions)
   * @param  {Function} handler  The source handler
   * @param  {Boolean}  first    Register it before any existing handlers
   */
  _Tech.registerSourceHandler = function (handler, index) {
    var handlers = _Tech.sourceHandlers;

    if (!handlers) {
      handlers = _Tech.sourceHandlers = [];
    }

    if (index === undefined) {
      // add to the end of the list
      index = handlers.length;
    }

    handlers.splice(index, 0, handler);
  };

  /*
   * Check if the tech can support the given type
   * @param  {String} type    The mimetype to check
   * @return {String}         'probably', 'maybe', or '' (empty string)
   */
  _Tech.canPlayType = function (type) {
    var handlers = _Tech.sourceHandlers || [];
    var can = undefined;

    for (var i = 0; i < handlers.length; i++) {
      can = handlers[i].canPlayType(type);

      if (can) {
        return can;
      }
    }

    return '';
  };

  /*
   * Return the first source handler that supports the source
   * TODO: Answer question: should 'probably' be prioritized over 'maybe'
   * @param  {Object} source The source object
   * @returns {Object}       The first source handler that supports the source
   * @returns {null}         Null if no source handler is found
   */
  _Tech.selectSourceHandler = function (source) {
    var handlers = _Tech.sourceHandlers || [];
    var can = undefined;

    for (var i = 0; i < handlers.length; i++) {
      can = handlers[i].canHandleSource(source);

      if (can) {
        return handlers[i];
      }
    }

    return null;
  };

  /*
   * Check if the tech can support the given source
   * @param  {Object} srcObj  The source object
   * @return {String}         'probably', 'maybe', or '' (empty string)
   */
  _Tech.canPlaySource = function (srcObj) {
    var sh = _Tech.selectSourceHandler(srcObj);

    if (sh) {
      return sh.canHandleSource(srcObj);
    }

    return '';
  };

  /*
   * When using a source handler, prefer its implementation of
   * any function normally provided by the tech.
   */
  var deferrable = ['seekable', 'duration'];

  deferrable.forEach(function (fnName) {
    var originalFn = this[fnName];

    if (typeof originalFn !== 'function') {
      return;
    }

    this[fnName] = function () {
      if (this.sourceHandler_ && this.sourceHandler_[fnName]) {
        return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments);
      }
      return originalFn.apply(this, arguments);
    };
  }, _Tech.prototype);

  /*
   * Create a function for setting the source using a source object
   * and source handlers.
   * Should never be called unless a source handler was found.
   * @param {Object} source  A source object with src and type keys
   * @return {Tech} self
   */
  _Tech.prototype.setSource = function (source) {
    var sh = _Tech.selectSourceHandler(source);

    if (!sh) {
      // Fall back to a native source hander when unsupported sources are
      // deliberately set
      if (_Tech.nativeSourceHandler) {
        sh = _Tech.nativeSourceHandler;
      } else {
        _utilsLogJs2['default'].error('No source hander found for the current source.');
      }
    }

    // Dispose any existing source handler
    this.disposeSourceHandler();
    this.off('dispose', this.disposeSourceHandler);

    this.currentSource_ = source;
    this.sourceHandler_ = sh.handleSource(source, this);
    this.on('dispose', this.disposeSourceHandler);

    return this;
  };

  /*
   * Clean up any existing source handler
   */
  _Tech.prototype.disposeSourceHandler = function () {
    if (this.sourceHandler_ && this.sourceHandler_.dispose) {
      this.sourceHandler_.dispose();
    }
  };
};

_component2['default'].registerComponent('Tech', Tech);
// Old name for Tech
_component2['default'].registerComponent('MediaTechController', Tech);
Tech.registerTech('Tech', Tech);
exports['default'] = Tech;
module.exports = exports['default'];

},{"../component":67,"../media-error.js":103,"../tracks/html-track-element":121,"../tracks/html-track-element-list":120,"../tracks/text-track":128,"../tracks/text-track-list":126,"../utils/buffer.js":130,"../utils/fn.js":134,"../utils/log.js":137,"../utils/merge-options.js":138,"../utils/time-ranges.js":140,"global/document":1,"global/window":2}],120:[function(_dereq_,module,exports){
/**
 * @file html-track-element-list.js
 */

'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

var _utilsBrowserJs = _dereq_('../utils/browser.js');

var browser = _interopRequireWildcard(_utilsBrowserJs);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var HtmlTrackElementList = (function () {
  function HtmlTrackElementList() {
    var trackElements = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];

    _classCallCheck(this, HtmlTrackElementList);

    var list = this;

    if (browser.IS_IE8) {
      list = _globalDocument2['default'].createElement('custom');

      for (var prop in HtmlTrackElementList.prototype) {
        if (prop !== 'constructor') {
          list[prop] = HtmlTrackElementList.prototype[prop];
        }
      }
    }

    list.trackElements_ = [];

    Object.defineProperty(list, 'length', {
      get: function get() {
        return this.trackElements_.length;
      }
    });

    for (var i = 0, _length = trackElements.length; i < _length; i++) {
      list.addTrackElement_(trackElements[i]);
    }

    if (browser.IS_IE8) {
      return list;
    }
  }

  HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) {
    this.trackElements_.push(trackElement);
  };

  HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) {
    var trackElement_ = undefined;

    for (var i = 0, _length2 = this.trackElements_.length; i < _length2; i++) {
      if (track === this.trackElements_[i].track) {
        trackElement_ = this.trackElements_[i];

        break;
      }
    }

    return trackElement_;
  };

  HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) {
    for (var i = 0, _length3 = this.trackElements_.length; i < _length3; i++) {
      if (trackElement === this.trackElements_[i]) {
        this.trackElements_.splice(i, 1);

        break;
      }
    }
  };

  return HtmlTrackElementList;
})();

exports['default'] = HtmlTrackElementList;
module.exports = exports['default'];

},{"../utils/browser.js":129,"global/document":1}],121:[function(_dereq_,module,exports){
/**
 * @file html-track-element.js
 */

'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _utilsBrowserJs = _dereq_('../utils/browser.js');

var browser = _interopRequireWildcard(_utilsBrowserJs);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var _eventTarget = _dereq_('../event-target');

var _eventTarget2 = _interopRequireDefault(_eventTarget);

var _tracksTextTrack = _dereq_('../tracks/text-track');

var _tracksTextTrack2 = _interopRequireDefault(_tracksTextTrack);

var NONE = 0;
var LOADING = 1;
var LOADED = 2;
var ERROR = 3;

/**
 * https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement
 *
 * interface HTMLTrackElement : HTMLElement {
 *   attribute DOMString kind;
 *   attribute DOMString src;
 *   attribute DOMString srclang;
 *   attribute DOMString label;
 *   attribute boolean default;
 *
 *   const unsigned short NONE = 0;
 *   const unsigned short LOADING = 1;
 *   const unsigned short LOADED = 2;
 *   const unsigned short ERROR = 3;
 *   readonly attribute unsigned short readyState;
 *
 *   readonly attribute TextTrack track;
 * };
 *
 * @param {Object} options TextTrack configuration
 * @class HTMLTrackElement
 */

var HTMLTrackElement = (function (_EventTarget) {
  _inherits(HTMLTrackElement, _EventTarget);

  function HTMLTrackElement() {
    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];

    _classCallCheck(this, HTMLTrackElement);

    _EventTarget.call(this);

    var readyState = undefined,
        trackElement = this;

    if (browser.IS_IE8) {
      trackElement = _globalDocument2['default'].createElement('custom');

      for (var prop in HTMLTrackElement.prototype) {
        if (prop !== 'constructor') {
          trackElement[prop] = HTMLTrackElement.prototype[prop];
        }
      }
    }

    var track = new _tracksTextTrack2['default'](options);

    trackElement.kind = track.kind;
    trackElement.src = track.src;
    trackElement.srclang = track.language;
    trackElement.label = track.label;
    trackElement['default'] = track['default'];

    Object.defineProperty(trackElement, 'readyState', {
      get: function get() {
        return readyState;
      }
    });

    Object.defineProperty(trackElement, 'track', {
      get: function get() {
        return track;
      }
    });

    readyState = NONE;

    track.addEventListener('loadeddata', function () {
      readyState = LOADED;

      trackElement.trigger({
        type: 'load',
        target: trackElement
      });
    });

    if (browser.IS_IE8) {
      return trackElement;
    }
  }

  return HTMLTrackElement;
})(_eventTarget2['default']);

HTMLTrackElement.prototype.allowedEvents_ = {
  load: 'load'
};

HTMLTrackElement.NONE = NONE;
HTMLTrackElement.LOADING = LOADING;
HTMLTrackElement.LOADED = LOADED;
HTMLTrackElement.ERROR = ERROR;

exports['default'] = HTMLTrackElement;
module.exports = exports['default'];

},{"../event-target":99,"../tracks/text-track":128,"../utils/browser.js":129,"global/document":1}],122:[function(_dereq_,module,exports){
/**
 * @file text-track-cue-list.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

var _utilsBrowserJs = _dereq_('../utils/browser.js');

var browser = _interopRequireWildcard(_utilsBrowserJs);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

/**
 * A List of text track cues as defined in:
 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist
 *
 * interface TextTrackCueList {
 *   readonly attribute unsigned long length;
 *   getter TextTrackCue (unsigned long index);
 *   TextTrackCue? getCueById(DOMString id);
 * };
 *
 * @param {Array} cues A list of cues to be initialized with
 * @class TextTrackCueList
 */

var TextTrackCueList = (function () {
  function TextTrackCueList(cues) {
    _classCallCheck(this, TextTrackCueList);

    var list = this;

    if (browser.IS_IE8) {
      list = _globalDocument2['default'].createElement('custom');

      for (var prop in TextTrackCueList.prototype) {
        if (prop !== 'constructor') {
          list[prop] = TextTrackCueList.prototype[prop];
        }
      }
    }

    TextTrackCueList.prototype.setCues_.call(list, cues);

    Object.defineProperty(list, 'length', {
      get: function get() {
        return this.length_;
      }
    });

    if (browser.IS_IE8) {
      return list;
    }
  }

  /**
   * A setter for cues in this list
   *
   * @param {Array} cues an array of cues
   * @method setCues_
   * @private
   */

  TextTrackCueList.prototype.setCues_ = function setCues_(cues) {
    var oldLength = this.length || 0;
    var i = 0;
    var l = cues.length;

    this.cues_ = cues;
    this.length_ = cues.length;

    var defineProp = function defineProp(index) {
      if (!('' + index in this)) {
        Object.defineProperty(this, '' + index, {
          get: function get() {
            return this.cues_[index];
          }
        });
      }
    };

    if (oldLength < l) {
      i = oldLength;

      for (; i < l; i++) {
        defineProp.call(this, i);
      }
    }
  };

  /**
   * Get a cue that is currently in the Cue list by id
   *
   * @param {String} id
   * @method getCueById
   * @return {Object} a single cue
   */

  TextTrackCueList.prototype.getCueById = function getCueById(id) {
    var result = null;

    for (var i = 0, l = this.length; i < l; i++) {
      var cue = this[i];

      if (cue.id === id) {
        result = cue;
        break;
      }
    }

    return result;
  };

  return TextTrackCueList;
})();

exports['default'] = TextTrackCueList;
module.exports = exports['default'];

},{"../utils/browser.js":129,"global/document":1}],123:[function(_dereq_,module,exports){
/**
 * @file text-track-display.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _component = _dereq_('../component');

var _component2 = _interopRequireDefault(_component);

var _menuMenuJs = _dereq_('../menu/menu.js');

var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs);

var _menuMenuItemJs = _dereq_('../menu/menu-item.js');

var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);

var _menuMenuButtonJs = _dereq_('../menu/menu-button.js');

var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs);

var _utilsFnJs = _dereq_('../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

var darkGray = '#222';
var lightGray = '#ccc';
var fontMap = {
  monospace: 'monospace',
  sansSerif: 'sans-serif',
  serif: 'serif',
  monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace',
  monospaceSerif: '"Courier New", monospace',
  proportionalSansSerif: 'sans-serif',
  proportionalSerif: 'serif',
  casual: '"Comic Sans MS", Impact, fantasy',
  script: '"Monotype Corsiva", cursive',
  smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif'
};

/**
 * The component for displaying text track cues
 *
 * @param {Object} player  Main Player
 * @param {Object=} options Object of option names and values
 * @param {Function=} ready    Ready callback function
 * @extends Component
 * @class TextTrackDisplay
 */

var TextTrackDisplay = (function (_Component) {
  _inherits(TextTrackDisplay, _Component);

  function TextTrackDisplay(player, options, ready) {
    _classCallCheck(this, TextTrackDisplay);

    _Component.call(this, player, options, ready);

    player.on('loadstart', Fn.bind(this, this.toggleDisplay));
    player.on('texttrackchange', Fn.bind(this, this.updateDisplay));

    // This used to be called during player init, but was causing an error
    // if a track should show by default and the display hadn't loaded yet.
    // Should probably be moved to an external track loader when we support
    // tracks that don't need a display.
    player.ready(Fn.bind(this, function () {
      if (player.tech_ && player.tech_['featuresNativeTextTracks']) {
        this.hide();
        return;
      }

      player.on('fullscreenchange', Fn.bind(this, this.updateDisplay));

      var tracks = this.options_.playerOptions['tracks'] || [];
      for (var i = 0; i < tracks.length; i++) {
        var track = tracks[i];
        this.player_.addRemoteTextTrack(track);
      }
    }));
  }

  /**
  * Add cue HTML to display
  *
  * @param {Number} color Hex number for color, like #f0e
  * @param {Number} opacity Value for opacity,0.0 - 1.0
  * @return {RGBAColor} In the form 'rgba(255, 0, 0, 0.3)'
  * @method constructColor
  */

  /**
   * Toggle display texttracks
   *
   * @method toggleDisplay
   */

  TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() {
    if (this.player_.tech_ && this.player_.tech_['featuresNativeTextTracks']) {
      this.hide();
    } else {
      this.show();
    }
  };

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  TextTrackDisplay.prototype.createEl = function createEl() {
    return _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-text-track-display'
    });
  };

  /**
   * Clear display texttracks
   *
   * @method clearDisplay
   */

  TextTrackDisplay.prototype.clearDisplay = function clearDisplay() {
    if (typeof _globalWindow2['default']['WebVTT'] === 'function') {
      _globalWindow2['default']['WebVTT']['processCues'](_globalWindow2['default'], [], this.el_);
    }
  };

  /**
   * Update display texttracks
   *
   * @method updateDisplay
   */

  TextTrackDisplay.prototype.updateDisplay = function updateDisplay() {
    var tracks = this.player_.textTracks();

    this.clearDisplay();

    if (!tracks) {
      return;
    }

    for (var i = 0; i < tracks.length; i++) {
      var track = tracks[i];
      if (track['mode'] === 'showing') {
        this.updateForTrack(track);
      }
    }
  };

  /**
   * Add texttrack to texttrack list
   *
   * @param {TextTrackObject} track Texttrack object to be added to list
   * @method updateForTrack
   */

  TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) {
    if (typeof _globalWindow2['default']['WebVTT'] !== 'function' || !track['activeCues']) {
      return;
    }

    var overrides = this.player_['textTrackSettings'].getValues();

    var cues = [];
    for (var _i = 0; _i < track['activeCues'].length; _i++) {
      cues.push(track['activeCues'][_i]);
    }

    _globalWindow2['default']['WebVTT']['processCues'](_globalWindow2['default'], track['activeCues'], this.el_);

    var i = cues.length;
    while (i--) {
      var cue = cues[i];
      if (!cue) {
        continue;
      }

      var cueDiv = cue.displayState;
      if (overrides.color) {
        cueDiv.firstChild.style.color = overrides.color;
      }
      if (overrides.textOpacity) {
        tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity));
      }
      if (overrides.backgroundColor) {
        cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor;
      }
      if (overrides.backgroundOpacity) {
        tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity));
      }
      if (overrides.windowColor) {
        if (overrides.windowOpacity) {
          tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity));
        } else {
          cueDiv.style.backgroundColor = overrides.windowColor;
        }
      }
      if (overrides.edgeStyle) {
        if (overrides.edgeStyle === 'dropshadow') {
          cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray;
        } else if (overrides.edgeStyle === 'raised') {
          cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray;
        } else if (overrides.edgeStyle === 'depressed') {
          cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray;
        } else if (overrides.edgeStyle === 'uniform') {
          cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray;
        }
      }
      if (overrides.fontPercent && overrides.fontPercent !== 1) {
        var fontSize = _globalWindow2['default'].parseFloat(cueDiv.style.fontSize);
        cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px';
        cueDiv.style.height = 'auto';
        cueDiv.style.top = 'auto';
        cueDiv.style.bottom = '2px';
      }
      if (overrides.fontFamily && overrides.fontFamily !== 'default') {
        if (overrides.fontFamily === 'small-caps') {
          cueDiv.firstChild.style.fontVariant = 'small-caps';
        } else {
          cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily];
        }
      }
    }
  };

  return TextTrackDisplay;
})(_component2['default']);

function constructColor(color, opacity) {
  return 'rgba(' +
  // color looks like "#f0e"
  parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')';
}

/**
 * Try to update style
 * Some style changes will throw an error, particularly in IE8. Those should be noops.
 *
 * @param {Element} el The element to be styles
 * @param {CSSProperty} style The CSS property to be styled
 * @param {CSSStyle} rule The actual style to be applied to the property
 * @method tryUpdateStyle
 */
function tryUpdateStyle(el, style, rule) {
  //
  try {
    el.style[style] = rule;
  } catch (e) {}
}

_component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay);
exports['default'] = TextTrackDisplay;
module.exports = exports['default'];

},{"../component":67,"../menu/menu-button.js":104,"../menu/menu-item.js":105,"../menu/menu.js":106,"../utils/fn.js":134,"global/document":1,"global/window":2}],124:[function(_dereq_,module,exports){
/**
 * @file text-track-enums.js
 */

/**
 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode
 *
 * enum TextTrackMode { "disabled",  "hidden",  "showing" };
 */
'use strict';

exports.__esModule = true;
var TextTrackMode = {
  disabled: 'disabled',
  hidden: 'hidden',
  showing: 'showing'
};

/**
 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackkind
 *
 * enum TextTrackKind {
 *   "subtitles",
 *   "captions",
 *   "descriptions",
 *   "chapters",
 *   "metadata"
 * };
 */
var TextTrackKind = {
  subtitles: 'subtitles',
  captions: 'captions',
  descriptions: 'descriptions',
  chapters: 'chapters',
  metadata: 'metadata'
};

/* jshint ignore:start */
// we ignore jshint here because it does not see
// TextTrackMode or TextTrackKind as defined here somehow...
exports.TextTrackMode = TextTrackMode;
exports.TextTrackKind = TextTrackKind;

/* jshint ignore:end */

},{}],125:[function(_dereq_,module,exports){
/**
 * Utilities for capturing text track state and re-creating tracks
 * based on a capture.
 *
 * @file text-track-list-converter.js
 */

/**
 * Examine a single text track and return a JSON-compatible javascript
 * object that represents the text track's state.
 * @param track {TextTrackObject} the text track to query
 * @return {Object} a serializable javascript representation of the
 * @private
 */
'use strict';

exports.__esModule = true;
var trackToJson_ = function trackToJson_(track) {
  var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) {
    if (track[prop]) {
      acc[prop] = track[prop];
    }

    return acc;
  }, {
    cues: track.cues && Array.prototype.map.call(track.cues, function (cue) {
      return {
        startTime: cue.startTime,
        endTime: cue.endTime,
        text: cue.text,
        id: cue.id
      };
    })
  });

  return ret;
};

/**
 * Examine a tech and return a JSON-compatible javascript array that
 * represents the state of all text tracks currently configured. The
 * return array is compatible with `jsonToTextTracks`.
 * @param tech {tech} the tech object to query
 * @return {Array} a serializable javascript representation of the
 * @function textTracksToJson
 */
var textTracksToJson = function textTracksToJson(tech) {

  var trackEls = tech.$$('track');

  var trackObjs = Array.prototype.map.call(trackEls, function (t) {
    return t.track;
  });
  var tracks = Array.prototype.map.call(trackEls, function (trackEl) {
    var json = trackToJson_(trackEl.track);
    if (trackEl.src) {
      json.src = trackEl.src;
    }
    return json;
  });

  return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) {
    return trackObjs.indexOf(track) === -1;
  }).map(trackToJson_));
};

/**
 * Creates a set of remote text tracks on a tech based on an array of
 * javascript text track representations.
 * @param json {Array} an array of text track representation objects,
 * like those that would be produced by `textTracksToJson`
 * @param tech {tech} the tech to create text tracks on
 * @function jsonToTextTracks
 */
var jsonToTextTracks = function jsonToTextTracks(json, tech) {
  json.forEach(function (track) {
    var addedTrack = tech.addRemoteTextTrack(track).track;
    if (!track.src && track.cues) {
      track.cues.forEach(function (cue) {
        return addedTrack.addCue(cue);
      });
    }
  });

  return tech.textTracks();
};

exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ };
module.exports = exports['default'];

},{}],126:[function(_dereq_,module,exports){
/**
 * @file text-track-list.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _eventTarget = _dereq_('../event-target');

var _eventTarget2 = _interopRequireDefault(_eventTarget);

var _utilsFnJs = _dereq_('../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsBrowserJs = _dereq_('../utils/browser.js');

var browser = _interopRequireWildcard(_utilsBrowserJs);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

/**
 * A text track list as defined in:
 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist
 *
 * interface TextTrackList : EventTarget {
 *   readonly attribute unsigned long length;
 *   getter TextTrack (unsigned long index);
 *   TextTrack? getTrackById(DOMString id);
 *
 *   attribute EventHandler onchange;
 *   attribute EventHandler onaddtrack;
 *   attribute EventHandler onremovetrack;
 * };
 *
 * @param {Track[]} tracks A list of tracks to initialize the list with
 * @extends EventTarget
 * @class TextTrackList
 */

var TextTrackList = (function (_EventTarget) {
  _inherits(TextTrackList, _EventTarget);

  function TextTrackList() {
    var tracks = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];

    _classCallCheck(this, TextTrackList);

    _EventTarget.call(this);
    var list = this;

    if (browser.IS_IE8) {
      list = _globalDocument2['default'].createElement('custom');

      for (var prop in TextTrackList.prototype) {
        if (prop !== 'constructor') {
          list[prop] = TextTrackList.prototype[prop];
        }
      }
    }

    list.tracks_ = [];

    Object.defineProperty(list, 'length', {
      get: function get() {
        return this.tracks_.length;
      }
    });

    for (var i = 0; i < tracks.length; i++) {
      list.addTrack_(tracks[i]);
    }

    if (browser.IS_IE8) {
      return list;
    }
  }

  /**
   * change - One or more tracks in the track list have been enabled or disabled.
   * addtrack - A track has been added to the track list.
   * removetrack - A track has been removed from the track list.
   */

  /**
   * Add TextTrack from TextTrackList
   *
   * @param {TextTrack} track
   * @method addTrack_
   * @private
   */

  TextTrackList.prototype.addTrack_ = function addTrack_(track) {
    var index = this.tracks_.length;

    if (!('' + index in this)) {
      Object.defineProperty(this, index, {
        get: function get() {
          return this.tracks_[index];
        }
      });
    }

    track.addEventListener('modechange', Fn.bind(this, function () {
      this.trigger('change');
    }));

    // Do not add duplicate tracks
    if (this.tracks_.indexOf(track) === -1) {
      this.tracks_.push(track);
      this.trigger({
        track: track,
        type: 'addtrack'
      });
    }
  };

  /**
   * Remove TextTrack from TextTrackList
   * NOTE: Be mindful of what is passed in as it may be a HTMLTrackElement
   *
   * @param {TextTrack} rtrack
   * @method removeTrack_
   * @private
   */

  TextTrackList.prototype.removeTrack_ = function removeTrack_(rtrack) {
    var track = undefined;

    for (var i = 0, l = this.length; i < l; i++) {
      if (this[i] === rtrack) {
        track = this[i];
        if (track.off) {
          track.off();
        }

        this.tracks_.splice(i, 1);

        break;
      }
    }

    if (!track) {
      return;
    }

    this.trigger({
      track: track,
      type: 'removetrack'
    });
  };

  /**
   * Get a TextTrack from TextTrackList by a tracks id
   *
   * @param {String} id - the id of the track to get
   * @method getTrackById
   * @return {TextTrack}
   * @private
   */

  TextTrackList.prototype.getTrackById = function getTrackById(id) {
    var result = null;

    for (var i = 0, l = this.length; i < l; i++) {
      var track = this[i];

      if (track.id === id) {
        result = track;
        break;
      }
    }

    return result;
  };

  return TextTrackList;
})(_eventTarget2['default']);

TextTrackList.prototype.allowedEvents_ = {
  change: 'change',
  addtrack: 'addtrack',
  removetrack: 'removetrack'
};

// emulate attribute EventHandler support to allow for feature detection
for (var _event in TextTrackList.prototype.allowedEvents_) {
  TextTrackList.prototype['on' + _event] = null;
}

exports['default'] = TextTrackList;
module.exports = exports['default'];

},{"../event-target":99,"../utils/browser.js":129,"../utils/fn.js":134,"global/document":1}],127:[function(_dereq_,module,exports){
/**
 * @file text-track-settings.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _component = _dereq_('../component');

var _component2 = _interopRequireDefault(_component);

var _utilsEventsJs = _dereq_('../utils/events.js');

var Events = _interopRequireWildcard(_utilsEventsJs);

var _utilsFnJs = _dereq_('../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsLogJs = _dereq_('../utils/log.js');

var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);

var _safeJsonParseTuple = _dereq_('safe-json-parse/tuple');

var _safeJsonParseTuple2 = _interopRequireDefault(_safeJsonParseTuple);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

/**
 * Manipulate settings of texttracks
 *
 * @param {Object} player  Main Player
 * @param {Object=} options Object of option names and values
 * @extends Component
 * @class TextTrackSettings
 */

var TextTrackSettings = (function (_Component) {
  _inherits(TextTrackSettings, _Component);

  function TextTrackSettings(player, options) {
    _classCallCheck(this, TextTrackSettings);

    _Component.call(this, player, options);
    this.hide();

    // Grab `persistTextTrackSettings` from the player options if not passed in child options
    if (options.persistTextTrackSettings === undefined) {
      this.options_.persistTextTrackSettings = this.options_.playerOptions.persistTextTrackSettings;
    }

    Events.on(this.$('.vjs-done-button'), 'click', Fn.bind(this, function () {
      this.saveSettings();
      this.hide();
    }));

    Events.on(this.$('.vjs-default-button'), 'click', Fn.bind(this, function () {
      this.$('.vjs-fg-color > select').selectedIndex = 0;
      this.$('.vjs-bg-color > select').selectedIndex = 0;
      this.$('.window-color > select').selectedIndex = 0;
      this.$('.vjs-text-opacity > select').selectedIndex = 0;
      this.$('.vjs-bg-opacity > select').selectedIndex = 0;
      this.$('.vjs-window-opacity > select').selectedIndex = 0;
      this.$('.vjs-edge-style select').selectedIndex = 0;
      this.$('.vjs-font-family select').selectedIndex = 0;
      this.$('.vjs-font-percent select').selectedIndex = 2;
      this.updateDisplay();
    }));

    Events.on(this.$('.vjs-fg-color > select'), 'change', Fn.bind(this, this.updateDisplay));
    Events.on(this.$('.vjs-bg-color > select'), 'change', Fn.bind(this, this.updateDisplay));
    Events.on(this.$('.window-color > select'), 'change', Fn.bind(this, this.updateDisplay));
    Events.on(this.$('.vjs-text-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
    Events.on(this.$('.vjs-bg-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
    Events.on(this.$('.vjs-window-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
    Events.on(this.$('.vjs-font-percent select'), 'change', Fn.bind(this, this.updateDisplay));
    Events.on(this.$('.vjs-edge-style select'), 'change', Fn.bind(this, this.updateDisplay));
    Events.on(this.$('.vjs-font-family select'), 'change', Fn.bind(this, this.updateDisplay));

    if (this.options_.persistTextTrackSettings) {
      this.restoreSettings();
    }
  }

  /**
   * Create the component's DOM element
   *
   * @return {Element}
   * @method createEl
   */

  TextTrackSettings.prototype.createEl = function createEl() {
    return _Component.prototype.createEl.call(this, 'div', {
      className: 'vjs-caption-settings vjs-modal-overlay',
      innerHTML: captionOptionsMenuTemplate()
    });
  };

  /**
   * Get texttrack settings
   * Settings are
   * .vjs-edge-style
   * .vjs-font-family
   * .vjs-fg-color
   * .vjs-text-opacity
   * .vjs-bg-color
   * .vjs-bg-opacity
   * .window-color
   * .vjs-window-opacity
   *
   * @return {Object}
   * @method getValues
   */

  TextTrackSettings.prototype.getValues = function getValues() {
    var textEdge = getSelectedOptionValue(this.$('.vjs-edge-style select'));
    var fontFamily = getSelectedOptionValue(this.$('.vjs-font-family select'));
    var fgColor = getSelectedOptionValue(this.$('.vjs-fg-color > select'));
    var textOpacity = getSelectedOptionValue(this.$('.vjs-text-opacity > select'));
    var bgColor = getSelectedOptionValue(this.$('.vjs-bg-color > select'));
    var bgOpacity = getSelectedOptionValue(this.$('.vjs-bg-opacity > select'));
    var windowColor = getSelectedOptionValue(this.$('.window-color > select'));
    var windowOpacity = getSelectedOptionValue(this.$('.vjs-window-opacity > select'));
    var fontPercent = _globalWindow2['default']['parseFloat'](getSelectedOptionValue(this.$('.vjs-font-percent > select')));

    var result = {
      'backgroundOpacity': bgOpacity,
      'textOpacity': textOpacity,
      'windowOpacity': windowOpacity,
      'edgeStyle': textEdge,
      'fontFamily': fontFamily,
      'color': fgColor,
      'backgroundColor': bgColor,
      'windowColor': windowColor,
      'fontPercent': fontPercent
    };
    for (var _name in result) {
      if (result[_name] === '' || result[_name] === 'none' || _name === 'fontPercent' && result[_name] === 1.00) {
        delete result[_name];
      }
    }
    return result;
  };

  /**
   * Set texttrack settings
   * Settings are
   * .vjs-edge-style
   * .vjs-font-family
   * .vjs-fg-color
   * .vjs-text-opacity
   * .vjs-bg-color
   * .vjs-bg-opacity
   * .window-color
   * .vjs-window-opacity
   *
   * @param {Object} values Object with texttrack setting values
   * @method setValues
   */

  TextTrackSettings.prototype.setValues = function setValues(values) {
    setSelectedOption(this.$('.vjs-edge-style select'), values.edgeStyle);
    setSelectedOption(this.$('.vjs-font-family select'), values.fontFamily);
    setSelectedOption(this.$('.vjs-fg-color > select'), values.color);
    setSelectedOption(this.$('.vjs-text-opacity > select'), values.textOpacity);
    setSelectedOption(this.$('.vjs-bg-color > select'), values.backgroundColor);
    setSelectedOption(this.$('.vjs-bg-opacity > select'), values.backgroundOpacity);
    setSelectedOption(this.$('.window-color > select'), values.windowColor);
    setSelectedOption(this.$('.vjs-window-opacity > select'), values.windowOpacity);

    var fontPercent = values.fontPercent;

    if (fontPercent) {
      fontPercent = fontPercent.toFixed(2);
    }

    setSelectedOption(this.$('.vjs-font-percent > select'), fontPercent);
  };

  /**
   * Restore texttrack settings
   *
   * @method restoreSettings
   */

  TextTrackSettings.prototype.restoreSettings = function restoreSettings() {
    var err = undefined,
        values = undefined;

    try {
      var _safeParseTuple = _safeJsonParseTuple2['default'](_globalWindow2['default'].localStorage.getItem('vjs-text-track-settings'));

      err = _safeParseTuple[0];
      values = _safeParseTuple[1];

      if (err) {
        _utilsLogJs2['default'].error(err);
      }
    } catch (e) {
      _utilsLogJs2['default'].warn(e);
    }

    if (values) {
      this.setValues(values);
    }
  };

  /**
   * Save texttrack settings to local storage
   *
   * @method saveSettings
   */

  TextTrackSettings.prototype.saveSettings = function saveSettings() {
    if (!this.options_.persistTextTrackSettings) {
      return;
    }

    var values = this.getValues();
    try {
      if (Object.getOwnPropertyNames(values).length > 0) {
        _globalWindow2['default'].localStorage.setItem('vjs-text-track-settings', JSON.stringify(values));
      } else {
        _globalWindow2['default'].localStorage.removeItem('vjs-text-track-settings');
      }
    } catch (e) {
      _utilsLogJs2['default'].warn(e);
    }
  };

  /**
   * Update display of texttrack settings
   *
   * @method updateDisplay
   */

  TextTrackSettings.prototype.updateDisplay = function updateDisplay() {
    var ttDisplay = this.player_.getChild('textTrackDisplay');
    if (ttDisplay) {
      ttDisplay.updateDisplay();
    }
  };

  return TextTrackSettings;
})(_component2['default']);

_component2['default'].registerComponent('TextTrackSettings', TextTrackSettings);

function getSelectedOptionValue(target) {
  var selectedOption = undefined;
  // not all browsers support selectedOptions, so, fallback to options
  if (target.selectedOptions) {
    selectedOption = target.selectedOptions[0];
  } else if (target.options) {
    selectedOption = target.options[target.options.selectedIndex];
  }

  return selectedOption.value;
}

function setSelectedOption(target, value) {
  if (!value) {
    return;
  }

  var i = undefined;
  for (i = 0; i < target.options.length; i++) {
    var option = target.options[i];
    if (option.value === value) {
      break;
    }
  }

  target.selectedIndex = i;
}

function captionOptionsMenuTemplate() {
  var template = '<div class="vjs-tracksettings">\n      <div class="vjs-tracksettings-colors">\n        <div class="vjs-fg-color vjs-tracksetting">\n            <label class="vjs-label">Foreground</label>\n            <select>\n              <option value="">---</option>\n              <option value="#FFF">White</option>\n              <option value="#000">Black</option>\n              <option value="#F00">Red</option>\n              <option value="#0F0">Green</option>\n              <option value="#00F">Blue</option>\n              <option value="#FF0">Yellow</option>\n              <option value="#F0F">Magenta</option>\n              <option value="#0FF">Cyan</option>\n            </select>\n            <span class="vjs-text-opacity vjs-opacity">\n              <select>\n                <option value="">---</option>\n                <option value="1">Opaque</option>\n                <option value="0.5">Semi-Opaque</option>\n              </select>\n            </span>\n        </div> <!-- vjs-fg-color -->\n        <div class="vjs-bg-color vjs-tracksetting">\n            <label class="vjs-label">Background</label>\n            <select>\n              <option value="">---</option>\n              <option value="#FFF">White</option>\n              <option value="#000">Black</option>\n              <option value="#F00">Red</option>\n              <option value="#0F0">Green</option>\n              <option value="#00F">Blue</option>\n              <option value="#FF0">Yellow</option>\n              <option value="#F0F">Magenta</option>\n              <option value="#0FF">Cyan</option>\n            </select>\n            <span class="vjs-bg-opacity vjs-opacity">\n                <select>\n                  <option value="">---</option>\n                  <option value="1">Opaque</option>\n                  <option value="0.5">Semi-Transparent</option>\n                  <option value="0">Transparent</option>\n                </select>\n            </span>\n        </div> <!-- vjs-bg-color -->\n        <div class="window-color vjs-tracksetting">\n            <label class="vjs-label">Window</label>\n            <select>\n              <option value="">---</option>\n              <option value="#FFF">White</option>\n              <option value="#000">Black</option>\n              <option value="#F00">Red</option>\n              <option value="#0F0">Green</option>\n              <option value="#00F">Blue</option>\n              <option value="#FF0">Yellow</option>\n              <option value="#F0F">Magenta</option>\n              <option value="#0FF">Cyan</option>\n            </select>\n            <span class="vjs-window-opacity vjs-opacity">\n                <select>\n                  <option value="">---</option>\n                  <option value="1">Opaque</option>\n                  <option value="0.5">Semi-Transparent</option>\n                  <option value="0">Transparent</option>\n                </select>\n            </span>\n        </div> <!-- vjs-window-color -->\n      </div> <!-- vjs-tracksettings -->\n      <div class="vjs-tracksettings-font">\n        <div class="vjs-font-percent vjs-tracksetting">\n          <label class="vjs-label">Font Size</label>\n          <select>\n            <option value="0.50">50%</option>\n            <option value="0.75">75%</option>\n            <option value="1.00" selected>100%</option>\n            <option value="1.25">125%</option>\n            <option value="1.50">150%</option>\n            <option value="1.75">175%</option>\n            <option value="2.00">200%</option>\n            <option value="3.00">300%</option>\n            <option value="4.00">400%</option>\n          </select>\n        </div> <!-- vjs-font-percent -->\n        <div class="vjs-edge-style vjs-tracksetting">\n          <label class="vjs-label">Text Edge Style</label>\n          <select>\n            <option value="none">None</option>\n            <option value="raised">Raised</option>\n            <option value="depressed">Depressed</option>\n            <option value="uniform">Uniform</option>\n            <option value="dropshadow">Dropshadow</option>\n          </select>\n        </div> <!-- vjs-edge-style -->\n        <div class="vjs-font-family vjs-tracksetting">\n          <label class="vjs-label">Font Family</label>\n          <select>\n            <option value="">Default</option>\n            <option value="monospaceSerif">Monospace Serif</option>\n            <option value="proportionalSerif">Proportional Serif</option>\n            <option value="monospaceSansSerif">Monospace Sans-Serif</option>\n            <option value="proportionalSansSerif">Proportional Sans-Serif</option>\n            <option value="casual">Casual</option>\n            <option value="script">Script</option>\n            <option value="small-caps">Small Caps</option>\n          </select>\n        </div> <!-- vjs-font-family -->\n      </div>\n    </div>\n    <div class="vjs-tracksettings-controls">\n      <button class="vjs-default-button">Defaults</button>\n      <button class="vjs-done-button">Done</button>\n    </div>';

  return template;
}

exports['default'] = TextTrackSettings;
module.exports = exports['default'];

},{"../component":67,"../utils/events.js":133,"../utils/fn.js":134,"../utils/log.js":137,"global/window":2,"safe-json-parse/tuple":54}],128:[function(_dereq_,module,exports){
/**
 * @file text-track.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _textTrackCueList = _dereq_('./text-track-cue-list');

var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList);

var _utilsFnJs = _dereq_('../utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _utilsGuidJs = _dereq_('../utils/guid.js');

var Guid = _interopRequireWildcard(_utilsGuidJs);

var _utilsBrowserJs = _dereq_('../utils/browser.js');

var browser = _interopRequireWildcard(_utilsBrowserJs);

var _textTrackEnums = _dereq_('./text-track-enums');

var TextTrackEnum = _interopRequireWildcard(_textTrackEnums);

var _utilsLogJs = _dereq_('../utils/log.js');

var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);

var _eventTarget = _dereq_('../event-target');

var _eventTarget2 = _interopRequireDefault(_eventTarget);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

var _utilsUrlJs = _dereq_('../utils/url.js');

var _xhr = _dereq_('xhr');

var _xhr2 = _interopRequireDefault(_xhr);

/**
 * takes a webvtt file contents and parses it into cues
 *
 * @param {String} srcContent webVTT file contents
 * @param {Track} track track to addcues to
 */
var parseCues = function parseCues(srcContent, track) {
  var parser = new _globalWindow2['default'].WebVTT.Parser(_globalWindow2['default'], _globalWindow2['default'].vttjs, _globalWindow2['default'].WebVTT.StringDecoder());

  parser.oncue = function (cue) {
    track.addCue(cue);
  };

  parser.onparsingerror = function (error) {
    _utilsLogJs2['default'].error(error);
  };

  parser.onflush = function () {
    track.trigger({
      type: 'loadeddata',
      target: track
    });
  };

  parser.parse(srcContent);
  parser.flush();
};

/**
 * load a track from a  specifed url
 *
 * @param {String} src url to load track from
 * @param {Track} track track to addcues to
 */
var loadTrack = function loadTrack(src, track) {
  var opts = {
    uri: src
  };
  var crossOrigin = _utilsUrlJs.isCrossOrigin(src);

  if (crossOrigin) {
    opts.cors = crossOrigin;
  }

  _xhr2['default'](opts, Fn.bind(this, function (err, response, responseBody) {
    if (err) {
      return _utilsLogJs2['default'].error(err, response);
    }

    track.loaded_ = true;

    // Make sure that vttjs has loaded, otherwise, wait till it finished loading
    // NOTE: this is only used for the alt/video.novtt.js build
    if (typeof _globalWindow2['default'].WebVTT !== 'function') {
      if (track.tech_) {
        (function () {
          var loadHandler = function loadHandler() {
            return parseCues(responseBody, track);
          };
          track.tech_.on('vttjsloaded', loadHandler);
          track.tech_.on('vttjserror', function () {
            _utilsLogJs2['default'].error('vttjs failed to load, stopping trying to process ' + track.src);
            track.tech_.off('vttjsloaded', loadHandler);
          });
        })();
      }
    } else {
      parseCues(responseBody, track);
    }
  }));
};

/**
 * A single text track as defined in:
 * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack
 *
 * interface TextTrack : EventTarget {
 *   readonly attribute TextTrackKind kind;
 *   readonly attribute DOMString label;
 *   readonly attribute DOMString language;
 *
 *   readonly attribute DOMString id;
 *   readonly attribute DOMString inBandMetadataTrackDispatchType;
 *
 *   attribute TextTrackMode mode;
 *
 *   readonly attribute TextTrackCueList? cues;
 *   readonly attribute TextTrackCueList? activeCues;
 *
 *   void addCue(TextTrackCue cue);
 *   void removeCue(TextTrackCue cue);
 *
 *   attribute EventHandler oncuechange;
 * };
 *
 * @param {Object=} options Object of option names and values
 * @extends EventTarget
 * @class TextTrack
 */

var TextTrack = (function (_EventTarget) {
  _inherits(TextTrack, _EventTarget);

  function TextTrack() {
    var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];

    _classCallCheck(this, TextTrack);

    _EventTarget.call(this);
    if (!options.tech) {
      throw new Error('A tech was not provided.');
    }

    var tt = this;

    if (browser.IS_IE8) {
      tt = _globalDocument2['default'].createElement('custom');

      for (var prop in TextTrack.prototype) {
        if (prop !== 'constructor') {
          tt[prop] = TextTrack.prototype[prop];
        }
      }
    }

    tt.tech_ = options.tech;

    var mode = TextTrackEnum.TextTrackMode[options.mode] || 'disabled';
    var kind = TextTrackEnum.TextTrackKind[options.kind] || 'subtitles';
    var label = options.label || '';
    var language = options.language || options.srclang || '';
    var id = options.id || 'vjs_text_track_' + Guid.newGUID();

    if (kind === 'metadata' || kind === 'chapters') {
      mode = 'hidden';
    }

    tt.cues_ = [];
    tt.activeCues_ = [];

    var cues = new _textTrackCueList2['default'](tt.cues_);
    var activeCues = new _textTrackCueList2['default'](tt.activeCues_);
    var changed = false;
    var timeupdateHandler = Fn.bind(tt, function () {
      this.activeCues;
      if (changed) {
        this.trigger('cuechange');
        changed = false;
      }
    });

    if (mode !== 'disabled') {
      tt.tech_.on('timeupdate', timeupdateHandler);
    }

    Object.defineProperty(tt, 'kind', {
      get: function get() {
        return kind;
      },
      set: function set() {}
    });

    Object.defineProperty(tt, 'label', {
      get: function get() {
        return label;
      },
      set: function set() {}
    });

    Object.defineProperty(tt, 'language', {
      get: function get() {
        return language;
      },
      set: function set() {}
    });

    Object.defineProperty(tt, 'id', {
      get: function get() {
        return id;
      },
      set: function set() {}
    });

    Object.defineProperty(tt, 'mode', {
      get: function get() {
        return mode;
      },
      set: function set(newMode) {
        if (!TextTrackEnum.TextTrackMode[newMode]) {
          return;
        }
        mode = newMode;
        if (mode === 'showing') {
          this.tech_.on('timeupdate', timeupdateHandler);
        }
        this.trigger('modechange');
      }
    });

    Object.defineProperty(tt, 'cues', {
      get: function get() {
        if (!this.loaded_) {
          return null;
        }

        return cues;
      },
      set: function set() {}
    });

    Object.defineProperty(tt, 'activeCues', {
      get: function get() {
        if (!this.loaded_) {
          return null;
        }

        // nothing to do
        if (this.cues.length === 0) {
          return activeCues;
        }

        var ct = this.tech_.currentTime();
        var active = [];

        for (var i = 0, l = this.cues.length; i < l; i++) {
          var cue = this.cues[i];

          if (cue.startTime <= ct && cue.endTime >= ct) {
            active.push(cue);
          } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) {
            active.push(cue);
          }
        }

        changed = false;

        if (active.length !== this.activeCues_.length) {
          changed = true;
        } else {
          for (var i = 0; i < active.length; i++) {
            if (this.activeCues_.indexOf(active[i]) === -1) {
              changed = true;
            }
          }
        }

        this.activeCues_ = active;
        activeCues.setCues_(this.activeCues_);

        return activeCues;
      },
      set: function set() {}
    });

    if (options.src) {
      tt.src = options.src;
      loadTrack(options.src, tt);
    } else {
      tt.loaded_ = true;
    }

    if (browser.IS_IE8) {
      return tt;
    }
  }

  /**
   * cuechange - One or more cues in the track have become active or stopped being active.
   */

  /**
   * add a cue to the internal list of cues
   *
   * @param {Object} cue the cue to add to our internal list
   * @method addCue
   */

  TextTrack.prototype.addCue = function addCue(cue) {
    var tracks = this.tech_.textTracks();

    if (tracks) {
      for (var i = 0; i < tracks.length; i++) {
        if (tracks[i] !== this) {
          tracks[i].removeCue(cue);
        }
      }
    }

    this.cues_.push(cue);
    this.cues.setCues_(this.cues_);
  };

  /**
   * remvoe a cue from our internal list
   *
   * @param {Object} removeCue the cue to remove from our internal list
   * @method removeCue
   */

  TextTrack.prototype.removeCue = function removeCue(_removeCue) {
    var removed = false;

    for (var i = 0, l = this.cues_.length; i < l; i++) {
      var cue = this.cues_[i];

      if (cue === _removeCue) {
        this.cues_.splice(i, 1);
        removed = true;
      }
    }

    if (removed) {
      this.cues.setCues_(this.cues_);
    }
  };

  return TextTrack;
})(_eventTarget2['default']);

TextTrack.prototype.allowedEvents_ = {
  cuechange: 'cuechange'
};

exports['default'] = TextTrack;
module.exports = exports['default'];

},{"../event-target":99,"../utils/browser.js":129,"../utils/fn.js":134,"../utils/guid.js":136,"../utils/log.js":137,"../utils/url.js":142,"./text-track-cue-list":122,"./text-track-enums":124,"global/document":1,"global/window":2,"xhr":56}],129:[function(_dereq_,module,exports){
/**
 * @file browser.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

var USER_AGENT = _globalWindow2['default'].navigator.userAgent;
var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT);
var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null;

/*
 * Device is an iPhone
 *
 * @type {Boolean}
 * @constant
 * @private
 */
var IS_IPAD = /iPad/i.test(USER_AGENT);

exports.IS_IPAD = IS_IPAD;
// The Facebook app's UIWebView identifies as both an iPhone and iPad, so
// to identify iPhones, we need to exclude iPads.
// http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/
var IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD;
exports.IS_IPHONE = IS_IPHONE;
var IS_IPOD = /iPod/i.test(USER_AGENT);
exports.IS_IPOD = IS_IPOD;
var IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;

exports.IS_IOS = IS_IOS;
var IOS_VERSION = (function () {
  var match = USER_AGENT.match(/OS (\d+)_/i);
  if (match && match[1]) {
    return match[1];
  }
})();

exports.IOS_VERSION = IOS_VERSION;
var IS_ANDROID = /Android/i.test(USER_AGENT);
exports.IS_ANDROID = IS_ANDROID;
var ANDROID_VERSION = (function () {
  // This matches Android Major.Minor.Patch versions
  // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
  var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i),
      major,
      minor;

  if (!match) {
    return null;
  }

  major = match[1] && parseFloat(match[1]);
  minor = match[2] && parseFloat(match[2]);

  if (major && minor) {
    return parseFloat(match[1] + '.' + match[2]);
  } else if (major) {
    return major;
  } else {
    return null;
  }
})();
exports.ANDROID_VERSION = ANDROID_VERSION;
// Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser
var IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3;
exports.IS_OLD_ANDROID = IS_OLD_ANDROID;
var IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537;

exports.IS_NATIVE_ANDROID = IS_NATIVE_ANDROID;
var IS_FIREFOX = /Firefox/i.test(USER_AGENT);
exports.IS_FIREFOX = IS_FIREFOX;
var IS_CHROME = /Chrome/i.test(USER_AGENT);
exports.IS_CHROME = IS_CHROME;
var IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT);

exports.IS_IE8 = IS_IE8;
var TOUCH_ENABLED = !!('ontouchstart' in _globalWindow2['default'] || _globalWindow2['default'].DocumentTouch && _globalDocument2['default'] instanceof _globalWindow2['default'].DocumentTouch);
exports.TOUCH_ENABLED = TOUCH_ENABLED;
var BACKGROUND_SIZE_SUPPORTED = ('backgroundSize' in _globalDocument2['default'].createElement('video').style);
exports.BACKGROUND_SIZE_SUPPORTED = BACKGROUND_SIZE_SUPPORTED;

},{"global/document":1,"global/window":2}],130:[function(_dereq_,module,exports){
/**
 * @file buffer.js
 */
'use strict';

exports.__esModule = true;
exports.bufferedPercent = bufferedPercent;

var _timeRangesJs = _dereq_('./time-ranges.js');

/**
 * Compute how much your video has been buffered
 *
 * @param  {Object} Buffered object
 * @param  {Number} Total duration
 * @return {Number} Percent buffered of the total duration
 * @private
 * @function bufferedPercent
 */

function bufferedPercent(buffered, duration) {
  var bufferedDuration = 0,
      start,
      end;

  if (!duration) {
    return 0;
  }

  if (!buffered || !buffered.length) {
    buffered = _timeRangesJs.createTimeRange(0, 0);
  }

  for (var i = 0; i < buffered.length; i++) {
    start = buffered.start(i);
    end = buffered.end(i);

    // buffered end can be bigger than duration by a very small fraction
    if (end > duration) {
      end = duration;
    }

    bufferedDuration += end - start;
  }

  return bufferedDuration / duration;
}

},{"./time-ranges.js":140}],131:[function(_dereq_,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _logJs = _dereq_('./log.js');

var _logJs2 = _interopRequireDefault(_logJs);

/**
 * Object containing the default behaviors for available handler methods.
 *
 * @private
 * @type {Object}
 */
var defaultBehaviors = {
  get: function get(obj, key) {
    return obj[key];
  },
  set: function set(obj, key, value) {
    obj[key] = value;
    return true;
  }
};

/**
 * Expose private objects publicly using a Proxy to log deprecation warnings.
 *
 * Browsers that do not support Proxy objects will simply return the `target`
 * object, so it can be directly exposed.
 *
 * @param {Object} target The target object.
 * @param {Object} messages Messages to display from a Proxy. Only operations
 *                          with an associated message will be proxied.
 * @param {String} [messages.get]
 * @param {String} [messages.set]
 * @return {Object} A Proxy if supported or the `target` argument.
 */

exports['default'] = function (target) {
  var messages = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

  if (typeof Proxy === 'function') {
    var _ret = (function () {
      var handler = {};

      // Build a handler object based on those keys that have both messages
      // and default behaviors.
      Object.keys(messages).forEach(function (key) {
        if (defaultBehaviors.hasOwnProperty(key)) {
          handler[key] = function () {
            _logJs2['default'].warn(messages[key]);
            return defaultBehaviors[key].apply(this, arguments);
          };
        }
      });

      return {
        v: new Proxy(target, handler)
      };
    })();

    if (typeof _ret === 'object') return _ret.v;
  }
  return target;
};

module.exports = exports['default'];

},{"./log.js":137}],132:[function(_dereq_,module,exports){
/**
 * @file dom.js
 */
'use strict';

exports.__esModule = true;
exports.getEl = getEl;
exports.createEl = createEl;
exports.textContent = textContent;
exports.insertElFirst = insertElFirst;
exports.getElData = getElData;
exports.hasElData = hasElData;
exports.removeElData = removeElData;
exports.hasElClass = hasElClass;
exports.addElClass = addElClass;
exports.removeElClass = removeElClass;
exports.toggleElClass = toggleElClass;
exports.setElAttributes = setElAttributes;
exports.getElAttributes = getElAttributes;
exports.blockTextSelection = blockTextSelection;
exports.unblockTextSelection = unblockTextSelection;
exports.findElPosition = findElPosition;
exports.getPointerPosition = getPointerPosition;
exports.isEl = isEl;
exports.isTextNode = isTextNode;
exports.emptyEl = emptyEl;
exports.normalizeContent = normalizeContent;
exports.appendContent = appendContent;
exports.insertContent = insertContent;

var _templateObject = _taggedTemplateLiteralLoose(['Setting attributes in the second argument of createEl()\n                has been deprecated. Use the third argument instead.\n                createEl(type, properties, attributes). Attempting to set ', ' to ', '.'], ['Setting attributes in the second argument of createEl()\n                has been deprecated. Use the third argument instead.\n                createEl(type, properties, attributes). Attempting to set ', ' to ', '.']);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

var _guidJs = _dereq_('./guid.js');

var Guid = _interopRequireWildcard(_guidJs);

var _logJs = _dereq_('./log.js');

var _logJs2 = _interopRequireDefault(_logJs);

var _tsml = _dereq_('tsml');

var _tsml2 = _interopRequireDefault(_tsml);

/**
 * Detect if a value is a string with any non-whitespace characters.
 *
 * @param  {String} str
 * @return {Boolean}
 */
function isNonBlankString(str) {
  return typeof str === 'string' && /\S/.test(str);
}

/**
 * Throws an error if the passed string has whitespace. This is used by
 * class methods to be relatively consistent with the classList API.
 *
 * @param  {String} str
 * @return {Boolean}
 */
function throwIfWhitespace(str) {
  if (/\s/.test(str)) {
    throw new Error('class has illegal whitespace characters');
  }
}

/**
 * Produce a regular expression for matching a class name.
 *
 * @param  {String} className
 * @return {RegExp}
 */
function classRegExp(className) {
  return new RegExp('(^|\\s)' + className + '($|\\s)');
}

/**
 * Creates functions to query the DOM using a given method.
 *
 * @function createQuerier
 * @private
 * @param  {String} method
 * @return {Function}
 */
function createQuerier(method) {
  return function (selector, context) {
    if (!isNonBlankString(selector)) {
      return _globalDocument2['default'][method](null);
    }
    if (isNonBlankString(context)) {
      context = _globalDocument2['default'].querySelector(context);
    }
    return (isEl(context) ? context : _globalDocument2['default'])[method](selector);
  };
}

/**
 * Shorthand for document.getElementById()
 * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs.
 *
 * @param  {String} id  Element ID
 * @return {Element}    Element with supplied ID
 * @function getEl
 */

function getEl(id) {
  if (id.indexOf('#') === 0) {
    id = id.slice(1);
  }

  return _globalDocument2['default'].getElementById(id);
}

/**
 * Creates an element and applies properties.
 *
 * @param  {String} [tagName='div'] Name of tag to be created.
 * @param  {Object} [properties={}] Element properties to be applied.
 * @param  {Object} [attributes={}] Element attributes to be applied.
 * @return {Element}
 * @function createEl
 */

function createEl() {
  var tagName = arguments.length <= 0 || arguments[0] === undefined ? 'div' : arguments[0];
  var properties = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
  var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];

  var el = _globalDocument2['default'].createElement(tagName);

  Object.getOwnPropertyNames(properties).forEach(function (propName) {
    var val = properties[propName];

    // See #2176
    // We originally were accepting both properties and attributes in the
    // same object, but that doesn't work so well.
    if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') {
      _logJs2['default'].warn(_tsml2['default'](_templateObject, propName, val));
      el.setAttribute(propName, val);
    } else {
      el[propName] = val;
    }
  });

  Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
    var val = attributes[attrName];
    el.setAttribute(attrName, attributes[attrName]);
  });

  return el;
}

/**
 * Injects text into an element, replacing any existing contents entirely.
 *
 * @param  {Element} el
 * @param  {String} text
 * @return {Element}
 * @function textContent
 */

function textContent(el, text) {
  if (typeof el.textContent === 'undefined') {
    el.innerText = text;
  } else {
    el.textContent = text;
  }
}

/**
 * Insert an element as the first child node of another
 *
 * @param  {Element} child   Element to insert
 * @param  {Element} parent Element to insert child into
 * @private
 * @function insertElFirst
 */

function insertElFirst(child, parent) {
  if (parent.firstChild) {
    parent.insertBefore(child, parent.firstChild);
  } else {
    parent.appendChild(child);
  }
}

/**
 * Element Data Store. Allows for binding data to an element without putting it directly on the element.
 * Ex. Event listeners are stored here.
 * (also from jsninja.com, slightly modified and updated for closure compiler)
 *
 * @type {Object}
 * @private
 */
var elData = {};

/*
 * Unique attribute name to store an element's guid in
 *
 * @type {String}
 * @constant
 * @private
 */
var elIdAttr = 'vdata' + new Date().getTime();

/**
 * Returns the cache object where data for an element is stored
 *
 * @param  {Element} el Element to store data for.
 * @return {Object}
 * @function getElData
 */

function getElData(el) {
  var id = el[elIdAttr];

  if (!id) {
    id = el[elIdAttr] = Guid.newGUID();
  }

  if (!elData[id]) {
    elData[id] = {};
  }

  return elData[id];
}

/**
 * Returns whether or not an element has cached data
 *
 * @param  {Element} el A dom element
 * @return {Boolean}
 * @private
 * @function hasElData
 */

function hasElData(el) {
  var id = el[elIdAttr];

  if (!id) {
    return false;
  }

  return !!Object.getOwnPropertyNames(elData[id]).length;
}

/**
 * Delete data for the element from the cache and the guid attr from getElementById
 *
 * @param  {Element} el Remove data for an element
 * @private
 * @function removeElData
 */

function removeElData(el) {
  var id = el[elIdAttr];

  if (!id) {
    return;
  }

  // Remove all stored data
  delete elData[id];

  // Remove the elIdAttr property from the DOM node
  try {
    delete el[elIdAttr];
  } catch (e) {
    if (el.removeAttribute) {
      el.removeAttribute(elIdAttr);
    } else {
      // IE doesn't appear to support removeAttribute on the document element
      el[elIdAttr] = null;
    }
  }
}

/**
 * Check if an element has a CSS class
 *
 * @function hasElClass
 * @param {Element} element Element to check
 * @param {String} classToCheck Classname to check
 */

function hasElClass(element, classToCheck) {
  if (element.classList) {
    return element.classList.contains(classToCheck);
  } else {
    throwIfWhitespace(classToCheck);
    return classRegExp(classToCheck).test(element.className);
  }
}

/**
 * Add a CSS class name to an element
 *
 * @function addElClass
 * @param {Element} element    Element to add class name to
 * @param {String} classToAdd Classname to add
 */

function addElClass(element, classToAdd) {
  if (element.classList) {
    element.classList.add(classToAdd);

    // Don't need to `throwIfWhitespace` here because `hasElClass` will do it
    // in the case of classList not being supported.
  } else if (!hasElClass(element, classToAdd)) {
      element.className = (element.className + ' ' + classToAdd).trim();
    }

  return element;
}

/**
 * Remove a CSS class name from an element
 *
 * @function removeElClass
 * @param {Element} element    Element to remove from class name
 * @param {String} classToRemove Classname to remove
 */

function removeElClass(element, classToRemove) {
  if (element.classList) {
    element.classList.remove(classToRemove);
  } else {
    throwIfWhitespace(classToRemove);
    element.className = element.className.split(/\s+/).filter(function (c) {
      return c !== classToRemove;
    }).join(' ');
  }

  return element;
}

/**
 * Adds or removes a CSS class name on an element depending on an optional
 * condition or the presence/absence of the class name.
 *
 * @function toggleElClass
 * @param    {Element} element
 * @param    {String} classToToggle
 * @param    {Boolean|Function} [predicate]
 *           Can be a function that returns a Boolean. If `true`, the class
 *           will be added; if `false`, the class will be removed. If not
 *           given, the class will be added if not present and vice versa.
 */

function toggleElClass(element, classToToggle, predicate) {

  // This CANNOT use `classList` internally because IE does not support the
  // second parameter to the `classList.toggle()` method! Which is fine because
  // `classList` will be used by the add/remove functions.
  var has = hasElClass(element, classToToggle);

  if (typeof predicate === 'function') {
    predicate = predicate(element, classToToggle);
  }

  if (typeof predicate !== 'boolean') {
    predicate = !has;
  }

  // If the necessary class operation matches the current state of the
  // element, no action is required.
  if (predicate === has) {
    return;
  }

  if (predicate) {
    addElClass(element, classToToggle);
  } else {
    removeElClass(element, classToToggle);
  }

  return element;
}

/**
 * Apply attributes to an HTML element.
 *
 * @param  {Element} el         Target element.
 * @param  {Object=} attributes Element attributes to be applied.
 * @private
 * @function setElAttributes
 */

function setElAttributes(el, attributes) {
  Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
    var attrValue = attributes[attrName];

    if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
      el.removeAttribute(attrName);
    } else {
      el.setAttribute(attrName, attrValue === true ? '' : attrValue);
    }
  });
}

/**
 * Get an element's attribute values, as defined on the HTML tag
 * Attributes are not the same as properties. They're defined on the tag
 * or with setAttribute (which shouldn't be used with HTML)
 * This will return true or false for boolean attributes.
 *
 * @param  {Element} tag Element from which to get tag attributes
 * @return {Object}
 * @private
 * @function getElAttributes
 */

function getElAttributes(tag) {
  var obj, knownBooleans, attrs, attrName, attrVal;

  obj = {};

  // known boolean attributes
  // we can check for matching boolean properties, but older browsers
  // won't know about HTML5 boolean attributes that we still read from
  knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ',';

  if (tag && tag.attributes && tag.attributes.length > 0) {
    attrs = tag.attributes;

    for (var i = attrs.length - 1; i >= 0; i--) {
      attrName = attrs[i].name;
      attrVal = attrs[i].value;

      // check for known booleans
      // the matching element property will return a value for typeof
      if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {
        // the value of an included boolean attribute is typically an empty
        // string ('') which would equal false if we just check for a false value.
        // we also don't want support bad code like autoplay='false'
        attrVal = attrVal !== null ? true : false;
      }

      obj[attrName] = attrVal;
    }
  }

  return obj;
}

/**
 * Attempt to block the ability to select text while dragging controls
 *
 * @return {Boolean}
 * @function blockTextSelection
 */

function blockTextSelection() {
  _globalDocument2['default'].body.focus();
  _globalDocument2['default'].onselectstart = function () {
    return false;
  };
}

/**
 * Turn off text selection blocking
 *
 * @return {Boolean}
 * @function unblockTextSelection
 */

function unblockTextSelection() {
  _globalDocument2['default'].onselectstart = function () {
    return true;
  };
}

/**
 * Offset Left
 * getBoundingClientRect technique from
 * John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/
 *
 * @function findElPosition
 * @param {Element} el Element from which to get offset
 * @return {Object}
 */

function findElPosition(el) {
  var box = undefined;

  if (el.getBoundingClientRect && el.parentNode) {
    box = el.getBoundingClientRect();
  }

  if (!box) {
    return {
      left: 0,
      top: 0
    };
  }

  var docEl = _globalDocument2['default'].documentElement;
  var body = _globalDocument2['default'].body;

  var clientLeft = docEl.clientLeft || body.clientLeft || 0;
  var scrollLeft = _globalWindow2['default'].pageXOffset || body.scrollLeft;
  var left = box.left + scrollLeft - clientLeft;

  var clientTop = docEl.clientTop || body.clientTop || 0;
  var scrollTop = _globalWindow2['default'].pageYOffset || body.scrollTop;
  var top = box.top + scrollTop - clientTop;

  // Android sometimes returns slightly off decimal values, so need to round
  return {
    left: Math.round(left),
    top: Math.round(top)
  };
}

/**
 * Get pointer position in element
 * Returns an object with x and y coordinates.
 * The base on the coordinates are the bottom left of the element.
 *
 * @function getPointerPosition
 * @param {Element} el Element on which to get the pointer position on
 * @param {Event} event Event object
 * @return {Object} This object will have x and y coordinates corresponding to the mouse position
 */

function getPointerPosition(el, event) {
  var position = {};
  var box = findElPosition(el);
  var boxW = el.offsetWidth;
  var boxH = el.offsetHeight;

  var boxY = box.top;
  var boxX = box.left;
  var pageY = event.pageY;
  var pageX = event.pageX;

  if (event.changedTouches) {
    pageX = event.changedTouches[0].pageX;
    pageY = event.changedTouches[0].pageY;
  }

  position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH));
  position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));

  return position;
}

/**
 * Determines, via duck typing, whether or not a value is a DOM element.
 *
 * @function isEl
 * @param    {Mixed} value
 * @return   {Boolean}
 */

function isEl(value) {
  return !!value && typeof value === 'object' && value.nodeType === 1;
}

/**
 * Determines, via duck typing, whether or not a value is a text node.
 *
 * @param  {Mixed} value
 * @return {Boolean}
 */

function isTextNode(value) {
  return !!value && typeof value === 'object' && value.nodeType === 3;
}

/**
 * Empties the contents of an element.
 *
 * @function emptyEl
 * @param    {Element} el
 * @return   {Element}
 */

function emptyEl(el) {
  while (el.firstChild) {
    el.removeChild(el.firstChild);
  }
  return el;
}

/**
 * Normalizes content for eventual insertion into the DOM.
 *
 * This allows a wide range of content definition methods, but protects
 * from falling into the trap of simply writing to `innerHTML`, which is
 * an XSS concern.
 *
 * The content for an element can be passed in multiple types and
 * combinations, whose behavior is as follows:
 *
 * - String
 *   Normalized into a text node.
 *
 * - Element, TextNode
 *   Passed through.
 *
 * - Array
 *   A one-dimensional array of strings, elements, nodes, or functions (which
 *   return single strings, elements, or nodes).
 *
 * - Function
 *   If the sole argument, is expected to produce a string, element,
 *   node, or array.
 *
 * @function normalizeContent
 * @param    {String|Element|TextNode|Array|Function} content
 * @return   {Array}
 */

function normalizeContent(content) {

  // First, invoke content if it is a function. If it produces an array,
  // that needs to happen before normalization.
  if (typeof content === 'function') {
    content = content();
  }

  // Next up, normalize to an array, so one or many items can be normalized,
  // filtered, and returned.
  return (Array.isArray(content) ? content : [content]).map(function (value) {

    // First, invoke value if it is a function to produce a new value,
    // which will be subsequently normalized to a Node of some kind.
    if (typeof value === 'function') {
      value = value();
    }

    if (isEl(value) || isTextNode(value)) {
      return value;
    }

    if (typeof value === 'string' && /\S/.test(value)) {
      return _globalDocument2['default'].createTextNode(value);
    }
  }).filter(function (value) {
    return value;
  });
}

/**
 * Normalizes and appends content to an element.
 *
 * @function appendContent
 * @param    {Element} el
 * @param    {String|Element|TextNode|Array|Function} content
 *           See: `normalizeContent`
 * @return   {Element}
 */

function appendContent(el, content) {
  normalizeContent(content).forEach(function (node) {
    return el.appendChild(node);
  });
  return el;
}

/**
 * Normalizes and inserts content into an element; this is identical to
 * `appendContent()`, except it empties the element first.
 *
 * @function insertContent
 * @param    {Element} el
 * @param    {String|Element|TextNode|Array|Function} content
 *           See: `normalizeContent`
 * @return   {Element}
 */

function insertContent(el, content) {
  return appendContent(emptyEl(el), content);
}

/**
 * Finds a single DOM element matching `selector` within the optional
 * `context` of another DOM element (defaulting to `document`).
 *
 * @function $
 * @param    {String} selector
 *           A valid CSS selector, which will be passed to `querySelector`.
 *
 * @param    {Element|String} [context=document]
 *           A DOM element within which to query. Can also be a selector
 *           string in which case the first matching element will be used
 *           as context. If missing (or no element matches selector), falls
 *           back to `document`.
 *
 * @return   {Element|null}
 */
var $ = createQuerier('querySelector');

exports.$ = $;
/**
 * Finds a all DOM elements matching `selector` within the optional
 * `context` of another DOM element (defaulting to `document`).
 *
 * @function $$
 * @param    {String} selector
 *           A valid CSS selector, which will be passed to `querySelectorAll`.
 *
 * @param    {Element|String} [context=document]
 *           A DOM element within which to query. Can also be a selector
 *           string in which case the first matching element will be used
 *           as context. If missing (or no element matches selector), falls
 *           back to `document`.
 *
 * @return   {NodeList}
 */
var $$ = createQuerier('querySelectorAll');
exports.$$ = $$;

},{"./guid.js":136,"./log.js":137,"global/document":1,"global/window":2,"tsml":55}],133:[function(_dereq_,module,exports){
/**
 * @file events.js
 *
 * Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/)
 * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible)
 * This should work very similarly to jQuery's events, however it's based off the book version which isn't as
 * robust as jquery's, so there's probably some differences.
 */

'use strict';

exports.__esModule = true;
exports.on = on;
exports.off = off;
exports.trigger = trigger;
exports.one = one;
exports.fixEvent = fixEvent;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

var _domJs = _dereq_('./dom.js');

var Dom = _interopRequireWildcard(_domJs);

var _guidJs = _dereq_('./guid.js');

var Guid = _interopRequireWildcard(_guidJs);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

/**
 * Add an event listener to element
 * It stores the handler function in a separate cache object
 * and adds a generic handler to the element's event,
 * along with a unique id (guid) to the element.
 *
 * @param  {Element|Object}   elem Element or object to bind listeners to
 * @param  {String|Array}   type Type of event to bind to.
 * @param  {Function} fn   Event listener.
 * @method on
 */

function on(elem, type, fn) {
  if (Array.isArray(type)) {
    return _handleMultipleEvents(on, elem, type, fn);
  }

  var data = Dom.getElData(elem);

  // We need a place to store all our handler data
  if (!data.handlers) data.handlers = {};

  if (!data.handlers[type]) data.handlers[type] = [];

  if (!fn.guid) fn.guid = Guid.newGUID();

  data.handlers[type].push(fn);

  if (!data.dispatcher) {
    data.disabled = false;

    data.dispatcher = function (event, hash) {

      if (data.disabled) return;
      event = fixEvent(event);

      var handlers = data.handlers[event.type];

      if (handlers) {
        // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.
        var handlersCopy = handlers.slice(0);

        for (var m = 0, n = handlersCopy.length; m < n; m++) {
          if (event.isImmediatePropagationStopped()) {
            break;
          } else {
            handlersCopy[m].call(elem, event, hash);
          }
        }
      }
    };
  }

  if (data.handlers[type].length === 1) {
    if (elem.addEventListener) {
      elem.addEventListener(type, data.dispatcher, false);
    } else if (elem.attachEvent) {
      elem.attachEvent('on' + type, data.dispatcher);
    }
  }
}

/**
 * Removes event listeners from an element
 *
 * @param  {Element|Object}   elem Object to remove listeners from
 * @param  {String|Array=}   type Type of listener to remove. Don't include to remove all events from element.
 * @param  {Function} fn   Specific listener to remove. Don't include to remove listeners for an event type.
 * @method off
 */

function off(elem, type, fn) {
  // Don't want to add a cache object through getElData if not needed
  if (!Dom.hasElData(elem)) return;

  var data = Dom.getElData(elem);

  // If no events exist, nothing to unbind
  if (!data.handlers) {
    return;
  }

  if (Array.isArray(type)) {
    return _handleMultipleEvents(off, elem, type, fn);
  }

  // Utility function
  var removeType = function removeType(t) {
    data.handlers[t] = [];
    _cleanUpEvents(elem, t);
  };

  // Are we removing all bound events?
  if (!type) {
    for (var t in data.handlers) {
      removeType(t);
    }return;
  }

  var handlers = data.handlers[type];

  // If no handlers exist, nothing to unbind
  if (!handlers) return;

  // If no listener was provided, remove all listeners for type
  if (!fn) {
    removeType(type);
    return;
  }

  // We're only removing a single handler
  if (fn.guid) {
    for (var n = 0; n < handlers.length; n++) {
      if (handlers[n].guid === fn.guid) {
        handlers.splice(n--, 1);
      }
    }
  }

  _cleanUpEvents(elem, type);
}

/**
 * Trigger an event for an element
 *
 * @param  {Element|Object}      elem  Element to trigger an event on
 * @param  {Event|Object|String} event A string (the type) or an event object with a type attribute
 * @param  {Object} [hash] data hash to pass along with the event
 * @return {Boolean=} Returned only if default was prevented
 * @method trigger
 */

function trigger(elem, event, hash) {
  // Fetches element data and a reference to the parent (for bubbling).
  // Don't want to add a data object to cache for every parent,
  // so checking hasElData first.
  var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {};
  var parent = elem.parentNode || elem.ownerDocument;
  // type = event.type || event,
  // handler;

  // If an event name was passed as a string, creates an event out of it
  if (typeof event === 'string') {
    event = { type: event, target: elem };
  }
  // Normalizes the event properties.
  event = fixEvent(event);

  // If the passed element has a dispatcher, executes the established handlers.
  if (elemData.dispatcher) {
    elemData.dispatcher.call(elem, event, hash);
  }

  // Unless explicitly stopped or the event does not bubble (e.g. media events)
  // recursively calls this function to bubble the event up the DOM.
  if (parent && !event.isPropagationStopped() && event.bubbles === true) {
    trigger.call(null, parent, event, hash);

    // If at the top of the DOM, triggers the default action unless disabled.
  } else if (!parent && !event.defaultPrevented) {
      var targetData = Dom.getElData(event.target);

      // Checks if the target has a default action for this event.
      if (event.target[event.type]) {
        // Temporarily disables event dispatching on the target as we have already executed the handler.
        targetData.disabled = true;
        // Executes the default action.
        if (typeof event.target[event.type] === 'function') {
          event.target[event.type]();
        }
        // Re-enables event dispatching.
        targetData.disabled = false;
      }
    }

  // Inform the triggerer if the default was prevented by returning false
  return !event.defaultPrevented;
}

/**
 * Trigger a listener only once for an event
 *
 * @param  {Element|Object}   elem Element or object to
 * @param  {String|Array}   type Name/type of event
 * @param  {Function} fn Event handler function
 * @method one
 */

function one(elem, type, fn) {
  if (Array.isArray(type)) {
    return _handleMultipleEvents(one, elem, type, fn);
  }
  var func = function func() {
    off(elem, type, func);
    fn.apply(this, arguments);
  };
  // copy the guid to the new function so it can removed using the original function's ID
  func.guid = fn.guid = fn.guid || Guid.newGUID();
  on(elem, type, func);
}

/**
 * Fix a native event to have standard property values
 *
 * @param  {Object} event Event object to fix
 * @return {Object}
 * @private
 * @method fixEvent
 */

function fixEvent(event) {

  function returnTrue() {
    return true;
  }
  function returnFalse() {
    return false;
  }

  // Test if fixing up is needed
  // Used to check if !event.stopPropagation instead of isPropagationStopped
  // But native events return true for stopPropagation, but don't have
  // other expected methods like isPropagationStopped. Seems to be a problem
  // with the Javascript Ninja code. So we're just overriding all events now.
  if (!event || !event.isPropagationStopped) {
    var old = event || _globalWindow2['default'].event;

    event = {};
    // Clone the old object so that we can modify the values event = {};
    // IE8 Doesn't like when you mess with native event properties
    // Firefox returns false for event.hasOwnProperty('type') and other props
    //  which makes copying more difficult.
    // TODO: Probably best to create a whitelist of event props
    for (var key in old) {
      // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
      // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation
      // and webkitMovementX/Y
      if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') {
        // Chrome 32+ warns if you try to copy deprecated returnValue, but
        // we still want to if preventDefault isn't supported (IE8).
        if (!(key === 'returnValue' && old.preventDefault)) {
          event[key] = old[key];
        }
      }
    }

    // The event occurred on this element
    if (!event.target) {
      event.target = event.srcElement || _globalDocument2['default'];
    }

    // Handle which other element the event is related to
    if (!event.relatedTarget) {
      event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
    }

    // Stop the default browser action
    event.preventDefault = function () {
      if (old.preventDefault) {
        old.preventDefault();
      }
      event.returnValue = false;
      old.returnValue = false;
      event.defaultPrevented = true;
    };

    event.defaultPrevented = false;

    // Stop the event from bubbling
    event.stopPropagation = function () {
      if (old.stopPropagation) {
        old.stopPropagation();
      }
      event.cancelBubble = true;
      old.cancelBubble = true;
      event.isPropagationStopped = returnTrue;
    };

    event.isPropagationStopped = returnFalse;

    // Stop the event from bubbling and executing other handlers
    event.stopImmediatePropagation = function () {
      if (old.stopImmediatePropagation) {
        old.stopImmediatePropagation();
      }
      event.isImmediatePropagationStopped = returnTrue;
      event.stopPropagation();
    };

    event.isImmediatePropagationStopped = returnFalse;

    // Handle mouse position
    if (event.clientX != null) {
      var doc = _globalDocument2['default'].documentElement,
          body = _globalDocument2['default'].body;

      event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
      event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
    }

    // Handle key presses
    event.which = event.charCode || event.keyCode;

    // Fix button for mouse clicks:
    // 0 == left; 1 == middle; 2 == right
    if (event.button != null) {
      event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0;
    }
  }

  // Returns fixed-up instance
  return event;
}

/**
 * Clean up the listener cache and dispatchers
*
 * @param  {Element|Object} elem Element to clean up
 * @param  {String} type Type of event to clean up
 * @private
 * @method _cleanUpEvents
 */
function _cleanUpEvents(elem, type) {
  var data = Dom.getElData(elem);

  // Remove the events of a particular type if there are none left
  if (data.handlers[type].length === 0) {
    delete data.handlers[type];
    // data.handlers[type] = null;
    // Setting to null was causing an error with data.handlers

    // Remove the meta-handler from the element
    if (elem.removeEventListener) {
      elem.removeEventListener(type, data.dispatcher, false);
    } else if (elem.detachEvent) {
      elem.detachEvent('on' + type, data.dispatcher);
    }
  }

  // Remove the events object if there are no types left
  if (Object.getOwnPropertyNames(data.handlers).length <= 0) {
    delete data.handlers;
    delete data.dispatcher;
    delete data.disabled;
  }

  // Finally remove the element data if there is no data left
  if (Object.getOwnPropertyNames(data).length === 0) {
    Dom.removeElData(elem);
  }
}

/**
 * Loops through an array of event types and calls the requested method for each type.
 *
 * @param  {Function} fn   The event method we want to use.
 * @param  {Element|Object} elem Element or object to bind listeners to
 * @param  {String}   type Type of event to bind to.
 * @param  {Function} callback   Event listener.
 * @private
 * @function _handleMultipleEvents
 */
function _handleMultipleEvents(fn, elem, types, callback) {
  types.forEach(function (type) {
    //Call the event method for each one of the types
    fn(elem, type, callback);
  });
}

},{"./dom.js":132,"./guid.js":136,"global/document":1,"global/window":2}],134:[function(_dereq_,module,exports){
/**
 * @file fn.js
 */
'use strict';

exports.__esModule = true;

var _guidJs = _dereq_('./guid.js');

/**
 * Bind (a.k.a proxy or Context). A simple method for changing the context of a function
 * It also stores a unique id on the function so it can be easily removed from events
 *
 * @param  {*}   context The object to bind as scope
 * @param  {Function} fn      The function to be bound to a scope
 * @param  {Number=}   uid     An optional unique ID for the function to be set
 * @return {Function}
 * @private
 * @method bind
 */
var bind = function bind(context, fn, uid) {
  // Make sure the function has a unique ID
  if (!fn.guid) {
    fn.guid = _guidJs.newGUID();
  }

  // Create the new function that changes the context
  var ret = function ret() {
    return fn.apply(context, arguments);
  };

  // Allow for the ability to individualize this function
  // Needed in the case where multiple objects might share the same prototype
  // IF both items add an event listener with the same function, then you try to remove just one
  // it will remove both because they both have the same guid.
  // when using this, you need to use the bind method when you remove the listener as well.
  // currently used in text tracks
  ret.guid = uid ? uid + '_' + fn.guid : fn.guid;

  return ret;
};
exports.bind = bind;

},{"./guid.js":136}],135:[function(_dereq_,module,exports){
/**
 * @file format-time.js
 *
 * Format seconds as a time string, H:MM:SS or M:SS
 * Supplying a guide (in seconds) will force a number of leading zeros
 * to cover the length of the guide
 *
 * @param  {Number} seconds Number of seconds to be turned into a string
 * @param  {Number} guide   Number (in seconds) to model the string after
 * @return {String}         Time formatted as H:MM:SS or M:SS
 * @private
 * @function formatTime
 */
'use strict';

exports.__esModule = true;
function formatTime(seconds) {
  var guide = arguments.length <= 1 || arguments[1] === undefined ? seconds : arguments[1];
  return (function () {
    seconds = seconds < 0 ? 0 : seconds;
    var s = Math.floor(seconds % 60);
    var m = Math.floor(seconds / 60 % 60);
    var h = Math.floor(seconds / 3600);
    var gm = Math.floor(guide / 60 % 60);
    var gh = Math.floor(guide / 3600);

    // handle invalid times
    if (isNaN(seconds) || seconds === Infinity) {
      // '-' is false for all relational operators (e.g. <, >=) so this setting
      // will add the minimum number of fields specified by the guide
      h = m = s = '-';
    }

    // Check if we need to show hours
    h = h > 0 || gh > 0 ? h + ':' : '';

    // If hours are showing, we may need to add a leading zero.
    // Always show at least one digit of minutes.
    m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':';

    // Check if leading zero is need for seconds
    s = s < 10 ? '0' + s : s;

    return h + m + s;
  })();
}

exports['default'] = formatTime;
module.exports = exports['default'];

},{}],136:[function(_dereq_,module,exports){
/**
 * @file guid.js
 *
 * Unique ID for an element or function
 * @type {Number}
 * @private
 */
"use strict";

exports.__esModule = true;
exports.newGUID = newGUID;
var _guid = 1;

/**
 * Get the next unique ID
 *
 * @return {String} 
 * @function newGUID
 */

function newGUID() {
  return _guid++;
}

},{}],137:[function(_dereq_,module,exports){
/**
 * @file log.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

/**
 * Log plain debug messages
 */
var log = function log() {
  _logType(null, arguments);
};

/**
 * Keep a history of log messages
 * @type {Array}
 */
log.history = [];

/**
 * Log error messages
 */
log.error = function () {
  _logType('error', arguments);
};

/**
 * Log warning messages
 */
log.warn = function () {
  _logType('warn', arguments);
};

/**
 * Log messages to the console and history based on the type of message
 *
 * @param  {String} type The type of message, or `null` for `log`
 * @param  {Object} args The args to be passed to the log
 * @private
 * @method _logType
 */
function _logType(type, args) {
  // convert args to an array to get array functions
  var argsArray = Array.prototype.slice.call(args);
  // if there's no console then don't try to output messages
  // they will still be stored in log.history
  // Was setting these once outside of this function, but containing them
  // in the function makes it easier to test cases where console doesn't exist
  var noop = function noop() {};

  var console = _globalWindow2['default']['console'] || {
    'log': noop,
    'warn': noop,
    'error': noop
  };

  if (type) {
    // add the type to the front of the message
    argsArray.unshift(type.toUpperCase() + ':');
  } else {
    // default to log with no prefix
    type = 'log';
  }

  // add to history
  log.history.push(argsArray);

  // add console prefix after adding to history
  argsArray.unshift('VIDEOJS:');

  // call appropriate log function
  if (console[type].apply) {
    console[type].apply(console, argsArray);
  } else {
    // ie8 doesn't allow error.apply, but it will just join() the array anyway
    console[type](argsArray.join(' '));
  }
}

exports['default'] = log;
module.exports = exports['default'];

},{"global/window":2}],138:[function(_dereq_,module,exports){
/**
 * @file merge-options.js
 */
'use strict';

exports.__esModule = true;
exports['default'] = mergeOptions;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _lodashCompatObjectMerge = _dereq_('lodash-compat/object/merge');

var _lodashCompatObjectMerge2 = _interopRequireDefault(_lodashCompatObjectMerge);

function isPlain(obj) {
  return !!obj && typeof obj === 'object' && obj.toString() === '[object Object]' && obj.constructor === Object;
}

/**
 * Merge customizer. video.js simply overwrites non-simple objects
 * (like arrays) instead of attempting to overlay them.
 * @see https://lodash.com/docs#merge
 */
var customizer = function customizer(destination, source) {
  // If we're not working with a plain object, copy the value as is
  // If source is an array, for instance, it will replace destination
  if (!isPlain(source)) {
    return source;
  }

  // If the new value is a plain object but the first object value is not
  // we need to create a new object for the first object to merge with.
  // This makes it consistent with how merge() works by default
  // and also protects from later changes the to first object affecting
  // the second object's values.
  if (!isPlain(destination)) {
    return mergeOptions(source);
  }
};

/**
 * Merge one or more options objects, recursively merging **only**
 * plain object properties.  Previously `deepMerge`.
 *
 * @param  {...Object} source One or more objects to merge
 * @returns {Object}          a new object that is the union of all
 * provided objects
 * @function mergeOptions
 */

function mergeOptions() {
  // contruct the call dynamically to handle the variable number of
  // objects to merge
  var args = Array.prototype.slice.call(arguments);

  // unshift an empty object into the front of the call as the target
  // of the merge
  args.unshift({});

  // customize conflict resolution to match our historical merge behavior
  args.push(customizer);

  _lodashCompatObjectMerge2['default'].apply(null, args);

  // return the mutated result object
  return args[0];
}

module.exports = exports['default'];

},{"lodash-compat/object/merge":40}],139:[function(_dereq_,module,exports){
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var createStyleElement = function createStyleElement(className) {
  var style = _globalDocument2['default'].createElement('style');
  style.className = className;

  return style;
};

exports.createStyleElement = createStyleElement;
var setTextContent = function setTextContent(el, content) {
  if (el.styleSheet) {
    el.styleSheet.cssText = content;
  } else {
    el.textContent = content;
  }
};
exports.setTextContent = setTextContent;

},{"global/document":1}],140:[function(_dereq_,module,exports){
'use strict';

exports.__esModule = true;
exports.createTimeRanges = createTimeRanges;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _logJs = _dereq_('./log.js');

var _logJs2 = _interopRequireDefault(_logJs);

/**
 * @file time-ranges.js
 *
 * Should create a fake TimeRange object
 * Mimics an HTML5 time range instance, which has functions that
 * return the start and end times for a range
 * TimeRanges are returned by the buffered() method
 *
 * @param  {(Number|Array)} Start of a single range or an array of ranges
 * @param  {Number} End of a single range
 * @private
 * @method createTimeRanges
 */

function createTimeRanges(start, end) {
  if (Array.isArray(start)) {
    return createTimeRangesObj(start);
  } else if (start === undefined || end === undefined) {
    return createTimeRangesObj();
  }
  return createTimeRangesObj([[start, end]]);
}

exports.createTimeRange = createTimeRanges;

function createTimeRangesObj(ranges) {
  if (ranges === undefined || ranges.length === 0) {
    return {
      length: 0,
      start: function start() {
        throw new Error('This TimeRanges object is empty');
      },
      end: function end() {
        throw new Error('This TimeRanges object is empty');
      }
    };
  }
  return {
    length: ranges.length,
    start: getRange.bind(null, 'start', 0, ranges),
    end: getRange.bind(null, 'end', 1, ranges)
  };
}

function getRange(fnName, valueIndex, ranges, rangeIndex) {
  if (rangeIndex === undefined) {
    _logJs2['default'].warn('DEPRECATED: Function \'' + fnName + '\' on \'TimeRanges\' called without an index argument.');
    rangeIndex = 0;
  }
  rangeCheck(fnName, rangeIndex, ranges.length - 1);
  return ranges[rangeIndex][valueIndex];
}

function rangeCheck(fnName, index, maxIndex) {
  if (index < 0 || index > maxIndex) {
    throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is greater than or equal to the maximum bound (' + maxIndex + ').');
  }
}

},{"./log.js":137}],141:[function(_dereq_,module,exports){
/**
 * @file to-title-case.js
 *
 * Uppercase the first letter of a string
 *
 * @param  {String} string String to be uppercased
 * @return {String}
 * @private
 * @method toTitleCase
 */
"use strict";

exports.__esModule = true;
function toTitleCase(string) {
  return string.charAt(0).toUpperCase() + string.slice(1);
}

exports["default"] = toTitleCase;
module.exports = exports["default"];

},{}],142:[function(_dereq_,module,exports){
/**
 * @file url.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var _globalWindow = _dereq_('global/window');

var _globalWindow2 = _interopRequireDefault(_globalWindow);

/**
 * Resolve and parse the elements of a URL
 *
 * @param  {String} url The url to parse
 * @return {Object}     An object of url details
 * @method parseUrl
 */
var parseUrl = function parseUrl(url) {
  var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host'];

  // add the url to an anchor and let the browser parse the URL
  var a = _globalDocument2['default'].createElement('a');
  a.href = url;

  // IE8 (and 9?) Fix
  // ie8 doesn't parse the URL correctly until the anchor is actually
  // added to the body, and an innerHTML is needed to trigger the parsing
  var addToBody = a.host === '' && a.protocol !== 'file:';
  var div = undefined;
  if (addToBody) {
    div = _globalDocument2['default'].createElement('div');
    div.innerHTML = '<a href="' + url + '"></a>';
    a = div.firstChild;
    // prevent the div from affecting layout
    div.setAttribute('style', 'display:none; position:absolute;');
    _globalDocument2['default'].body.appendChild(div);
  }

  // Copy the specific URL properties to a new object
  // This is also needed for IE8 because the anchor loses its
  // properties when it's removed from the dom
  var details = {};
  for (var i = 0; i < props.length; i++) {
    details[props[i]] = a[props[i]];
  }

  // IE9 adds the port to the host property unlike everyone else. If
  // a port identifier is added for standard ports, strip it.
  if (details.protocol === 'http:') {
    details.host = details.host.replace(/:80$/, '');
  }
  if (details.protocol === 'https:') {
    details.host = details.host.replace(/:443$/, '');
  }

  if (addToBody) {
    _globalDocument2['default'].body.removeChild(div);
  }

  return details;
};

exports.parseUrl = parseUrl;
/**
 * Get absolute version of relative URL. Used to tell flash correct URL.
 * http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
 *
 * @param  {String} url URL to make absolute
 * @return {String}     Absolute URL
 * @private
 * @method getAbsoluteURL
 */
var getAbsoluteURL = function getAbsoluteURL(url) {
  // Check if absolute URL
  if (!url.match(/^https?:\/\//)) {
    // Convert to absolute URL. Flash hosted off-site needs an absolute URL.
    var div = _globalDocument2['default'].createElement('div');
    div.innerHTML = '<a href="' + url + '">x</a>';
    url = div.firstChild.href;
  }

  return url;
};

exports.getAbsoluteURL = getAbsoluteURL;
/**
 * Returns the extension of the passed file name. It will return an empty string if you pass an invalid path
 *
 * @param {String}    path    The fileName path like '/path/to/file.mp4'
 * @returns {String}          The extension in lower case or an empty string if no extension could be found.
 * @method getFileExtension
 */
var getFileExtension = function getFileExtension(path) {
  if (typeof path === 'string') {
    var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i;
    var pathParts = splitPathRe.exec(path);

    if (pathParts) {
      return pathParts.pop().toLowerCase();
    }
  }

  return '';
};

exports.getFileExtension = getFileExtension;
/**
 * Returns whether the url passed is a cross domain request or not.
 *
 * @param {String} url The url to check
 * @return {Boolean}   Whether it is a cross domain request or not
 * @method isCrossOrigin
 */
var isCrossOrigin = function isCrossOrigin(url) {
  var winLoc = _globalWindow2['default'].location;
  var urlInfo = parseUrl(url);

  // IE8 protocol relative urls will return ':' for protocol
  var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol;

  // Check if url is for another domain/origin
  // IE8 doesn't know location.origin, so we won't rely on it here
  var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host;

  return crossOrigin;
};
exports.isCrossOrigin = isCrossOrigin;

},{"global/document":1,"global/window":2}],143:[function(_dereq_,module,exports){
/**
 * @file video.js
 */
'use strict';

exports.__esModule = true;

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _globalDocument = _dereq_('global/document');

var _globalDocument2 = _interopRequireDefault(_globalDocument);

var _setup = _dereq_('./setup');

var setup = _interopRequireWildcard(_setup);

var _utilsStylesheetJs = _dereq_('./utils/stylesheet.js');

var stylesheet = _interopRequireWildcard(_utilsStylesheetJs);

var _component = _dereq_('./component');

var _component2 = _interopRequireDefault(_component);

var _eventTarget = _dereq_('./event-target');

var _eventTarget2 = _interopRequireDefault(_eventTarget);

var _utilsEventsJs = _dereq_('./utils/events.js');

var Events = _interopRequireWildcard(_utilsEventsJs);

var _player = _dereq_('./player');

var _player2 = _interopRequireDefault(_player);

var _pluginsJs = _dereq_('./plugins.js');

var _pluginsJs2 = _interopRequireDefault(_pluginsJs);

var _srcJsUtilsMergeOptionsJs = _dereq_('../../src/js/utils/merge-options.js');

var _srcJsUtilsMergeOptionsJs2 = _interopRequireDefault(_srcJsUtilsMergeOptionsJs);

var _utilsFnJs = _dereq_('./utils/fn.js');

var Fn = _interopRequireWildcard(_utilsFnJs);

var _tracksTextTrackJs = _dereq_('./tracks/text-track.js');

var _tracksTextTrackJs2 = _interopRequireDefault(_tracksTextTrackJs);

var _objectAssign = _dereq_('object.assign');

var _objectAssign2 = _interopRequireDefault(_objectAssign);

var _utilsTimeRangesJs = _dereq_('./utils/time-ranges.js');

var _utilsFormatTimeJs = _dereq_('./utils/format-time.js');

var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);

var _utilsLogJs = _dereq_('./utils/log.js');

var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);

var _utilsDomJs = _dereq_('./utils/dom.js');

var Dom = _interopRequireWildcard(_utilsDomJs);

var _utilsBrowserJs = _dereq_('./utils/browser.js');

var browser = _interopRequireWildcard(_utilsBrowserJs);

var _utilsUrlJs = _dereq_('./utils/url.js');

var Url = _interopRequireWildcard(_utilsUrlJs);

var _extendJs = _dereq_('./extend.js');

var _extendJs2 = _interopRequireDefault(_extendJs);

var _lodashCompatObjectMerge = _dereq_('lodash-compat/object/merge');

var _lodashCompatObjectMerge2 = _interopRequireDefault(_lodashCompatObjectMerge);

var _utilsCreateDeprecationProxyJs = _dereq_('./utils/create-deprecation-proxy.js');

var _utilsCreateDeprecationProxyJs2 = _interopRequireDefault(_utilsCreateDeprecationProxyJs);

var _xhr = _dereq_('xhr');

var _xhr2 = _interopRequireDefault(_xhr);

// Include the built-in techs

var _techTechJs = _dereq_('./tech/tech.js');

var _techTechJs2 = _interopRequireDefault(_techTechJs);

var _techHtml5Js = _dereq_('./tech/html5.js');

var _techHtml5Js2 = _interopRequireDefault(_techHtml5Js);

var _techFlashJs = _dereq_('./tech/flash.js');

var _techFlashJs2 = _interopRequireDefault(_techFlashJs);

// HTML5 Element Shim for IE8
if (typeof HTMLVideoElement === 'undefined') {
  _globalDocument2['default'].createElement('video');
  _globalDocument2['default'].createElement('audio');
  _globalDocument2['default'].createElement('track');
}

/**
 * Doubles as the main function for users to create a player instance and also
 * the main library object.
 * The `videojs` function can be used to initialize or retrieve a player.
 * ```js
 *     var myPlayer = videojs('my_video_id');
 * ```
 *
 * @param  {String|Element} id      Video element or video element ID
 * @param  {Object=} options        Optional options object for config/settings
 * @param  {Function=} ready        Optional ready callback
 * @return {Player}                 A player instance
 * @mixes videojs
 * @method videojs
 */
var videojs = function videojs(id, options, ready) {
  var tag = undefined; // Element of ID

  // Allow for element or ID to be passed in
  // String ID
  if (typeof id === 'string') {

    // Adjust for jQuery ID syntax
    if (id.indexOf('#') === 0) {
      id = id.slice(1);
    }

    // If a player instance has already been created for this ID return it.
    if (videojs.getPlayers()[id]) {

      // If options or ready funtion are passed, warn
      if (options) {
        _utilsLogJs2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.');
      }

      if (ready) {
        videojs.getPlayers()[id].ready(ready);
      }

      return videojs.getPlayers()[id];

      // Otherwise get element for ID
    } else {
        tag = Dom.getEl(id);
      }

    // ID is a media element
  } else {
      tag = id;
    }

  // Check for a useable element
  if (!tag || !tag.nodeName) {
    // re: nodeName, could be a box div also
    throw new TypeError('The element or ID supplied is not valid. (videojs)'); // Returns
  }

  // Element may have a player attr referring to an already created player instance.
  // If not, set up a new player and return the instance.
  return tag['player'] || _player2['default'].players[tag.playerId] || new _player2['default'](tag, options, ready);
};

// Add default styles
var style = Dom.$('.vjs-styles-defaults');
if (!style) {
  style = stylesheet.createStyleElement('vjs-styles-defaults');
  var head = Dom.$('head');
  head.insertBefore(style, head.firstChild);
  stylesheet.setTextContent(style, '\n    .video-js {\n      width: 300px;\n      height: 150px;\n    }\n\n    .vjs-fluid {\n      padding-top: 56.25%\n    }\n  ');
}

// Run Auto-load players
// You have to wait at least once in case this script is loaded after your video in the DOM (weird behavior only with minified version)
setup.autoSetupTimeout(1, videojs);

/*
 * Current software version (semver)
 *
 * @type {String}
 */
videojs.VERSION = '5.8.8';

/**
 * The global options object. These are the settings that take effect
 * if no overrides are specified when the player is created.
 *
 * ```js
 *     videojs.options.autoplay = true
 *     // -> all players will autoplay by default
 * ```
 *
 * @type {Object}
 */
videojs.options = _player2['default'].prototype.options_;

/**
 * Get an object with the currently created players, keyed by player ID
 *
 * @return {Object} The created players
 * @mixes videojs
 * @method getPlayers
 */
videojs.getPlayers = function () {
  return _player2['default'].players;
};

/**
 * For backward compatibility, expose players object.
 *
 * @deprecated
 * @memberOf videojs
 * @property {Object|Proxy} players
 */
videojs.players = _utilsCreateDeprecationProxyJs2['default'](_player2['default'].players, {
  get: 'Access to videojs.players is deprecated; use videojs.getPlayers instead',
  set: 'Modification of videojs.players is deprecated'
});

/**
 * Get a component class object by name
 * ```js
 *     var VjsButton = videojs.getComponent('Button');
 *     // Create a new instance of the component
 *     var myButton = new VjsButton(myPlayer);
 * ```
 *
 * @return {Component} Component identified by name
 * @mixes videojs
 * @method getComponent
 */
videojs.getComponent = _component2['default'].getComponent;

/**
 * Register a component so it can referred to by name
 * Used when adding to other
 * components, either through addChild
 * `component.addChild('myComponent')`
 * or through default children options
 * `{ children: ['myComponent'] }`.
 * ```js
 *     // Get a component to subclass
 *     var VjsButton = videojs.getComponent('Button');
 *     // Subclass the component (see 'extend' doc for more info)
 *     var MySpecialButton = videojs.extend(VjsButton, {});
 *     // Register the new component
 *     VjsButton.registerComponent('MySepcialButton', MySepcialButton);
 *     // (optionally) add the new component as a default player child
 *     myPlayer.addChild('MySepcialButton');
 * ```
 * NOTE: You could also just initialize the component before adding.
 * `component.addChild(new MyComponent());`
 *
 * @param {String} The class name of the component
 * @param {Component} The component class
 * @return {Component} The newly registered component
 * @mixes videojs
 * @method registerComponent
 */
videojs.registerComponent = function (name, comp) {
  if (_techTechJs2['default'].isTech(comp)) {
    _utilsLogJs2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)');
  }

  _component2['default'].registerComponent.call(_component2['default'], name, comp);
};

/**
 * Get a Tech class object by name
 * ```js
 *     var Html5 = videojs.getTech('Html5');
 *     // Create a new instance of the component
 *     var html5 = new Html5(options);
 * ```
 *
 * @return {Tech} Tech identified by name
 * @mixes videojs
 * @method getComponent
 */
videojs.getTech = _techTechJs2['default'].getTech;

/**
 * Register a Tech so it can referred to by name.
 * This is used in the tech order for the player.
 *
 * ```js
 *     // get the Html5 Tech
 *     var Html5 = videojs.getTech('Html5');
 *     var MyTech = videojs.extend(Html5, {});
 *     // Register the new Tech
 *     VjsButton.registerTech('Tech', MyTech);
 *     var player = videojs('myplayer', {
 *       techOrder: ['myTech', 'html5']
 *     });
 * ```
 *
 * @param {String} The class name of the tech
 * @param {Tech} The tech class
 * @return {Tech} The newly registered Tech
 * @mixes videojs
 * @method registerTech
 */
videojs.registerTech = _techTechJs2['default'].registerTech;

/**
 * A suite of browser and device tests
 *
 * @type {Object}
 * @private
 */
videojs.browser = browser;

/**
 * Whether or not the browser supports touch events. Included for backward
 * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED`
 * instead going forward.
 *
 * @deprecated
 * @type {Boolean}
 */
videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED;

/**
 * Subclass an existing class
 * Mimics ES6 subclassing with the `extend` keyword
 * ```js
 *     // Create a basic javascript 'class'
 *     function MyClass(name){
 *       // Set a property at initialization
 *       this.myName = name;
 *     }
 *     // Create an instance method
 *     MyClass.prototype.sayMyName = function(){
 *       alert(this.myName);
 *     };
 *     // Subclass the exisitng class and change the name
 *     // when initializing
 *     var MySubClass = videojs.extend(MyClass, {
 *       constructor: function(name) {
 *         // Call the super class constructor for the subclass
 *         MyClass.call(this, name)
 *       }
 *     });
 *     // Create an instance of the new sub class
 *     var myInstance = new MySubClass('John');
 *     myInstance.sayMyName(); // -> should alert "John"
 * ```
 *
 * @param {Function} The Class to subclass
 * @param {Object} An object including instace methods for the new class
 *                   Optionally including a `constructor` function
 * @return {Function} The newly created subclass
 * @mixes videojs
 * @method extend
 */
videojs.extend = _extendJs2['default'];

/**
 * Merge two options objects recursively
 * Performs a deep merge like lodash.merge but **only merges plain objects**
 * (not arrays, elements, anything else)
 * Other values will be copied directly from the second object.
 * ```js
 *     var defaultOptions = {
 *       foo: true,
 *       bar: {
 *         a: true,
 *         b: [1,2,3]
 *       }
 *     };
 *     var newOptions = {
 *       foo: false,
 *       bar: {
 *         b: [4,5,6]
 *       }
 *     };
 *     var result = videojs.mergeOptions(defaultOptions, newOptions);
 *     // result.foo = false;
 *     // result.bar.a = true;
 *     // result.bar.b = [4,5,6];
 * ```
 *
 * @param {Object} defaults  The options object whose values will be overriden
 * @param {Object} overrides The options object with values to override the first
 * @param {Object} etc       Any number of additional options objects
 *
 * @return {Object} a new object with the merged values
 * @mixes videojs
 * @method mergeOptions
 */
videojs.mergeOptions = _srcJsUtilsMergeOptionsJs2['default'];

/**
 * Change the context (this) of a function
 *
 *     videojs.bind(newContext, function(){
 *       this === newContext
 *     });
 *
 * NOTE: as of v5.0 we require an ES5 shim, so you should use the native
 * `function(){}.bind(newContext);` instead of this.
 *
 * @param  {*}        context The object to bind as scope
 * @param  {Function} fn      The function to be bound to a scope
 * @param  {Number=}  uid     An optional unique ID for the function to be set
 * @return {Function}
 */
videojs.bind = Fn.bind;

/**
 * Create a Video.js player plugin
 * Plugins are only initialized when options for the plugin are included
 * in the player options, or the plugin function on the player instance is
 * called.
 * **See the plugin guide in the docs for a more detailed example**
 * ```js
 *     // Make a plugin that alerts when the player plays
 *     videojs.plugin('myPlugin', function(myPluginOptions) {
 *       myPluginOptions = myPluginOptions || {};
 *
 *       var player = this;
 *       var alertText = myPluginOptions.text || 'Player is playing!'
 *
 *       player.on('play', function(){
 *         alert(alertText);
 *       });
 *     });
 *     // USAGE EXAMPLES
 *     // EXAMPLE 1: New player with plugin options, call plugin immediately
 *     var player1 = videojs('idOne', {
 *       myPlugin: {
 *         text: 'Custom text!'
 *       }
 *     });
 *     // Click play
 *     // --> Should alert 'Custom text!'
 *     // EXAMPLE 3: New player, initialize plugin later
 *     var player3 = videojs('idThree');
 *     // Click play
 *     // --> NO ALERT
 *     // Click pause
 *     // Initialize plugin using the plugin function on the player instance
 *     player3.myPlugin({
 *       text: 'Plugin added later!'
 *     });
 *     // Click play
 *     // --> Should alert 'Plugin added later!'
 * ```
 *
 * @param {String} name The plugin name
 * @param {Function} fn The plugin function that will be called with options
 * @mixes videojs
 * @method plugin
 */
videojs.plugin = _pluginsJs2['default'];

/**
 * Adding languages so that they're available to all players.
 * ```js
 *     videojs.addLanguage('es', { 'Hello': 'Hola' });
 * ```
 *
 * @param  {String} code The language code or dictionary property
 * @param  {Object} data The data values to be translated
 * @return {Object} The resulting language dictionary object
 * @mixes videojs
 * @method addLanguage
 */
videojs.addLanguage = function (code, data) {
  var _merge;

  code = ('' + code).toLowerCase();
  return _lodashCompatObjectMerge2['default'](videojs.options.languages, (_merge = {}, _merge[code] = data, _merge))[code];
};

/**
 * Log debug messages.
 *
 * @param {...Object} messages One or more messages to log
 */
videojs.log = _utilsLogJs2['default'];

/**
 * Creates an emulated TimeRange object.
 *
 * @param  {Number|Array} start Start time in seconds or an array of ranges
 * @param  {Number} end   End time in seconds
 * @return {Object}       Fake TimeRange object
 * @method createTimeRange
 */
videojs.createTimeRange = videojs.createTimeRanges = _utilsTimeRangesJs.createTimeRanges;

/**
 * Format seconds as a time string, H:MM:SS or M:SS
 * Supplying a guide (in seconds) will force a number of leading zeros
 * to cover the length of the guide
 *
 * @param  {Number} seconds Number of seconds to be turned into a string
 * @param  {Number} guide   Number (in seconds) to model the string after
 * @return {String}         Time formatted as H:MM:SS or M:SS
 * @method formatTime
 */
videojs.formatTime = _utilsFormatTimeJs2['default'];

/**
 * Resolve and parse the elements of a URL
 *
 * @param  {String} url The url to parse
 * @return {Object}     An object of url details
 * @method parseUrl
 */
videojs.parseUrl = Url.parseUrl;

/**
 * Returns whether the url passed is a cross domain request or not.
 *
 * @param {String} url The url to check
 * @return {Boolean}   Whether it is a cross domain request or not
 * @method isCrossOrigin
 */
videojs.isCrossOrigin = Url.isCrossOrigin;

/**
 * Event target class.
 *
 * @type {Function}
 */
videojs.EventTarget = _eventTarget2['default'];

/**
 * Add an event listener to element
 * It stores the handler function in a separate cache object
 * and adds a generic handler to the element's event,
 * along with a unique id (guid) to the element.
 *
 * @param  {Element|Object}   elem Element or object to bind listeners to
 * @param  {String|Array}   type Type of event to bind to.
 * @param  {Function} fn   Event listener.
 * @method on
 */
videojs.on = Events.on;

/**
 * Trigger a listener only once for an event
 *
 * @param  {Element|Object}   elem Element or object to
 * @param  {String|Array}   type Name/type of event
 * @param  {Function} fn Event handler function
 * @method one
 */
videojs.one = Events.one;

/**
 * Removes event listeners from an element
 *
 * @param  {Element|Object}   elem Object to remove listeners from
 * @param  {String|Array=}   type Type of listener to remove. Don't include to remove all events from element.
 * @param  {Function} fn   Specific listener to remove. Don't include to remove listeners for an event type.
 * @method off
 */
videojs.off = Events.off;

/**
 * Trigger an event for an element
 *
 * @param  {Element|Object}      elem  Element to trigger an event on
 * @param  {Event|Object|String} event A string (the type) or an event object with a type attribute
 * @param  {Object} [hash] data hash to pass along with the event
 * @return {Boolean=} Returned only if default was prevented
 * @method trigger
 */
videojs.trigger = Events.trigger;

/**
 * A cross-browser XMLHttpRequest wrapper. Here's a simple example:
 *
 *     videojs.xhr({
 *       body: someJSONString,
 *       uri: "/foo",
 *       headers: {
 *         "Content-Type": "application/json"
 *       }
 *     }, function (err, resp, body) {
 *       // check resp.statusCode
 *     });
 *
 * Check out the [full
 * documentation](https://github.com/Raynos/xhr/blob/v2.1.0/README.md)
 * for more options.
 *
 * @param {Object} options settings for the request.
 * @return {XMLHttpRequest|XDomainRequest} the request object.
 * @see https://github.com/Raynos/xhr
 */
videojs.xhr = _xhr2['default'];

/**
 * TextTrack class
 *
 * @type {Function}
 */
videojs.TextTrack = _tracksTextTrackJs2['default'];

/**
 * Determines, via duck typing, whether or not a value is a DOM element.
 *
 * @method isEl
 * @param  {Mixed} value
 * @return {Boolean}
 */
videojs.isEl = Dom.isEl;

/**
 * Determines, via duck typing, whether or not a value is a text node.
 *
 * @method isTextNode
 * @param  {Mixed} value
 * @return {Boolean}
 */
videojs.isTextNode = Dom.isTextNode;

/**
 * Creates an element and applies properties.
 *
 * @method createEl
 * @param  {String} [tagName='div'] Name of tag to be created.
 * @param  {Object} [properties={}] Element properties to be applied.
 * @param  {Object} [attributes={}] Element attributes to be applied.
 * @return {Element}
 */
videojs.createEl = Dom.createEl;

/**
 * Check if an element has a CSS class
 *
 * @method hasClass
 * @param {Element} element Element to check
 * @param {String} classToCheck Classname to check
 */
videojs.hasClass = Dom.hasElClass;

/**
 * Add a CSS class name to an element
 *
 * @method addClass
 * @param {Element} element    Element to add class name to
 * @param {String} classToAdd Classname to add
 */
videojs.addClass = Dom.addElClass;

/**
 * Remove a CSS class name from an element
 *
 * @method removeClass
 * @param {Element} element    Element to remove from class name
 * @param {String} classToRemove Classname to remove
 */
videojs.removeClass = Dom.removeElClass;

/**
 * Adds or removes a CSS class name on an element depending on an optional
 * condition or the presence/absence of the class name.
 *
 * @method toggleElClass
 * @param  {Element} element
 * @param  {String} classToToggle
 * @param  {Boolean|Function} [predicate]
 *         Can be a function that returns a Boolean. If `true`, the class
 *         will be added; if `false`, the class will be removed. If not
 *         given, the class will be added if not present and vice versa.
 */
videojs.toggleClass = Dom.toggleElClass;

/**
 * Apply attributes to an HTML element.
 *
 * @method setAttributes
 * @param  {Element} el         Target element.
 * @param  {Object=} attributes Element attributes to be applied.
 */
videojs.setAttributes = Dom.setElAttributes;

/**
 * Get an element's attribute values, as defined on the HTML tag
 * Attributes are not the same as properties. They're defined on the tag
 * or with setAttribute (which shouldn't be used with HTML)
 * This will return true or false for boolean attributes.
 *
 * @method getAttributes
 * @param  {Element} tag Element from which to get tag attributes
 * @return {Object}
 */
videojs.getAttributes = Dom.getElAttributes;

/**
 * Empties the contents of an element.
 *
 * @method emptyEl
 * @param  {Element} el
 * @return {Element}
 */
videojs.emptyEl = Dom.emptyEl;

/**
 * Normalizes and appends content to an element.
 *
 * The content for an element can be passed in multiple types and
 * combinations, whose behavior is as follows:
 *
 * - String
 *   Normalized into a text node.
 *
 * - Element, TextNode
 *   Passed through.
 *
 * - Array
 *   A one-dimensional array of strings, elements, nodes, or functions (which
 *   return single strings, elements, or nodes).
 *
 * - Function
 *   If the sole argument, is expected to produce a string, element,
 *   node, or array.
 *
 * @method appendContent
 * @param  {Element} el
 * @param  {String|Element|TextNode|Array|Function} content
 * @return {Element}
 */
videojs.appendContent = Dom.appendContent;

/**
 * Normalizes and inserts content into an element; this is identical to
 * `appendContent()`, except it empties the element first.
 *
 * The content for an element can be passed in multiple types and
 * combinations, whose behavior is as follows:
 *
 * - String
 *   Normalized into a text node.
 *
 * - Element, TextNode
 *   Passed through.
 *
 * - Array
 *   A one-dimensional array of strings, elements, nodes, or functions (which
 *   return single strings, elements, or nodes).
 *
 * - Function
 *   If the sole argument, is expected to produce a string, element,
 *   node, or array.
 *
 * @method insertContent
 * @param  {Element} el
 * @param  {String|Element|TextNode|Array|Function} content
 * @return {Element}
 */
videojs.insertContent = Dom.insertContent;

/*
 * Custom Universal Module Definition (UMD)
 *
 * Video.js will never be a non-browser lib so we can simplify UMD a bunch and
 * still support requirejs and browserify. This also needs to be closure
 * compiler compatible, so string keys are used.
 */
if (typeof define === 'function' && define['amd']) {
  define('videojs', [], function () {
    return videojs;
  });

  // checking that module is an object too because of umdjs/umd#35
} else if (typeof exports === 'object' && typeof module === 'object') {
    module['exports'] = videojs;
  }

exports['default'] = videojs;
module.exports = exports['default'];

},{"../../src/js/utils/merge-options.js":138,"./component":67,"./event-target":99,"./extend.js":100,"./player":108,"./plugins.js":109,"./setup":113,"./tech/flash.js":116,"./tech/html5.js":117,"./tech/tech.js":119,"./tracks/text-track.js":128,"./utils/browser.js":129,"./utils/create-deprecation-proxy.js":131,"./utils/dom.js":132,"./utils/events.js":133,"./utils/fn.js":134,"./utils/format-time.js":135,"./utils/log.js":137,"./utils/stylesheet.js":139,"./utils/time-ranges.js":140,"./utils/url.js":142,"global/document":1,"lodash-compat/object/merge":40,"object.assign":45,"xhr":56}]},{},[143])(143)
});


//# sourceMappingURL=video.js.map
/* vtt.js - v0.12.1 (https://github.com/mozilla/vtt.js) built on 08-07-2015 */

(function(root) {
  var vttjs = root.vttjs = {};
  var cueShim = vttjs.VTTCue;
  var regionShim = vttjs.VTTRegion;
  var oldVTTCue = root.VTTCue;
  var oldVTTRegion = root.VTTRegion;

  vttjs.shim = function() {
    vttjs.VTTCue = cueShim;
    vttjs.VTTRegion = regionShim;
  };

  vttjs.restore = function() {
    vttjs.VTTCue = oldVTTCue;
    vttjs.VTTRegion = oldVTTRegion;
  };
}(this));

/**
 * Copyright 2013 vtt.js Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

(function(root, vttjs) {

  var autoKeyword = "auto";
  var directionSetting = {
    "": true,
    "lr": true,
    "rl": true
  };
  var alignSetting = {
    "start": true,
    "middle": true,
    "end": true,
    "left": true,
    "right": true
  };

  function findDirectionSetting(value) {
    if (typeof value !== "string") {
      return false;
    }
    var dir = directionSetting[value.toLowerCase()];
    return dir ? value.toLowerCase() : false;
  }

  function findAlignSetting(value) {
    if (typeof value !== "string") {
      return false;
    }
    var align = alignSetting[value.toLowerCase()];
    return align ? value.toLowerCase() : false;
  }

  function extend(obj) {
    var i = 1;
    for (; i < arguments.length; i++) {
      var cobj = arguments[i];
      for (var p in cobj) {
        obj[p] = cobj[p];
      }
    }

    return obj;
  }

  function VTTCue(startTime, endTime, text) {
    var cue = this;
    var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
    var baseObj = {};

    if (isIE8) {
      cue = document.createElement('custom');
    } else {
      baseObj.enumerable = true;
    }

    /**
     * Shim implementation specific properties. These properties are not in
     * the spec.
     */

    // Lets us know when the VTTCue's data has changed in such a way that we need
    // to recompute its display state. This lets us compute its display state
    // lazily.
    cue.hasBeenReset = false;

    /**
     * VTTCue and TextTrackCue properties
     * http://dev.w3.org/html5/webvtt/#vttcue-interface
     */

    var _id = "";
    var _pauseOnExit = false;
    var _startTime = startTime;
    var _endTime = endTime;
    var _text = text;
    var _region = null;
    var _vertical = "";
    var _snapToLines = true;
    var _line = "auto";
    var _lineAlign = "start";
    var _position = 50;
    var _positionAlign = "middle";
    var _size = 50;
    var _align = "middle";

    Object.defineProperty(cue,
      "id", extend({}, baseObj, {
        get: function() {
          return _id;
        },
        set: function(value) {
          _id = "" + value;
        }
      }));

    Object.defineProperty(cue,
      "pauseOnExit", extend({}, baseObj, {
        get: function() {
          return _pauseOnExit;
        },
        set: function(value) {
          _pauseOnExit = !!value;
        }
      }));

    Object.defineProperty(cue,
      "startTime", extend({}, baseObj, {
        get: function() {
          return _startTime;
        },
        set: function(value) {
          if (typeof value !== "number") {
            throw new TypeError("Start time must be set to a number.");
          }
          _startTime = value;
          this.hasBeenReset = true;
        }
      }));

    Object.defineProperty(cue,
      "endTime", extend({}, baseObj, {
        get: function() {
          return _endTime;
        },
        set: function(value) {
          if (typeof value !== "number") {
            throw new TypeError("End time must be set to a number.");
          }
          _endTime = value;
          this.hasBeenReset = true;
        }
      }));

    Object.defineProperty(cue,
      "text", extend({}, baseObj, {
        get: function() {
          return _text;
        },
        set: function(value) {
          _text = "" + value;
          this.hasBeenReset = true;
        }
      }));

    Object.defineProperty(cue,
      "region", extend({}, baseObj, {
        get: function() {
          return _region;
        },
        set: function(value) {
          _region = value;
          this.hasBeenReset = true;
        }
      }));

    Object.defineProperty(cue,
      "vertical", extend({}, baseObj, {
        get: function() {
          return _vertical;
        },
        set: function(value) {
          var setting = findDirectionSetting(value);
          // Have to check for false because the setting an be an empty string.
          if (setting === false) {
            throw new SyntaxError("An invalid or illegal string was specified.");
          }
          _vertical = setting;
          this.hasBeenReset = true;
        }
      }));

    Object.defineProperty(cue,
      "snapToLines", extend({}, baseObj, {
        get: function() {
          return _snapToLines;
        },
        set: function(value) {
          _snapToLines = !!value;
          this.hasBeenReset = true;
        }
      }));

    Object.defineProperty(cue,
      "line", extend({}, baseObj, {
        get: function() {
          return _line;
        },
        set: function(value) {
          if (typeof value !== "number" && value !== autoKeyword) {
            throw new SyntaxError("An invalid number or illegal string was specified.");
          }
          _line = value;
          this.hasBeenReset = true;
        }
      }));

    Object.defineProperty(cue,
      "lineAlign", extend({}, baseObj, {
        get: function() {
          return _lineAlign;
        },
        set: function(value) {
          var setting = findAlignSetting(value);
          if (!setting) {
            throw new SyntaxError("An invalid or illegal string was specified.");
          }
          _lineAlign = setting;
          this.hasBeenReset = true;
        }
      }));

    Object.defineProperty(cue,
      "position", extend({}, baseObj, {
        get: function() {
          return _position;
        },
        set: function(value) {
          if (value < 0 || value > 100) {
            throw new Error("Position must be between 0 and 100.");
          }
          _position = value;
          this.hasBeenReset = true;
        }
      }));

    Object.defineProperty(cue,
      "positionAlign", extend({}, baseObj, {
        get: function() {
          return _positionAlign;
        },
        set: function(value) {
          var setting = findAlignSetting(value);
          if (!setting) {
            throw new SyntaxError("An invalid or illegal string was specified.");
          }
          _positionAlign = setting;
          this.hasBeenReset = true;
        }
      }));

    Object.defineProperty(cue,
      "size", extend({}, baseObj, {
        get: function() {
          return _size;
        },
        set: function(value) {
          if (value < 0 || value > 100) {
            throw new Error("Size must be between 0 and 100.");
          }
          _size = value;
          this.hasBeenReset = true;
        }
      }));

    Object.defineProperty(cue,
      "align", extend({}, baseObj, {
        get: function() {
          return _align;
        },
        set: function(value) {
          var setting = findAlignSetting(value);
          if (!setting) {
            throw new SyntaxError("An invalid or illegal string was specified.");
          }
          _align = setting;
          this.hasBeenReset = true;
        }
      }));

    /**
     * Other <track> spec defined properties
     */

    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state
    cue.displayState = undefined;

    if (isIE8) {
      return cue;
    }
  }

  /**
   * VTTCue methods
   */

  VTTCue.prototype.getCueAsHTML = function() {
    // Assume WebVTT.convertCueToDOMTree is on the global.
    return WebVTT.convertCueToDOMTree(window, this.text);
  };

  root.VTTCue = root.VTTCue || VTTCue;
  vttjs.VTTCue = VTTCue;
}(this, (this.vttjs || {})));

/**
 * Copyright 2013 vtt.js Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

(function(root, vttjs) {

  var scrollSetting = {
    "": true,
    "up": true
  };

  function findScrollSetting(value) {
    if (typeof value !== "string") {
      return false;
    }
    var scroll = scrollSetting[value.toLowerCase()];
    return scroll ? value.toLowerCase() : false;
  }

  function isValidPercentValue(value) {
    return typeof value === "number" && (value >= 0 && value <= 100);
  }

  // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface
  function VTTRegion() {
    var _width = 100;
    var _lines = 3;
    var _regionAnchorX = 0;
    var _regionAnchorY = 100;
    var _viewportAnchorX = 0;
    var _viewportAnchorY = 100;
    var _scroll = "";

    Object.defineProperties(this, {
      "width": {
        enumerable: true,
        get: function() {
          return _width;
        },
        set: function(value) {
          if (!isValidPercentValue(value)) {
            throw new Error("Width must be between 0 and 100.");
          }
          _width = value;
        }
      },
      "lines": {
        enumerable: true,
        get: function() {
          return _lines;
        },
        set: function(value) {
          if (typeof value !== "number") {
            throw new TypeError("Lines must be set to a number.");
          }
          _lines = value;
        }
      },
      "regionAnchorY": {
        enumerable: true,
        get: function() {
          return _regionAnchorY;
        },
        set: function(value) {
          if (!isValidPercentValue(value)) {
            throw new Error("RegionAnchorX must be between 0 and 100.");
          }
          _regionAnchorY = value;
        }
      },
      "regionAnchorX": {
        enumerable: true,
        get: function() {
          return _regionAnchorX;
        },
        set: function(value) {
          if(!isValidPercentValue(value)) {
            throw new Error("RegionAnchorY must be between 0 and 100.");
          }
          _regionAnchorX = value;
        }
      },
      "viewportAnchorY": {
        enumerable: true,
        get: function() {
          return _viewportAnchorY;
        },
        set: function(value) {
          if (!isValidPercentValue(value)) {
            throw new Error("ViewportAnchorY must be between 0 and 100.");
          }
          _viewportAnchorY = value;
        }
      },
      "viewportAnchorX": {
        enumerable: true,
        get: function() {
          return _viewportAnchorX;
        },
        set: function(value) {
          if (!isValidPercentValue(value)) {
            throw new Error("ViewportAnchorX must be between 0 and 100.");
          }
          _viewportAnchorX = value;
        }
      },
      "scroll": {
        enumerable: true,
        get: function() {
          return _scroll;
        },
        set: function(value) {
          var setting = findScrollSetting(value);
          // Have to check for false as an empty string is a legal value.
          if (setting === false) {
            throw new SyntaxError("An invalid or illegal string was specified.");
          }
          _scroll = setting;
        }
      }
    });
  }

  root.VTTRegion = root.VTTRegion || VTTRegion;
  vttjs.VTTRegion = VTTRegion;
}(this, (this.vttjs || {})));

/**
 * Copyright 2013 vtt.js Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

(function(global) {

  var _objCreate = Object.create || (function() {
    function F() {}
    return function(o) {
      if (arguments.length !== 1) {
        throw new Error('Object.create shim only accepts one parameter.');
      }
      F.prototype = o;
      return new F();
    };
  })();

  // Creates a new ParserError object from an errorData object. The errorData
  // object should have default code and message properties. The default message
  // property can be overriden by passing in a message parameter.
  // See ParsingError.Errors below for acceptable errors.
  function ParsingError(errorData, message) {
    this.name = "ParsingError";
    this.code = errorData.code;
    this.message = message || errorData.message;
  }
  ParsingError.prototype = _objCreate(Error.prototype);
  ParsingError.prototype.constructor = ParsingError;

  // ParsingError metadata for acceptable ParsingErrors.
  ParsingError.Errors = {
    BadSignature: {
      code: 0,
      message: "Malformed WebVTT signature."
    },
    BadTimeStamp: {
      code: 1,
      message: "Malformed time stamp."
    }
  };

  // Try to parse input as a time stamp.
  function parseTimeStamp(input) {

    function computeSeconds(h, m, s, f) {
      return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000;
    }

    var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);
    if (!m) {
      return null;
    }

    if (m[3]) {
      // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds]
      return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]);
    } else if (m[1] > 59) {
      // Timestamp takes the form of [hours]:[minutes].[milliseconds]
      // First position is hours as it's over 59.
      return computeSeconds(m[1], m[2], 0,  m[4]);
    } else {
      // Timestamp takes the form of [minutes]:[seconds].[milliseconds]
      return computeSeconds(0, m[1], m[2], m[4]);
    }
  }

  // A settings object holds key/value pairs and will ignore anything but the first
  // assignment to a specific key.
  function Settings() {
    this.values = _objCreate(null);
  }

  Settings.prototype = {
    // Only accept the first assignment to any key.
    set: function(k, v) {
      if (!this.get(k) && v !== "") {
        this.values[k] = v;
      }
    },
    // Return the value for a key, or a default value.
    // If 'defaultKey' is passed then 'dflt' is assumed to be an object with
    // a number of possible default values as properties where 'defaultKey' is
    // the key of the property that will be chosen; otherwise it's assumed to be
    // a single value.
    get: function(k, dflt, defaultKey) {
      if (defaultKey) {
        return this.has(k) ? this.values[k] : dflt[defaultKey];
      }
      return this.has(k) ? this.values[k] : dflt;
    },
    // Check whether we have a value for a key.
    has: function(k) {
      return k in this.values;
    },
    // Accept a setting if its one of the given alternatives.
    alt: function(k, v, a) {
      for (var n = 0; n < a.length; ++n) {
        if (v === a[n]) {
          this.set(k, v);
          break;
        }
      }
    },
    // Accept a setting if its a valid (signed) integer.
    integer: function(k, v) {
      if (/^-?\d+$/.test(v)) { // integer
        this.set(k, parseInt(v, 10));
      }
    },
    // Accept a setting if its a valid percentage.
    percent: function(k, v) {
      var m;
      if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) {
        v = parseFloat(v);
        if (v >= 0 && v <= 100) {
          this.set(k, v);
          return true;
        }
      }
      return false;
    }
  };

  // Helper function to parse input into groups separated by 'groupDelim', and
  // interprete each group as a key/value pair separated by 'keyValueDelim'.
  function parseOptions(input, callback, keyValueDelim, groupDelim) {
    var groups = groupDelim ? input.split(groupDelim) : [input];
    for (var i in groups) {
      if (typeof groups[i] !== "string") {
        continue;
      }
      var kv = groups[i].split(keyValueDelim);
      if (kv.length !== 2) {
        continue;
      }
      var k = kv[0];
      var v = kv[1];
      callback(k, v);
    }
  }

  function parseCue(input, cue, regionList) {
    // Remember the original input if we need to throw an error.
    var oInput = input;
    // 4.1 WebVTT timestamp
    function consumeTimeStamp() {
      var ts = parseTimeStamp(input);
      if (ts === null) {
        throw new ParsingError(ParsingError.Errors.BadTimeStamp,
                              "Malformed timestamp: " + oInput);
      }
      // Remove time stamp from input.
      input = input.replace(/^[^\sa-zA-Z-]+/, "");
      return ts;
    }

    // 4.4.2 WebVTT cue settings
    function consumeCueSettings(input, cue) {
      var settings = new Settings();

      parseOptions(input, function (k, v) {
        switch (k) {
        case "region":
          // Find the last region we parsed with the same region id.
          for (var i = regionList.length - 1; i >= 0; i--) {
            if (regionList[i].id === v) {
              settings.set(k, regionList[i].region);
              break;
            }
          }
          break;
        case "vertical":
          settings.alt(k, v, ["rl", "lr"]);
          break;
        case "line":
          var vals = v.split(","),
              vals0 = vals[0];
          settings.integer(k, vals0);
          settings.percent(k, vals0) ? settings.set("snapToLines", false) : null;
          settings.alt(k, vals0, ["auto"]);
          if (vals.length === 2) {
            settings.alt("lineAlign", vals[1], ["start", "middle", "end"]);
          }
          break;
        case "position":
          vals = v.split(",");
          settings.percent(k, vals[0]);
          if (vals.length === 2) {
            settings.alt("positionAlign", vals[1], ["start", "middle", "end"]);
          }
          break;
        case "size":
          settings.percent(k, v);
          break;
        case "align":
          settings.alt(k, v, ["start", "middle", "end", "left", "right"]);
          break;
        }
      }, /:/, /\s/);

      // Apply default values for any missing fields.
      cue.region = settings.get("region", null);
      cue.vertical = settings.get("vertical", "");
      cue.line = settings.get("line", "auto");
      cue.lineAlign = settings.get("lineAlign", "start");
      cue.snapToLines = settings.get("snapToLines", true);
      cue.size = settings.get("size", 100);
      cue.align = settings.get("align", "middle");
      cue.position = settings.get("position", {
        start: 0,
        left: 0,
        middle: 50,
        end: 100,
        right: 100
      }, cue.align);
      cue.positionAlign = settings.get("positionAlign", {
        start: "start",
        left: "start",
        middle: "middle",
        end: "end",
        right: "end"
      }, cue.align);
    }

    function skipWhitespace() {
      input = input.replace(/^\s+/, "");
    }

    // 4.1 WebVTT cue timings.
    skipWhitespace();
    cue.startTime = consumeTimeStamp();   // (1) collect cue start time
    skipWhitespace();
    if (input.substr(0, 3) !== "-->") {     // (3) next characters must match "-->"
      throw new ParsingError(ParsingError.Errors.BadTimeStamp,
                             "Malformed time stamp (time stamps must be separated by '-->'): " +
                             oInput);
    }
    input = input.substr(3);
    skipWhitespace();
    cue.endTime = consumeTimeStamp();     // (5) collect cue end time

    // 4.1 WebVTT cue settings list.
    skipWhitespace();
    consumeCueSettings(input, cue);
  }

  var ESCAPE = {
    "&amp;": "&",
    "&lt;": "<",
    "&gt;": ">",
    "&lrm;": "\u200e",
    "&rlm;": "\u200f",
    "&nbsp;": "\u00a0"
  };

  var TAG_NAME = {
    c: "span",
    i: "i",
    b: "b",
    u: "u",
    ruby: "ruby",
    rt: "rt",
    v: "span",
    lang: "span"
  };

  var TAG_ANNOTATION = {
    v: "title",
    lang: "lang"
  };

  var NEEDS_PARENT = {
    rt: "ruby"
  };

  // Parse content into a document fragment.
  function parseContent(window, input) {
    function nextToken() {
      // Check for end-of-string.
      if (!input) {
        return null;
      }

      // Consume 'n' characters from the input.
      function consume(result) {
        input = input.substr(result.length);
        return result;
      }

      var m = input.match(/^([^<]*)(<[^>]+>?)?/);
      // If there is some text before the next tag, return it, otherwise return
      // the tag.
      return consume(m[1] ? m[1] : m[2]);
    }

    // Unescape a string 's'.
    function unescape1(e) {
      return ESCAPE[e];
    }
    function unescape(s) {
      while ((m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/))) {
        s = s.replace(m[0], unescape1);
      }
      return s;
    }

    function shouldAdd(current, element) {
      return !NEEDS_PARENT[element.localName] ||
             NEEDS_PARENT[element.localName] === current.localName;
    }

    // Create an element for this tag.
    function createElement(type, annotation) {
      var tagName = TAG_NAME[type];
      if (!tagName) {
        return null;
      }
      var element = window.document.createElement(tagName);
      element.localName = tagName;
      var name = TAG_ANNOTATION[type];
      if (name && annotation) {
        element[name] = annotation.trim();
      }
      return element;
    }

    var rootDiv = window.document.createElement("div"),
        current = rootDiv,
        t,
        tagStack = [];

    while ((t = nextToken()) !== null) {
      if (t[0] === '<') {
        if (t[1] === "/") {
          // If the closing tag matches, move back up to the parent node.
          if (tagStack.length &&
              tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) {
            tagStack.pop();
            current = current.parentNode;
          }
          // Otherwise just ignore the end tag.
          continue;
        }
        var ts = parseTimeStamp(t.substr(1, t.length - 2));
        var node;
        if (ts) {
          // Timestamps are lead nodes as well.
          node = window.document.createProcessingInstruction("timestamp", ts);
          current.appendChild(node);
          continue;
        }
        var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);
        // If we can't parse the tag, skip to the next tag.
        if (!m) {
          continue;
        }
        // Try to construct an element, and ignore the tag if we couldn't.
        node = createElement(m[1], m[3]);
        if (!node) {
          continue;
        }
        // Determine if the tag should be added based on the context of where it
        // is placed in the cuetext.
        if (!shouldAdd(current, node)) {
          continue;
        }
        // Set the class list (as a list of classes, separated by space).
        if (m[2]) {
          node.className = m[2].substr(1).replace('.', ' ');
        }
        // Append the node to the current node, and enter the scope of the new
        // node.
        tagStack.push(m[1]);
        current.appendChild(node);
        current = node;
        continue;
      }

      // Text nodes are leaf nodes.
      current.appendChild(window.document.createTextNode(unescape(t)));
    }

    return rootDiv;
  }

  // This is a list of all the Unicode characters that have a strong
  // right-to-left category. What this means is that these characters are
  // written right-to-left for sure. It was generated by pulling all the strong
  // right-to-left characters out of the Unicode data table. That table can
  // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
  var strongRTLChars = [0x05BE, 0x05C0, 0x05C3, 0x05C6, 0x05D0, 0x05D1,
      0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA,
      0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3,
      0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x05F0, 0x05F1,
      0x05F2, 0x05F3, 0x05F4, 0x0608, 0x060B, 0x060D, 0x061B, 0x061E, 0x061F,
      0x0620, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628,
      0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631,
      0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A,
      0x063B, 0x063C, 0x063D, 0x063E, 0x063F, 0x0640, 0x0641, 0x0642, 0x0643,
      0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x066D, 0x066E,
      0x066F, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675, 0x0676, 0x0677, 0x0678,
      0x0679, 0x067A, 0x067B, 0x067C, 0x067D, 0x067E, 0x067F, 0x0680, 0x0681,
      0x0682, 0x0683, 0x0684, 0x0685, 0x0686, 0x0687, 0x0688, 0x0689, 0x068A,
      0x068B, 0x068C, 0x068D, 0x068E, 0x068F, 0x0690, 0x0691, 0x0692, 0x0693,
      0x0694, 0x0695, 0x0696, 0x0697, 0x0698, 0x0699, 0x069A, 0x069B, 0x069C,
      0x069D, 0x069E, 0x069F, 0x06A0, 0x06A1, 0x06A2, 0x06A3, 0x06A4, 0x06A5,
      0x06A6, 0x06A7, 0x06A8, 0x06A9, 0x06AA, 0x06AB, 0x06AC, 0x06AD, 0x06AE,
      0x06AF, 0x06B0, 0x06B1, 0x06B2, 0x06B3, 0x06B4, 0x06B5, 0x06B6, 0x06B7,
      0x06B8, 0x06B9, 0x06BA, 0x06BB, 0x06BC, 0x06BD, 0x06BE, 0x06BF, 0x06C0,
      0x06C1, 0x06C2, 0x06C3, 0x06C4, 0x06C5, 0x06C6, 0x06C7, 0x06C8, 0x06C9,
      0x06CA, 0x06CB, 0x06CC, 0x06CD, 0x06CE, 0x06CF, 0x06D0, 0x06D1, 0x06D2,
      0x06D3, 0x06D4, 0x06D5, 0x06E5, 0x06E6, 0x06EE, 0x06EF, 0x06FA, 0x06FB,
      0x06FC, 0x06FD, 0x06FE, 0x06FF, 0x0700, 0x0701, 0x0702, 0x0703, 0x0704,
      0x0705, 0x0706, 0x0707, 0x0708, 0x0709, 0x070A, 0x070B, 0x070C, 0x070D,
      0x070F, 0x0710, 0x0712, 0x0713, 0x0714, 0x0715, 0x0716, 0x0717, 0x0718,
      0x0719, 0x071A, 0x071B, 0x071C, 0x071D, 0x071E, 0x071F, 0x0720, 0x0721,
      0x0722, 0x0723, 0x0724, 0x0725, 0x0726, 0x0727, 0x0728, 0x0729, 0x072A,
      0x072B, 0x072C, 0x072D, 0x072E, 0x072F, 0x074D, 0x074E, 0x074F, 0x0750,
      0x0751, 0x0752, 0x0753, 0x0754, 0x0755, 0x0756, 0x0757, 0x0758, 0x0759,
      0x075A, 0x075B, 0x075C, 0x075D, 0x075E, 0x075F, 0x0760, 0x0761, 0x0762,
      0x0763, 0x0764, 0x0765, 0x0766, 0x0767, 0x0768, 0x0769, 0x076A, 0x076B,
      0x076C, 0x076D, 0x076E, 0x076F, 0x0770, 0x0771, 0x0772, 0x0773, 0x0774,
      0x0775, 0x0776, 0x0777, 0x0778, 0x0779, 0x077A, 0x077B, 0x077C, 0x077D,
      0x077E, 0x077F, 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0786,
      0x0787, 0x0788, 0x0789, 0x078A, 0x078B, 0x078C, 0x078D, 0x078E, 0x078F,
      0x0790, 0x0791, 0x0792, 0x0793, 0x0794, 0x0795, 0x0796, 0x0797, 0x0798,
      0x0799, 0x079A, 0x079B, 0x079C, 0x079D, 0x079E, 0x079F, 0x07A0, 0x07A1,
      0x07A2, 0x07A3, 0x07A4, 0x07A5, 0x07B1, 0x07C0, 0x07C1, 0x07C2, 0x07C3,
      0x07C4, 0x07C5, 0x07C6, 0x07C7, 0x07C8, 0x07C9, 0x07CA, 0x07CB, 0x07CC,
      0x07CD, 0x07CE, 0x07CF, 0x07D0, 0x07D1, 0x07D2, 0x07D3, 0x07D4, 0x07D5,
      0x07D6, 0x07D7, 0x07D8, 0x07D9, 0x07DA, 0x07DB, 0x07DC, 0x07DD, 0x07DE,
      0x07DF, 0x07E0, 0x07E1, 0x07E2, 0x07E3, 0x07E4, 0x07E5, 0x07E6, 0x07E7,
      0x07E8, 0x07E9, 0x07EA, 0x07F4, 0x07F5, 0x07FA, 0x0800, 0x0801, 0x0802,
      0x0803, 0x0804, 0x0805, 0x0806, 0x0807, 0x0808, 0x0809, 0x080A, 0x080B,
      0x080C, 0x080D, 0x080E, 0x080F, 0x0810, 0x0811, 0x0812, 0x0813, 0x0814,
      0x0815, 0x081A, 0x0824, 0x0828, 0x0830, 0x0831, 0x0832, 0x0833, 0x0834,
      0x0835, 0x0836, 0x0837, 0x0838, 0x0839, 0x083A, 0x083B, 0x083C, 0x083D,
      0x083E, 0x0840, 0x0841, 0x0842, 0x0843, 0x0844, 0x0845, 0x0846, 0x0847,
      0x0848, 0x0849, 0x084A, 0x084B, 0x084C, 0x084D, 0x084E, 0x084F, 0x0850,
      0x0851, 0x0852, 0x0853, 0x0854, 0x0855, 0x0856, 0x0857, 0x0858, 0x085E,
      0x08A0, 0x08A2, 0x08A3, 0x08A4, 0x08A5, 0x08A6, 0x08A7, 0x08A8, 0x08A9,
      0x08AA, 0x08AB, 0x08AC, 0x200F, 0xFB1D, 0xFB1F, 0xFB20, 0xFB21, 0xFB22,
      0xFB23, 0xFB24, 0xFB25, 0xFB26, 0xFB27, 0xFB28, 0xFB2A, 0xFB2B, 0xFB2C,
      0xFB2D, 0xFB2E, 0xFB2F, 0xFB30, 0xFB31, 0xFB32, 0xFB33, 0xFB34, 0xFB35,
      0xFB36, 0xFB38, 0xFB39, 0xFB3A, 0xFB3B, 0xFB3C, 0xFB3E, 0xFB40, 0xFB41,
      0xFB43, 0xFB44, 0xFB46, 0xFB47, 0xFB48, 0xFB49, 0xFB4A, 0xFB4B, 0xFB4C,
      0xFB4D, 0xFB4E, 0xFB4F, 0xFB50, 0xFB51, 0xFB52, 0xFB53, 0xFB54, 0xFB55,
      0xFB56, 0xFB57, 0xFB58, 0xFB59, 0xFB5A, 0xFB5B, 0xFB5C, 0xFB5D, 0xFB5E,
      0xFB5F, 0xFB60, 0xFB61, 0xFB62, 0xFB63, 0xFB64, 0xFB65, 0xFB66, 0xFB67,
      0xFB68, 0xFB69, 0xFB6A, 0xFB6B, 0xFB6C, 0xFB6D, 0xFB6E, 0xFB6F, 0xFB70,
      0xFB71, 0xFB72, 0xFB73, 0xFB74, 0xFB75, 0xFB76, 0xFB77, 0xFB78, 0xFB79,
      0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D, 0xFB7E, 0xFB7F, 0xFB80, 0xFB81, 0xFB82,
      0xFB83, 0xFB84, 0xFB85, 0xFB86, 0xFB87, 0xFB88, 0xFB89, 0xFB8A, 0xFB8B,
      0xFB8C, 0xFB8D, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91, 0xFB92, 0xFB93, 0xFB94,
      0xFB95, 0xFB96, 0xFB97, 0xFB98, 0xFB99, 0xFB9A, 0xFB9B, 0xFB9C, 0xFB9D,
      0xFB9E, 0xFB9F, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3, 0xFBA4, 0xFBA5, 0xFBA6,
      0xFBA7, 0xFBA8, 0xFBA9, 0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD, 0xFBAE, 0xFBAF,
      0xFBB0, 0xFBB1, 0xFBB2, 0xFBB3, 0xFBB4, 0xFBB5, 0xFBB6, 0xFBB7, 0xFBB8,
      0xFBB9, 0xFBBA, 0xFBBB, 0xFBBC, 0xFBBD, 0xFBBE, 0xFBBF, 0xFBC0, 0xFBC1,
      0xFBD3, 0xFBD4, 0xFBD5, 0xFBD6, 0xFBD7, 0xFBD8, 0xFBD9, 0xFBDA, 0xFBDB,
      0xFBDC, 0xFBDD, 0xFBDE, 0xFBDF, 0xFBE0, 0xFBE1, 0xFBE2, 0xFBE3, 0xFBE4,
      0xFBE5, 0xFBE6, 0xFBE7, 0xFBE8, 0xFBE9, 0xFBEA, 0xFBEB, 0xFBEC, 0xFBED,
      0xFBEE, 0xFBEF, 0xFBF0, 0xFBF1, 0xFBF2, 0xFBF3, 0xFBF4, 0xFBF5, 0xFBF6,
      0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF,
      0xFC00, 0xFC01, 0xFC02, 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFC08,
      0xFC09, 0xFC0A, 0xFC0B, 0xFC0C, 0xFC0D, 0xFC0E, 0xFC0F, 0xFC10, 0xFC11,
      0xFC12, 0xFC13, 0xFC14, 0xFC15, 0xFC16, 0xFC17, 0xFC18, 0xFC19, 0xFC1A,
      0xFC1B, 0xFC1C, 0xFC1D, 0xFC1E, 0xFC1F, 0xFC20, 0xFC21, 0xFC22, 0xFC23,
      0xFC24, 0xFC25, 0xFC26, 0xFC27, 0xFC28, 0xFC29, 0xFC2A, 0xFC2B, 0xFC2C,
      0xFC2D, 0xFC2E, 0xFC2F, 0xFC30, 0xFC31, 0xFC32, 0xFC33, 0xFC34, 0xFC35,
      0xFC36, 0xFC37, 0xFC38, 0xFC39, 0xFC3A, 0xFC3B, 0xFC3C, 0xFC3D, 0xFC3E,
      0xFC3F, 0xFC40, 0xFC41, 0xFC42, 0xFC43, 0xFC44, 0xFC45, 0xFC46, 0xFC47,
      0xFC48, 0xFC49, 0xFC4A, 0xFC4B, 0xFC4C, 0xFC4D, 0xFC4E, 0xFC4F, 0xFC50,
      0xFC51, 0xFC52, 0xFC53, 0xFC54, 0xFC55, 0xFC56, 0xFC57, 0xFC58, 0xFC59,
      0xFC5A, 0xFC5B, 0xFC5C, 0xFC5D, 0xFC5E, 0xFC5F, 0xFC60, 0xFC61, 0xFC62,
      0xFC63, 0xFC64, 0xFC65, 0xFC66, 0xFC67, 0xFC68, 0xFC69, 0xFC6A, 0xFC6B,
      0xFC6C, 0xFC6D, 0xFC6E, 0xFC6F, 0xFC70, 0xFC71, 0xFC72, 0xFC73, 0xFC74,
      0xFC75, 0xFC76, 0xFC77, 0xFC78, 0xFC79, 0xFC7A, 0xFC7B, 0xFC7C, 0xFC7D,
      0xFC7E, 0xFC7F, 0xFC80, 0xFC81, 0xFC82, 0xFC83, 0xFC84, 0xFC85, 0xFC86,
      0xFC87, 0xFC88, 0xFC89, 0xFC8A, 0xFC8B, 0xFC8C, 0xFC8D, 0xFC8E, 0xFC8F,
      0xFC90, 0xFC91, 0xFC92, 0xFC93, 0xFC94, 0xFC95, 0xFC96, 0xFC97, 0xFC98,
      0xFC99, 0xFC9A, 0xFC9B, 0xFC9C, 0xFC9D, 0xFC9E, 0xFC9F, 0xFCA0, 0xFCA1,
      0xFCA2, 0xFCA3, 0xFCA4, 0xFCA5, 0xFCA6, 0xFCA7, 0xFCA8, 0xFCA9, 0xFCAA,
      0xFCAB, 0xFCAC, 0xFCAD, 0xFCAE, 0xFCAF, 0xFCB0, 0xFCB1, 0xFCB2, 0xFCB3,
      0xFCB4, 0xFCB5, 0xFCB6, 0xFCB7, 0xFCB8, 0xFCB9, 0xFCBA, 0xFCBB, 0xFCBC,
      0xFCBD, 0xFCBE, 0xFCBF, 0xFCC0, 0xFCC1, 0xFCC2, 0xFCC3, 0xFCC4, 0xFCC5,
      0xFCC6, 0xFCC7, 0xFCC8, 0xFCC9, 0xFCCA, 0xFCCB, 0xFCCC, 0xFCCD, 0xFCCE,
      0xFCCF, 0xFCD0, 0xFCD1, 0xFCD2, 0xFCD3, 0xFCD4, 0xFCD5, 0xFCD6, 0xFCD7,
      0xFCD8, 0xFCD9, 0xFCDA, 0xFCDB, 0xFCDC, 0xFCDD, 0xFCDE, 0xFCDF, 0xFCE0,
      0xFCE1, 0xFCE2, 0xFCE3, 0xFCE4, 0xFCE5, 0xFCE6, 0xFCE7, 0xFCE8, 0xFCE9,
      0xFCEA, 0xFCEB, 0xFCEC, 0xFCED, 0xFCEE, 0xFCEF, 0xFCF0, 0xFCF1, 0xFCF2,
      0xFCF3, 0xFCF4, 0xFCF5, 0xFCF6, 0xFCF7, 0xFCF8, 0xFCF9, 0xFCFA, 0xFCFB,
      0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, 0xFD00, 0xFD01, 0xFD02, 0xFD03, 0xFD04,
      0xFD05, 0xFD06, 0xFD07, 0xFD08, 0xFD09, 0xFD0A, 0xFD0B, 0xFD0C, 0xFD0D,
      0xFD0E, 0xFD0F, 0xFD10, 0xFD11, 0xFD12, 0xFD13, 0xFD14, 0xFD15, 0xFD16,
      0xFD17, 0xFD18, 0xFD19, 0xFD1A, 0xFD1B, 0xFD1C, 0xFD1D, 0xFD1E, 0xFD1F,
      0xFD20, 0xFD21, 0xFD22, 0xFD23, 0xFD24, 0xFD25, 0xFD26, 0xFD27, 0xFD28,
      0xFD29, 0xFD2A, 0xFD2B, 0xFD2C, 0xFD2D, 0xFD2E, 0xFD2F, 0xFD30, 0xFD31,
      0xFD32, 0xFD33, 0xFD34, 0xFD35, 0xFD36, 0xFD37, 0xFD38, 0xFD39, 0xFD3A,
      0xFD3B, 0xFD3C, 0xFD3D, 0xFD50, 0xFD51, 0xFD52, 0xFD53, 0xFD54, 0xFD55,
      0xFD56, 0xFD57, 0xFD58, 0xFD59, 0xFD5A, 0xFD5B, 0xFD5C, 0xFD5D, 0xFD5E,
      0xFD5F, 0xFD60, 0xFD61, 0xFD62, 0xFD63, 0xFD64, 0xFD65, 0xFD66, 0xFD67,
      0xFD68, 0xFD69, 0xFD6A, 0xFD6B, 0xFD6C, 0xFD6D, 0xFD6E, 0xFD6F, 0xFD70,
      0xFD71, 0xFD72, 0xFD73, 0xFD74, 0xFD75, 0xFD76, 0xFD77, 0xFD78, 0xFD79,
      0xFD7A, 0xFD7B, 0xFD7C, 0xFD7D, 0xFD7E, 0xFD7F, 0xFD80, 0xFD81, 0xFD82,
      0xFD83, 0xFD84, 0xFD85, 0xFD86, 0xFD87, 0xFD88, 0xFD89, 0xFD8A, 0xFD8B,
      0xFD8C, 0xFD8D, 0xFD8E, 0xFD8F, 0xFD92, 0xFD93, 0xFD94, 0xFD95, 0xFD96,
      0xFD97, 0xFD98, 0xFD99, 0xFD9A, 0xFD9B, 0xFD9C, 0xFD9D, 0xFD9E, 0xFD9F,
      0xFDA0, 0xFDA1, 0xFDA2, 0xFDA3, 0xFDA4, 0xFDA5, 0xFDA6, 0xFDA7, 0xFDA8,
      0xFDA9, 0xFDAA, 0xFDAB, 0xFDAC, 0xFDAD, 0xFDAE, 0xFDAF, 0xFDB0, 0xFDB1,
      0xFDB2, 0xFDB3, 0xFDB4, 0xFDB5, 0xFDB6, 0xFDB7, 0xFDB8, 0xFDB9, 0xFDBA,
      0xFDBB, 0xFDBC, 0xFDBD, 0xFDBE, 0xFDBF, 0xFDC0, 0xFDC1, 0xFDC2, 0xFDC3,
      0xFDC4, 0xFDC5, 0xFDC6, 0xFDC7, 0xFDF0, 0xFDF1, 0xFDF2, 0xFDF3, 0xFDF4,
      0xFDF5, 0xFDF6, 0xFDF7, 0xFDF8, 0xFDF9, 0xFDFA, 0xFDFB, 0xFDFC, 0xFE70,
      0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE76, 0xFE77, 0xFE78, 0xFE79, 0xFE7A,
      0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F, 0xFE80, 0xFE81, 0xFE82, 0xFE83,
      0xFE84, 0xFE85, 0xFE86, 0xFE87, 0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C,
      0xFE8D, 0xFE8E, 0xFE8F, 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95,
      0xFE96, 0xFE97, 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E,
      0xFE9F, 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7,
      0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF, 0xFEB0,
      0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8, 0xFEB9,
      0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0, 0xFEC1, 0xFEC2,
      0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, 0xFEC9, 0xFECA, 0xFECB,
      0xFECC, 0xFECD, 0xFECE, 0xFECF, 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4,
      0xFED5, 0xFED6, 0xFED7, 0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD,
      0xFEDE, 0xFEDF, 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6,
      0xFEE7, 0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF,
      0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8,
      0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0x10800, 0x10801, 0x10802, 0x10803,
      0x10804, 0x10805, 0x10808, 0x1080A, 0x1080B, 0x1080C, 0x1080D, 0x1080E,
      0x1080F, 0x10810, 0x10811, 0x10812, 0x10813, 0x10814, 0x10815, 0x10816,
      0x10817, 0x10818, 0x10819, 0x1081A, 0x1081B, 0x1081C, 0x1081D, 0x1081E,
      0x1081F, 0x10820, 0x10821, 0x10822, 0x10823, 0x10824, 0x10825, 0x10826,
      0x10827, 0x10828, 0x10829, 0x1082A, 0x1082B, 0x1082C, 0x1082D, 0x1082E,
      0x1082F, 0x10830, 0x10831, 0x10832, 0x10833, 0x10834, 0x10835, 0x10837,
      0x10838, 0x1083C, 0x1083F, 0x10840, 0x10841, 0x10842, 0x10843, 0x10844,
      0x10845, 0x10846, 0x10847, 0x10848, 0x10849, 0x1084A, 0x1084B, 0x1084C,
      0x1084D, 0x1084E, 0x1084F, 0x10850, 0x10851, 0x10852, 0x10853, 0x10854,
      0x10855, 0x10857, 0x10858, 0x10859, 0x1085A, 0x1085B, 0x1085C, 0x1085D,
      0x1085E, 0x1085F, 0x10900, 0x10901, 0x10902, 0x10903, 0x10904, 0x10905,
      0x10906, 0x10907, 0x10908, 0x10909, 0x1090A, 0x1090B, 0x1090C, 0x1090D,
      0x1090E, 0x1090F, 0x10910, 0x10911, 0x10912, 0x10913, 0x10914, 0x10915,
      0x10916, 0x10917, 0x10918, 0x10919, 0x1091A, 0x1091B, 0x10920, 0x10921,
      0x10922, 0x10923, 0x10924, 0x10925, 0x10926, 0x10927, 0x10928, 0x10929,
      0x1092A, 0x1092B, 0x1092C, 0x1092D, 0x1092E, 0x1092F, 0x10930, 0x10931,
      0x10932, 0x10933, 0x10934, 0x10935, 0x10936, 0x10937, 0x10938, 0x10939,
      0x1093F, 0x10980, 0x10981, 0x10982, 0x10983, 0x10984, 0x10985, 0x10986,
      0x10987, 0x10988, 0x10989, 0x1098A, 0x1098B, 0x1098C, 0x1098D, 0x1098E,
      0x1098F, 0x10990, 0x10991, 0x10992, 0x10993, 0x10994, 0x10995, 0x10996,
      0x10997, 0x10998, 0x10999, 0x1099A, 0x1099B, 0x1099C, 0x1099D, 0x1099E,
      0x1099F, 0x109A0, 0x109A1, 0x109A2, 0x109A3, 0x109A4, 0x109A5, 0x109A6,
      0x109A7, 0x109A8, 0x109A9, 0x109AA, 0x109AB, 0x109AC, 0x109AD, 0x109AE,
      0x109AF, 0x109B0, 0x109B1, 0x109B2, 0x109B3, 0x109B4, 0x109B5, 0x109B6,
      0x109B7, 0x109BE, 0x109BF, 0x10A00, 0x10A10, 0x10A11, 0x10A12, 0x10A13,
      0x10A15, 0x10A16, 0x10A17, 0x10A19, 0x10A1A, 0x10A1B, 0x10A1C, 0x10A1D,
      0x10A1E, 0x10A1F, 0x10A20, 0x10A21, 0x10A22, 0x10A23, 0x10A24, 0x10A25,
      0x10A26, 0x10A27, 0x10A28, 0x10A29, 0x10A2A, 0x10A2B, 0x10A2C, 0x10A2D,
      0x10A2E, 0x10A2F, 0x10A30, 0x10A31, 0x10A32, 0x10A33, 0x10A40, 0x10A41,
      0x10A42, 0x10A43, 0x10A44, 0x10A45, 0x10A46, 0x10A47, 0x10A50, 0x10A51,
      0x10A52, 0x10A53, 0x10A54, 0x10A55, 0x10A56, 0x10A57, 0x10A58, 0x10A60,
      0x10A61, 0x10A62, 0x10A63, 0x10A64, 0x10A65, 0x10A66, 0x10A67, 0x10A68,
      0x10A69, 0x10A6A, 0x10A6B, 0x10A6C, 0x10A6D, 0x10A6E, 0x10A6F, 0x10A70,
      0x10A71, 0x10A72, 0x10A73, 0x10A74, 0x10A75, 0x10A76, 0x10A77, 0x10A78,
      0x10A79, 0x10A7A, 0x10A7B, 0x10A7C, 0x10A7D, 0x10A7E, 0x10A7F, 0x10B00,
      0x10B01, 0x10B02, 0x10B03, 0x10B04, 0x10B05, 0x10B06, 0x10B07, 0x10B08,
      0x10B09, 0x10B0A, 0x10B0B, 0x10B0C, 0x10B0D, 0x10B0E, 0x10B0F, 0x10B10,
      0x10B11, 0x10B12, 0x10B13, 0x10B14, 0x10B15, 0x10B16, 0x10B17, 0x10B18,
      0x10B19, 0x10B1A, 0x10B1B, 0x10B1C, 0x10B1D, 0x10B1E, 0x10B1F, 0x10B20,
      0x10B21, 0x10B22, 0x10B23, 0x10B24, 0x10B25, 0x10B26, 0x10B27, 0x10B28,
      0x10B29, 0x10B2A, 0x10B2B, 0x10B2C, 0x10B2D, 0x10B2E, 0x10B2F, 0x10B30,
      0x10B31, 0x10B32, 0x10B33, 0x10B34, 0x10B35, 0x10B40, 0x10B41, 0x10B42,
      0x10B43, 0x10B44, 0x10B45, 0x10B46, 0x10B47, 0x10B48, 0x10B49, 0x10B4A,
      0x10B4B, 0x10B4C, 0x10B4D, 0x10B4E, 0x10B4F, 0x10B50, 0x10B51, 0x10B52,
      0x10B53, 0x10B54, 0x10B55, 0x10B58, 0x10B59, 0x10B5A, 0x10B5B, 0x10B5C,
      0x10B5D, 0x10B5E, 0x10B5F, 0x10B60, 0x10B61, 0x10B62, 0x10B63, 0x10B64,
      0x10B65, 0x10B66, 0x10B67, 0x10B68, 0x10B69, 0x10B6A, 0x10B6B, 0x10B6C,
      0x10B6D, 0x10B6E, 0x10B6F, 0x10B70, 0x10B71, 0x10B72, 0x10B78, 0x10B79,
      0x10B7A, 0x10B7B, 0x10B7C, 0x10B7D, 0x10B7E, 0x10B7F, 0x10C00, 0x10C01,
      0x10C02, 0x10C03, 0x10C04, 0x10C05, 0x10C06, 0x10C07, 0x10C08, 0x10C09,
      0x10C0A, 0x10C0B, 0x10C0C, 0x10C0D, 0x10C0E, 0x10C0F, 0x10C10, 0x10C11,
      0x10C12, 0x10C13, 0x10C14, 0x10C15, 0x10C16, 0x10C17, 0x10C18, 0x10C19,
      0x10C1A, 0x10C1B, 0x10C1C, 0x10C1D, 0x10C1E, 0x10C1F, 0x10C20, 0x10C21,
      0x10C22, 0x10C23, 0x10C24, 0x10C25, 0x10C26, 0x10C27, 0x10C28, 0x10C29,
      0x10C2A, 0x10C2B, 0x10C2C, 0x10C2D, 0x10C2E, 0x10C2F, 0x10C30, 0x10C31,
      0x10C32, 0x10C33, 0x10C34, 0x10C35, 0x10C36, 0x10C37, 0x10C38, 0x10C39,
      0x10C3A, 0x10C3B, 0x10C3C, 0x10C3D, 0x10C3E, 0x10C3F, 0x10C40, 0x10C41,
      0x10C42, 0x10C43, 0x10C44, 0x10C45, 0x10C46, 0x10C47, 0x10C48, 0x1EE00,
      0x1EE01, 0x1EE02, 0x1EE03, 0x1EE05, 0x1EE06, 0x1EE07, 0x1EE08, 0x1EE09,
      0x1EE0A, 0x1EE0B, 0x1EE0C, 0x1EE0D, 0x1EE0E, 0x1EE0F, 0x1EE10, 0x1EE11,
      0x1EE12, 0x1EE13, 0x1EE14, 0x1EE15, 0x1EE16, 0x1EE17, 0x1EE18, 0x1EE19,
      0x1EE1A, 0x1EE1B, 0x1EE1C, 0x1EE1D, 0x1EE1E, 0x1EE1F, 0x1EE21, 0x1EE22,
      0x1EE24, 0x1EE27, 0x1EE29, 0x1EE2A, 0x1EE2B, 0x1EE2C, 0x1EE2D, 0x1EE2E,
      0x1EE2F, 0x1EE30, 0x1EE31, 0x1EE32, 0x1EE34, 0x1EE35, 0x1EE36, 0x1EE37,
      0x1EE39, 0x1EE3B, 0x1EE42, 0x1EE47, 0x1EE49, 0x1EE4B, 0x1EE4D, 0x1EE4E,
      0x1EE4F, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE57, 0x1EE59, 0x1EE5B, 0x1EE5D,
      0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE67, 0x1EE68, 0x1EE69, 0x1EE6A,
      0x1EE6C, 0x1EE6D, 0x1EE6E, 0x1EE6F, 0x1EE70, 0x1EE71, 0x1EE72, 0x1EE74,
      0x1EE75, 0x1EE76, 0x1EE77, 0x1EE79, 0x1EE7A, 0x1EE7B, 0x1EE7C, 0x1EE7E,
      0x1EE80, 0x1EE81, 0x1EE82, 0x1EE83, 0x1EE84, 0x1EE85, 0x1EE86, 0x1EE87,
      0x1EE88, 0x1EE89, 0x1EE8B, 0x1EE8C, 0x1EE8D, 0x1EE8E, 0x1EE8F, 0x1EE90,
      0x1EE91, 0x1EE92, 0x1EE93, 0x1EE94, 0x1EE95, 0x1EE96, 0x1EE97, 0x1EE98,
      0x1EE99, 0x1EE9A, 0x1EE9B, 0x1EEA1, 0x1EEA2, 0x1EEA3, 0x1EEA5, 0x1EEA6,
      0x1EEA7, 0x1EEA8, 0x1EEA9, 0x1EEAB, 0x1EEAC, 0x1EEAD, 0x1EEAE, 0x1EEAF,
      0x1EEB0, 0x1EEB1, 0x1EEB2, 0x1EEB3, 0x1EEB4, 0x1EEB5, 0x1EEB6, 0x1EEB7,
      0x1EEB8, 0x1EEB9, 0x1EEBA, 0x1EEBB, 0x10FFFD];

  function determineBidi(cueDiv) {
    var nodeStack = [],
        text = "",
        charCode;

    if (!cueDiv || !cueDiv.childNodes) {
      return "ltr";
    }

    function pushNodes(nodeStack, node) {
      for (var i = node.childNodes.length - 1; i >= 0; i--) {
        nodeStack.push(node.childNodes[i]);
      }
    }

    function nextTextNode(nodeStack) {
      if (!nodeStack || !nodeStack.length) {
        return null;
      }

      var node = nodeStack.pop(),
          text = node.textContent || node.innerText;
      if (text) {
        // TODO: This should match all unicode type B characters (paragraph
        // separator characters). See issue #115.
        var m = text.match(/^.*(\n|\r)/);
        if (m) {
          nodeStack.length = 0;
          return m[0];
        }
        return text;
      }
      if (node.tagName === "ruby") {
        return nextTextNode(nodeStack);
      }
      if (node.childNodes) {
        pushNodes(nodeStack, node);
        return nextTextNode(nodeStack);
      }
    }

    pushNodes(nodeStack, cueDiv);
    while ((text = nextTextNode(nodeStack))) {
      for (var i = 0; i < text.length; i++) {
        charCode = text.charCodeAt(i);
        for (var j = 0; j < strongRTLChars.length; j++) {
          if (strongRTLChars[j] === charCode) {
            return "rtl";
          }
        }
      }
    }
    return "ltr";
  }

  function computeLinePos(cue) {
    if (typeof cue.line === "number" &&
        (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) {
      return cue.line;
    }
    if (!cue.track || !cue.track.textTrackList ||
        !cue.track.textTrackList.mediaElement) {
      return -1;
    }
    var track = cue.track,
        trackList = track.textTrackList,
        count = 0;
    for (var i = 0; i < trackList.length && trackList[i] !== track; i++) {
      if (trackList[i].mode === "showing") {
        count++;
      }
    }
    return ++count * -1;
  }

  function StyleBox() {
  }

  // Apply styles to a div. If there is no div passed then it defaults to the
  // div on 'this'.
  StyleBox.prototype.applyStyles = function(styles, div) {
    div = div || this.div;
    for (var prop in styles) {
      if (styles.hasOwnProperty(prop)) {
        div.style[prop] = styles[prop];
      }
    }
  };

  StyleBox.prototype.formatStyle = function(val, unit) {
    return val === 0 ? 0 : val + unit;
  };

  // Constructs the computed display state of the cue (a div). Places the div
  // into the overlay which should be a block level element (usually a div).
  function CueStyleBox(window, cue, styleOptions) {
    var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
    var color = "rgba(255, 255, 255, 1)";
    var backgroundColor = "rgba(0, 0, 0, 0.8)";

    if (isIE8) {
      color = "rgb(255, 255, 255)";
      backgroundColor = "rgb(0, 0, 0)";
    }

    StyleBox.call(this);
    this.cue = cue;

    // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will
    // have inline positioning and will function as the cue background box.
    this.cueDiv = parseContent(window, cue.text);
    var styles = {
      color: color,
      backgroundColor: backgroundColor,
      position: "relative",
      left: 0,
      right: 0,
      top: 0,
      bottom: 0,
      display: "inline"
    };

    if (!isIE8) {
      styles.writingMode = cue.vertical === "" ? "horizontal-tb"
                                               : cue.vertical === "lr" ? "vertical-lr"
                                                                       : "vertical-rl";
      styles.unicodeBidi = "plaintext";
    }
    this.applyStyles(styles, this.cueDiv);

    // Create an absolutely positioned div that will be used to position the cue
    // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS
    // mirrors of them except "middle" which is "center" in CSS.
    this.div = window.document.createElement("div");
    styles = {
      textAlign: cue.align === "middle" ? "center" : cue.align,
      font: styleOptions.font,
      whiteSpace: "pre-line",
      position: "absolute"
    };

    if (!isIE8) {
      styles.direction = determineBidi(this.cueDiv);
      styles.writingMode = cue.vertical === "" ? "horizontal-tb"
                                               : cue.vertical === "lr" ? "vertical-lr"
                                                                       : "vertical-rl".
      stylesunicodeBidi =  "plaintext";
    }

    this.applyStyles(styles);

    this.div.appendChild(this.cueDiv);

    // Calculate the distance from the reference edge of the viewport to the text
    // position of the cue box. The reference edge will be resolved later when
    // the box orientation styles are applied.
    var textPos = 0;
    switch (cue.positionAlign) {
    case "start":
      textPos = cue.position;
      break;
    case "middle":
      textPos = cue.position - (cue.size / 2);
      break;
    case "end":
      textPos = cue.position - cue.size;
      break;
    }

    // Horizontal box orientation; textPos is the distance from the left edge of the
    // area to the left edge of the box and cue.size is the distance extending to
    // the right from there.
    if (cue.vertical === "") {
      this.applyStyles({
        left:  this.formatStyle(textPos, "%"),
        width: this.formatStyle(cue.size, "%")
      });
    // Vertical box orientation; textPos is the distance from the top edge of the
    // area to the top edge of the box and cue.size is the height extending
    // downwards from there.
    } else {
      this.applyStyles({
        top: this.formatStyle(textPos, "%"),
        height: this.formatStyle(cue.size, "%")
      });
    }

    this.move = function(box) {
      this.applyStyles({
        top: this.formatStyle(box.top, "px"),
        bottom: this.formatStyle(box.bottom, "px"),
        left: this.formatStyle(box.left, "px"),
        right: this.formatStyle(box.right, "px"),
        height: this.formatStyle(box.height, "px"),
        width: this.formatStyle(box.width, "px")
      });
    };
  }
  CueStyleBox.prototype = _objCreate(StyleBox.prototype);
  CueStyleBox.prototype.constructor = CueStyleBox;

  // Represents the co-ordinates of an Element in a way that we can easily
  // compute things with such as if it overlaps or intersects with another Element.
  // Can initialize it with either a StyleBox or another BoxPosition.
  function BoxPosition(obj) {
    var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);

    // Either a BoxPosition was passed in and we need to copy it, or a StyleBox
    // was passed in and we need to copy the results of 'getBoundingClientRect'
    // as the object returned is readonly. All co-ordinate values are in reference
    // to the viewport origin (top left).
    var lh, height, width, top;
    if (obj.div) {
      height = obj.div.offsetHeight;
      width = obj.div.offsetWidth;
      top = obj.div.offsetTop;

      var rects = (rects = obj.div.childNodes) && (rects = rects[0]) &&
                  rects.getClientRects && rects.getClientRects();
      obj = obj.div.getBoundingClientRect();
      // In certain cases the outter div will be slightly larger then the sum of
      // the inner div's lines. This could be due to bold text, etc, on some platforms.
      // In this case we should get the average line height and use that. This will
      // result in the desired behaviour.
      lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length)
                 : 0;

    }
    this.left = obj.left;
    this.right = obj.right;
    this.top = obj.top || top;
    this.height = obj.height || height;
    this.bottom = obj.bottom || (top + (obj.height || height));
    this.width = obj.width || width;
    this.lineHeight = lh !== undefined ? lh : obj.lineHeight;

    if (isIE8 && !this.lineHeight) {
      this.lineHeight = 13;
    }
  }

  // Move the box along a particular axis. Optionally pass in an amount to move
  // the box. If no amount is passed then the default is the line height of the
  // box.
  BoxPosition.prototype.move = function(axis, toMove) {
    toMove = toMove !== undefined ? toMove : this.lineHeight;
    switch (axis) {
    case "+x":
      this.left += toMove;
      this.right += toMove;
      break;
    case "-x":
      this.left -= toMove;
      this.right -= toMove;
      break;
    case "+y":
      this.top += toMove;
      this.bottom += toMove;
      break;
    case "-y":
      this.top -= toMove;
      this.bottom -= toMove;
      break;
    }
  };

  // Check if this box overlaps another box, b2.
  BoxPosition.prototype.overlaps = function(b2) {
    return this.left < b2.right &&
           this.right > b2.left &&
           this.top < b2.bottom &&
           this.bottom > b2.top;
  };

  // Check if this box overlaps any other boxes in boxes.
  BoxPosition.prototype.overlapsAny = function(boxes) {
    for (var i = 0; i < boxes.length; i++) {
      if (this.overlaps(boxes[i])) {
        return true;
      }
    }
    return false;
  };

  // Check if this box is within another box.
  BoxPosition.prototype.within = function(container) {
    return this.top >= container.top &&
           this.bottom <= container.bottom &&
           this.left >= container.left &&
           this.right <= container.right;
  };

  // Check if this box is entirely within the container or it is overlapping
  // on the edge opposite of the axis direction passed. For example, if "+x" is
  // passed and the box is overlapping on the left edge of the container, then
  // return true.
  BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) {
    switch (axis) {
    case "+x":
      return this.left < container.left;
    case "-x":
      return this.right > container.right;
    case "+y":
      return this.top < container.top;
    case "-y":
      return this.bottom > container.bottom;
    }
  };

  // Find the percentage of the area that this box is overlapping with another
  // box.
  BoxPosition.prototype.intersectPercentage = function(b2) {
    var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)),
        y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)),
        intersectArea = x * y;
    return intersectArea / (this.height * this.width);
  };

  // Convert the positions from this box to CSS compatible positions using
  // the reference container's positions. This has to be done because this
  // box's positions are in reference to the viewport origin, whereas, CSS
  // values are in referecne to their respective edges.
  BoxPosition.prototype.toCSSCompatValues = function(reference) {
    return {
      top: this.top - reference.top,
      bottom: reference.bottom - this.bottom,
      left: this.left - reference.left,
      right: reference.right - this.right,
      height: this.height,
      width: this.width
    };
  };

  // Get an object that represents the box's position without anything extra.
  // Can pass a StyleBox, HTMLElement, or another BoxPositon.
  BoxPosition.getSimpleBoxPosition = function(obj) {
    var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0;
    var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0;
    var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0;

    obj = obj.div ? obj.div.getBoundingClientRect() :
                  obj.tagName ? obj.getBoundingClientRect() : obj;
    var ret = {
      left: obj.left,
      right: obj.right,
      top: obj.top || top,
      height: obj.height || height,
      bottom: obj.bottom || (top + (obj.height || height)),
      width: obj.width || width
    };
    return ret;
  };

  // Move a StyleBox to its specified, or next best, position. The containerBox
  // is the box that contains the StyleBox, such as a div. boxPositions are
  // a list of other boxes that the styleBox can't overlap with.
  function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) {

    // Find the best position for a cue box, b, on the video. The axis parameter
    // is a list of axis, the order of which, it will move the box along. For example:
    // Passing ["+x", "-x"] will move the box first along the x axis in the positive
    // direction. If it doesn't find a good position for it there it will then move
    // it along the x axis in the negative direction.
    function findBestPosition(b, axis) {
      var bestPosition,
          specifiedPosition = new BoxPosition(b),
          percentage = 1; // Highest possible so the first thing we get is better.

      for (var i = 0; i < axis.length; i++) {
        while (b.overlapsOppositeAxis(containerBox, axis[i]) ||
               (b.within(containerBox) && b.overlapsAny(boxPositions))) {
          b.move(axis[i]);
        }
        // We found a spot where we aren't overlapping anything. This is our
        // best position.
        if (b.within(containerBox)) {
          return b;
        }
        var p = b.intersectPercentage(containerBox);
        // If we're outside the container box less then we were on our last try
        // then remember this position as the best position.
        if (percentage > p) {
          bestPosition = new BoxPosition(b);
          percentage = p;
        }
        // Reset the box position to the specified position.
        b = new BoxPosition(specifiedPosition);
      }
      return bestPosition || specifiedPosition;
    }

    var boxPosition = new BoxPosition(styleBox),
        cue = styleBox.cue,
        linePos = computeLinePos(cue),
        axis = [];

    // If we have a line number to align the cue to.
    if (cue.snapToLines) {
      var size;
      switch (cue.vertical) {
      case "":
        axis = [ "+y", "-y" ];
        size = "height";
        break;
      case "rl":
        axis = [ "+x", "-x" ];
        size = "width";
        break;
      case "lr":
        axis = [ "-x", "+x" ];
        size = "width";
        break;
      }

      var step = boxPosition.lineHeight,
          position = step * Math.round(linePos),
          maxPosition = containerBox[size] + step,
          initialAxis = axis[0];

      // If the specified intial position is greater then the max position then
      // clamp the box to the amount of steps it would take for the box to
      // reach the max position.
      if (Math.abs(position) > maxPosition) {
        position = position < 0 ? -1 : 1;
        position *= Math.ceil(maxPosition / step) * step;
      }

      // If computed line position returns negative then line numbers are
      // relative to the bottom of the video instead of the top. Therefore, we
      // need to increase our initial position by the length or width of the
      // video, depending on the writing direction, and reverse our axis directions.
      if (linePos < 0) {
        position += cue.vertical === "" ? containerBox.height : containerBox.width;
        axis = axis.reverse();
      }

      // Move the box to the specified position. This may not be its best
      // position.
      boxPosition.move(initialAxis, position);

    } else {
      // If we have a percentage line value for the cue.
      var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100;

      switch (cue.lineAlign) {
      case "middle":
        linePos -= (calculatedPercentage / 2);
        break;
      case "end":
        linePos -= calculatedPercentage;
        break;
      }

      // Apply initial line position to the cue box.
      switch (cue.vertical) {
      case "":
        styleBox.applyStyles({
          top: styleBox.formatStyle(linePos, "%")
        });
        break;
      case "rl":
        styleBox.applyStyles({
          left: styleBox.formatStyle(linePos, "%")
        });
        break;
      case "lr":
        styleBox.applyStyles({
          right: styleBox.formatStyle(linePos, "%")
        });
        break;
      }

      axis = [ "+y", "-x", "+x", "-y" ];

      // Get the box position again after we've applied the specified positioning
      // to it.
      boxPosition = new BoxPosition(styleBox);
    }

    var bestPosition = findBestPosition(boxPosition, axis);
    styleBox.move(bestPosition.toCSSCompatValues(containerBox));
  }

  function WebVTT() {
    // Nothing
  }

  // Helper to allow strings to be decoded instead of the default binary utf8 data.
  WebVTT.StringDecoder = function() {
    return {
      decode: function(data) {
        if (!data) {
          return "";
        }
        if (typeof data !== "string") {
          throw new Error("Error - expected string data.");
        }
        return decodeURIComponent(encodeURIComponent(data));
      }
    };
  };

  WebVTT.convertCueToDOMTree = function(window, cuetext) {
    if (!window || !cuetext) {
      return null;
    }
    return parseContent(window, cuetext);
  };

  var FONT_SIZE_PERCENT = 0.05;
  var FONT_STYLE = "sans-serif";
  var CUE_BACKGROUND_PADDING = "1.5%";

  // Runs the processing model over the cues and regions passed to it.
  // @param overlay A block level element (usually a div) that the computed cues
  //                and regions will be placed into.
  WebVTT.processCues = function(window, cues, overlay) {
    if (!window || !cues || !overlay) {
      return null;
    }

    // Remove all previous children.
    while (overlay.firstChild) {
      overlay.removeChild(overlay.firstChild);
    }

    var paddedOverlay = window.document.createElement("div");
    paddedOverlay.style.position = "absolute";
    paddedOverlay.style.left = "0";
    paddedOverlay.style.right = "0";
    paddedOverlay.style.top = "0";
    paddedOverlay.style.bottom = "0";
    paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;
    overlay.appendChild(paddedOverlay);

    // Determine if we need to compute the display states of the cues. This could
    // be the case if a cue's state has been changed since the last computation or
    // if it has not been computed yet.
    function shouldCompute(cues) {
      for (var i = 0; i < cues.length; i++) {
        if (cues[i].hasBeenReset || !cues[i].displayState) {
          return true;
        }
      }
      return false;
    }

    // We don't need to recompute the cues' display states. Just reuse them.
    if (!shouldCompute(cues)) {
      for (var i = 0; i < cues.length; i++) {
        paddedOverlay.appendChild(cues[i].displayState);
      }
      return;
    }

    var boxPositions = [],
        containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay),
        fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;
    var styleOptions = {
      font: fontSize + "px " + FONT_STYLE
    };

    (function() {
      var styleBox, cue;

      for (var i = 0; i < cues.length; i++) {
        cue = cues[i];

        // Compute the intial position and styles of the cue div.
        styleBox = new CueStyleBox(window, cue, styleOptions);
        paddedOverlay.appendChild(styleBox.div);

        // Move the cue div to it's correct line position.
        moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);

        // Remember the computed div so that we don't have to recompute it later
        // if we don't have too.
        cue.displayState = styleBox.div;

        boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox));
      }
    })();
  };

  WebVTT.Parser = function(window, vttjs, decoder) {
    if (!decoder) {
      decoder = vttjs;
      vttjs = {};
    }
    if (!vttjs) {
      vttjs = {};
    }

    this.window = window;
    this.vttjs = vttjs;
    this.state = "INITIAL";
    this.buffer = "";
    this.decoder = decoder || new TextDecoder("utf8");
    this.regionList = [];
  };

  WebVTT.Parser.prototype = {
    // If the error is a ParsingError then report it to the consumer if
    // possible. If it's not a ParsingError then throw it like normal.
    reportOrThrowError: function(e) {
      if (e instanceof ParsingError) {
        this.onparsingerror && this.onparsingerror(e);
      } else {
        throw e;
      }
    },
    parse: function (data) {
      var self = this;

      // If there is no data then we won't decode it, but will just try to parse
      // whatever is in buffer already. This may occur in circumstances, for
      // example when flush() is called.
      if (data) {
        // Try to decode the data that we received.
        self.buffer += self.decoder.decode(data, {stream: true});
      }

      function collectNextLine() {
        var buffer = self.buffer;
        var pos = 0;
        while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') {
          ++pos;
        }
        var line = buffer.substr(0, pos);
        // Advance the buffer early in case we fail below.
        if (buffer[pos] === '\r') {
          ++pos;
        }
        if (buffer[pos] === '\n') {
          ++pos;
        }
        self.buffer = buffer.substr(pos);
        return line;
      }

      // 3.4 WebVTT region and WebVTT region settings syntax
      function parseRegion(input) {
        var settings = new Settings();

        parseOptions(input, function (k, v) {
          switch (k) {
          case "id":
            settings.set(k, v);
            break;
          case "width":
            settings.percent(k, v);
            break;
          case "lines":
            settings.integer(k, v);
            break;
          case "regionanchor":
          case "viewportanchor":
            var xy = v.split(',');
            if (xy.length !== 2) {
              break;
            }
            // We have to make sure both x and y parse, so use a temporary
            // settings object here.
            var anchor = new Settings();
            anchor.percent("x", xy[0]);
            anchor.percent("y", xy[1]);
            if (!anchor.has("x") || !anchor.has("y")) {
              break;
            }
            settings.set(k + "X", anchor.get("x"));
            settings.set(k + "Y", anchor.get("y"));
            break;
          case "scroll":
            settings.alt(k, v, ["up"]);
            break;
          }
        }, /=/, /\s/);

        // Create the region, using default values for any values that were not
        // specified.
        if (settings.has("id")) {
          var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)();
          region.width = settings.get("width", 100);
          region.lines = settings.get("lines", 3);
          region.regionAnchorX = settings.get("regionanchorX", 0);
          region.regionAnchorY = settings.get("regionanchorY", 100);
          region.viewportAnchorX = settings.get("viewportanchorX", 0);
          region.viewportAnchorY = settings.get("viewportanchorY", 100);
          region.scroll = settings.get("scroll", "");
          // Register the region.
          self.onregion && self.onregion(region);
          // Remember the VTTRegion for later in case we parse any VTTCues that
          // reference it.
          self.regionList.push({
            id: settings.get("id"),
            region: region
          });
        }
      }

      // 3.2 WebVTT metadata header syntax
      function parseHeader(input) {
        parseOptions(input, function (k, v) {
          switch (k) {
          case "Region":
            // 3.3 WebVTT region metadata header syntax
            parseRegion(v);
            break;
          }
        }, /:/);
      }

      // 5.1 WebVTT file parsing.
      try {
        var line;
        if (self.state === "INITIAL") {
          // We can't start parsing until we have the first line.
          if (!/\r\n|\n/.test(self.buffer)) {
            return this;
          }

          line = collectNextLine();

          var m = line.match(/^WEBVTT([ \t].*)?$/);
          if (!m || !m[0]) {
            throw new ParsingError(ParsingError.Errors.BadSignature);
          }

          self.state = "HEADER";
        }

        var alreadyCollectedLine = false;
        while (self.buffer) {
          // We can't parse a line until we have the full line.
          if (!/\r\n|\n/.test(self.buffer)) {
            return this;
          }

          if (!alreadyCollectedLine) {
            line = collectNextLine();
          } else {
            alreadyCollectedLine = false;
          }

          switch (self.state) {
          case "HEADER":
            // 13-18 - Allow a header (metadata) under the WEBVTT line.
            if (/:/.test(line)) {
              parseHeader(line);
            } else if (!line) {
              // An empty line terminates the header and starts the body (cues).
              self.state = "ID";
            }
            continue;
          case "NOTE":
            // Ignore NOTE blocks.
            if (!line) {
              self.state = "ID";
            }
            continue;
          case "ID":
            // Check for the start of NOTE blocks.
            if (/^NOTE($|[ \t])/.test(line)) {
              self.state = "NOTE";
              break;
            }
            // 19-29 - Allow any number of line terminators, then initialize new cue values.
            if (!line) {
              continue;
            }
            self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, "");
            self.state = "CUE";
            // 30-39 - Check if self line contains an optional identifier or timing data.
            if (line.indexOf("-->") === -1) {
              self.cue.id = line;
              continue;
            }
            // Process line as start of a cue.
            /*falls through*/
          case "CUE":
            // 40 - Collect cue timings and settings.
            try {
              parseCue(line, self.cue, self.regionList);
            } catch (e) {
              self.reportOrThrowError(e);
              // In case of an error ignore rest of the cue.
              self.cue = null;
              self.state = "BADCUE";
              continue;
            }
            self.state = "CUETEXT";
            continue;
          case "CUETEXT":
            var hasSubstring = line.indexOf("-->") !== -1;
            // 34 - If we have an empty line then report the cue.
            // 35 - If we have the special substring '-->' then report the cue,
            // but do not collect the line as we need to process the current
            // one as a new cue.
            if (!line || hasSubstring && (alreadyCollectedLine = true)) {
              // We are done parsing self cue.
              self.oncue && self.oncue(self.cue);
              self.cue = null;
              self.state = "ID";
              continue;
            }
            if (self.cue.text) {
              self.cue.text += "\n";
            }
            self.cue.text += line;
            continue;
          case "BADCUE": // BADCUE
            // 54-62 - Collect and discard the remaining cue.
            if (!line) {
              self.state = "ID";
            }
            continue;
          }
        }
      } catch (e) {
        self.reportOrThrowError(e);

        // If we are currently parsing a cue, report what we have.
        if (self.state === "CUETEXT" && self.cue && self.oncue) {
          self.oncue(self.cue);
        }
        self.cue = null;
        // Enter BADWEBVTT state if header was not parsed correctly otherwise
        // another exception occurred so enter BADCUE state.
        self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE";
      }
      return this;
    },
    flush: function () {
      var self = this;
      try {
        // Finish decoding the stream.
        self.buffer += self.decoder.decode();
        // Synthesize the end of the current cue or region.
        if (self.cue || self.state === "HEADER") {
          self.buffer += "\n\n";
          self.parse();
        }
        // If we've flushed, parsed, and we're still on the INITIAL state then
        // that means we don't have enough of the stream to parse the first
        // line.
        if (self.state === "INITIAL") {
          throw new ParsingError(ParsingError.Errors.BadSignature);
        }
      } catch(e) {
        self.reportOrThrowError(e);
      }
      self.onflush && self.onflush();
      return this;
    }
  };

  global.WebVTT = WebVTT;

}(this, (this.vttjs || {})));

!function(){!function(a){var b=a&&a.videojs;if(b){b.CDN_VERSION="5.8.8";var c="https:"===a.location.protocol?"https://":"http://";b.options.flash.swf=c+"vjs.zencdn.net/swf/5.0.1/video-js.swf"}}(window),function(a,b,c,d,e,f,g){b&&b.HELP_IMPROVE_VIDEOJS!==!1&&(e.random()>.01||(f=b.location,g=b.videojs||{},a.src="//www.google-analytics.com/__utm.gif?utmwv=5.4.2&utmac=UA-16505296-3&utmn=1&utmhn="+d(f.hostname)+"&utmsr="+b.screen.availWidth+"x"+b.screen.availHeight+"&utmul="+(c.language||c.userLanguage||"").toLowerCase()+"&utmr="+d(f.href)+"&utmp="+d(f.hostname+f.pathname)+"&utmcc=__utma%3D1."+e.floor(1e10*e.random())+".1.1.1.1%3B&utme=8(vjsv*cdnv)9("+g.VERSION+"*"+g.CDN_VERSION+")"))}(new Image,window,navigator,encodeURIComponent,Math)}();;
/*!
 * imagesLoaded PACKAGED v3.1.8
 * JavaScript is all like "You images are done yet or what?"
 * MIT License
 */

(function(){function e(){}function t(e,t){for(var n=e.length;n--;)if(e[n].listener===t)return n;return-1}function n(e){return function(){return this[e].apply(this,arguments)}}var i=e.prototype,r=this,o=r.EventEmitter;i.getListeners=function(e){var t,n,i=this._getEvents();if("object"==typeof e){t={};for(n in i)i.hasOwnProperty(n)&&e.test(n)&&(t[n]=i[n])}else t=i[e]||(i[e]=[]);return t},i.flattenListeners=function(e){var t,n=[];for(t=0;e.length>t;t+=1)n.push(e[t].listener);return n},i.getListenersAsObject=function(e){var t,n=this.getListeners(e);return n instanceof Array&&(t={},t[e]=n),t||n},i.addListener=function(e,n){var i,r=this.getListenersAsObject(e),o="object"==typeof n;for(i in r)r.hasOwnProperty(i)&&-1===t(r[i],n)&&r[i].push(o?n:{listener:n,once:!1});return this},i.on=n("addListener"),i.addOnceListener=function(e,t){return this.addListener(e,{listener:t,once:!0})},i.once=n("addOnceListener"),i.defineEvent=function(e){return this.getListeners(e),this},i.defineEvents=function(e){for(var t=0;e.length>t;t+=1)this.defineEvent(e[t]);return this},i.removeListener=function(e,n){var i,r,o=this.getListenersAsObject(e);for(r in o)o.hasOwnProperty(r)&&(i=t(o[r],n),-1!==i&&o[r].splice(i,1));return this},i.off=n("removeListener"),i.addListeners=function(e,t){return this.manipulateListeners(!1,e,t)},i.removeListeners=function(e,t){return this.manipulateListeners(!0,e,t)},i.manipulateListeners=function(e,t,n){var i,r,o=e?this.removeListener:this.addListener,s=e?this.removeListeners:this.addListeners;if("object"!=typeof t||t instanceof RegExp)for(i=n.length;i--;)o.call(this,t,n[i]);else for(i in t)t.hasOwnProperty(i)&&(r=t[i])&&("function"==typeof r?o.call(this,i,r):s.call(this,i,r));return this},i.removeEvent=function(e){var t,n=typeof e,i=this._getEvents();if("string"===n)delete i[e];else if("object"===n)for(t in i)i.hasOwnProperty(t)&&e.test(t)&&delete i[t];else delete this._events;return this},i.removeAllListeners=n("removeEvent"),i.emitEvent=function(e,t){var n,i,r,o,s=this.getListenersAsObject(e);for(r in s)if(s.hasOwnProperty(r))for(i=s[r].length;i--;)n=s[r][i],n.once===!0&&this.removeListener(e,n.listener),o=n.listener.apply(this,t||[]),o===this._getOnceReturnValue()&&this.removeListener(e,n.listener);return this},i.trigger=n("emitEvent"),i.emit=function(e){var t=Array.prototype.slice.call(arguments,1);return this.emitEvent(e,t)},i.setOnceReturnValue=function(e){return this._onceReturnValue=e,this},i._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},i._getEvents=function(){return this._events||(this._events={})},e.noConflict=function(){return r.EventEmitter=o,e},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return e}):"object"==typeof module&&module.exports?module.exports=e:this.EventEmitter=e}).call(this),function(e){function t(t){var n=e.event;return n.target=n.target||n.srcElement||t,n}var n=document.documentElement,i=function(){};n.addEventListener?i=function(e,t,n){e.addEventListener(t,n,!1)}:n.attachEvent&&(i=function(e,n,i){e[n+i]=i.handleEvent?function(){var n=t(e);i.handleEvent.call(i,n)}:function(){var n=t(e);i.call(e,n)},e.attachEvent("on"+n,e[n+i])});var r=function(){};n.removeEventListener?r=function(e,t,n){e.removeEventListener(t,n,!1)}:n.detachEvent&&(r=function(e,t,n){e.detachEvent("on"+t,e[t+n]);try{delete e[t+n]}catch(i){e[t+n]=void 0}});var o={bind:i,unbind:r};"function"==typeof define&&define.amd?define("eventie/eventie",o):e.eventie=o}(this),function(e,t){"function"==typeof define&&define.amd?define(["eventEmitter/EventEmitter","eventie/eventie"],function(n,i){return t(e,n,i)}):"object"==typeof exports?module.exports=t(e,require("wolfy87-eventemitter"),require("eventie")):e.imagesLoaded=t(e,e.EventEmitter,e.eventie)}(window,function(e,t,n){function i(e,t){for(var n in t)e[n]=t[n];return e}function r(e){return"[object Array]"===d.call(e)}function o(e){var t=[];if(r(e))t=e;else if("number"==typeof e.length)for(var n=0,i=e.length;i>n;n++)t.push(e[n]);else t.push(e);return t}function s(e,t,n){if(!(this instanceof s))return new s(e,t);"string"==typeof e&&(e=document.querySelectorAll(e)),this.elements=o(e),this.options=i({},this.options),"function"==typeof t?n=t:i(this.options,t),n&&this.on("always",n),this.getImages(),a&&(this.jqDeferred=new a.Deferred);var r=this;setTimeout(function(){r.check()})}function f(e){this.img=e}function c(e){this.src=e,v[e]=this}var a=e.jQuery,u=e.console,h=u!==void 0,d=Object.prototype.toString;s.prototype=new t,s.prototype.options={},s.prototype.getImages=function(){this.images=[];for(var e=0,t=this.elements.length;t>e;e++){var n=this.elements[e];"IMG"===n.nodeName&&this.addImage(n);var i=n.nodeType;if(i&&(1===i||9===i||11===i))for(var r=n.querySelectorAll("img"),o=0,s=r.length;s>o;o++){var f=r[o];this.addImage(f)}}},s.prototype.addImage=function(e){var t=new f(e);this.images.push(t)},s.prototype.check=function(){function e(e,r){return t.options.debug&&h&&u.log("confirm",e,r),t.progress(e),n++,n===i&&t.complete(),!0}var t=this,n=0,i=this.images.length;if(this.hasAnyBroken=!1,!i)return this.complete(),void 0;for(var r=0;i>r;r++){var o=this.images[r];o.on("confirm",e),o.check()}},s.prototype.progress=function(e){this.hasAnyBroken=this.hasAnyBroken||!e.isLoaded;var t=this;setTimeout(function(){t.emit("progress",t,e),t.jqDeferred&&t.jqDeferred.notify&&t.jqDeferred.notify(t,e)})},s.prototype.complete=function(){var e=this.hasAnyBroken?"fail":"done";this.isComplete=!0;var t=this;setTimeout(function(){if(t.emit(e,t),t.emit("always",t),t.jqDeferred){var n=t.hasAnyBroken?"reject":"resolve";t.jqDeferred[n](t)}})},a&&(a.fn.imagesLoaded=function(e,t){var n=new s(this,e,t);return n.jqDeferred.promise(a(this))}),f.prototype=new t,f.prototype.check=function(){var e=v[this.img.src]||new c(this.img.src);if(e.isConfirmed)return this.confirm(e.isLoaded,"cached was confirmed"),void 0;if(this.img.complete&&void 0!==this.img.naturalWidth)return this.confirm(0!==this.img.naturalWidth,"naturalWidth"),void 0;var t=this;e.on("confirm",function(e,n){return t.confirm(e.isLoaded,n),!0}),e.check()},f.prototype.confirm=function(e,t){this.isLoaded=e,this.emit("confirm",this,t)};var v={};return c.prototype=new t,c.prototype.check=function(){if(!this.isChecked){var e=new Image;n.bind(e,"load",this),n.bind(e,"error",this),e.src=this.src,this.isChecked=!0}},c.prototype.handleEvent=function(e){var t="on"+e.type;this[t]&&this[t](e)},c.prototype.onload=function(e){this.confirm(!0,"onload"),this.unbindProxyEvents(e)},c.prototype.onerror=function(e){this.confirm(!1,"onerror"),this.unbindProxyEvents(e)},c.prototype.confirm=function(e,t){this.isConfirmed=!0,this.isLoaded=e,this.emit("confirm",this,t)},c.prototype.unbindProxyEvents=function(e){n.unbind(e.target,"load",this),n.unbind(e.target,"error",this)},s});;
// uses data variables and image resizer:
// data-msrc = source location of the file
// data-mratio = initial scale (1 = 100%, .5 = 50% or used at half width...)
// data-mtype = image - adds img src tag, background - add style with background tag to element
// data-mwidth = overrides max width perameter of largest image
// data-mheight = overrides max height perameter of largest image
// data-mquality = sets jpg quality 90,70,60 etc
// data-mformat = forces data format jpg or png
// data-mmode = Imageresizer mode
// data-mscale = Imageresizer scale
// data-manchor = Imageresizer anchor

// Attaches with class name of imageHandler

$(document).ready(function () {
    var maxwidth = 1600;
    var basescale = 1.0;
    var quality = 100;
    var browserwidth = $(window).width();
  
    //if (browserwidth <= 479) { basescale = 600 / maxwidth; }
    //else if (browserwidth <= 767) { basescale = 800 / maxwidth; }
    //else
  
    if (browserwidth <= 991) { basescale = 1000 / maxwidth; }
    else if (browserwidth <= 1199) { basescale = 1200 / maxwidth; }
    else if (browserwidth <= 1279) { basescale = 1400 / maxwidth; }
    else if (browserwidth <= 1499) { basescale = 1600 / maxwidth; }
  
    //setTimeout(function () {
    //    console.log('aftertimeout');
    //}, 5000);

      $(".imageHandler").each(function () {
          var thisscale = basescale;
          var thiswidth = maxwidth;
          var thisquality = 100;
          var thistype = "image"
          if ($(this).data("mtype") == "background") {
              thistype = "background";
          }
          if ($(this).data("mratio") && !isNaN($(this).data("mratio"))) {
              thisscale = thisscale * $(this).data("mratio");
          }
          if ($(this).data("mwidth") && !isNaN($(this).data("mwidth"))) {
              thiswidth = $(this).data("mwidth");
          }
          if ($(this).data("mquality") && !isNaN($(this).data("mquality"))) {
              thisquality = $(this).data("mquality");
          }
  
          
          
          // lets resize the width based on screen size
          thiswidth = Math.round(thiswidth * thisscale);
          var thisurl = "";

          if (thiswidth == maxwidth) {
              thisheight = Math.round($(this).data("mheight") * thisscale);

              thisurl = $(this).data("msrc") + "?h=" + thisheight + "&quality=" + thisquality
          }
          else {
              thisurl = $(this).data("msrc") + "?w=" + thiswidth + "&quality=" + thisquality;

              if ($(this).data("mheight")) {
                  thisheight = Math.round($(this).data("mheight") * thisscale);
                  thisurl = thisurl + "&h=" + thisheight;
              }
          }
          
          if ($(this).data("mformat")) {
              thisurl = thisurl + "&format=" + $(this).data("mformat");
          }
          if ($(this).data("mmode")) {
              thisurl = thisurl + "&mode=" + $(this).data("mmode");
          }
          if ($(this).data("mscale")) {
              thisurl = thisurl + "&scale=" + $(this).data("mscale");
          }
          if ($(this).data("manchor")) {
              thisurl = thisurl + "&anchot=" + $(this).data("manchor");
          }
  
          if (thistype == "image") {
            
              $(this).attr("src", thisurl);
              
          }
          else {
              $(this).css("background-image", "url('" + thisurl + "')");
          }
  
  
  
  
  
  
  
  
      });
  
  
  
  
  });
  ;
var navbar = function () {
    $(".navigation").toggleClass('active');
    $(".bg-banner-slide").toggleClass('active');
}

var resizeTimeout;

function slickSizer() {
    $('.slick-slide').css('height', 'auto');
    $('.slick-slide .slide-content_right').css('height', 'auto');
    setTimeout(function () {
        var stHeight = $('.slick-track').height();
        $('.slick-slide').css('height', stHeight + 'px');
        $('.slick-slide .slide-content_right').css('height', stHeight + 'px');
    }, 50);

};

$.fn.customMatchHeight = function (breakpoint, breakpointLG) {
    breakpoint = typeof breakpoint !== 'undefined' ? breakpoint : 0;
    breakpointLG = typeof breakpointLG !== 'undefined' ? breakpointLG : 0;



    if (this.length) {
        var $set = this;
        var len = $set.length;
        var range;
        $set.css({ 'height': 'auto' });


        var range = (breakpointLG != 0) ? (window.innerWidth > breakpoint && breakpointLG > window.innerWidth) : (window.innerWidth > breakpoint);

        if (range) {
            $set.css({ 'height': 'auto' });
            var height = $set[0].clientHeight;
            for (var i = 1; i < len; i++) {
                if ($set[i].clientHeight > height) {
                    height = $set[i].clientHeight;
                }
            }

            $set.css('height', height);
        } else {
            $set.removeStyle('height');
        }
    }
}

$(document).ready(function () {

    // Custom Select
    $('.select-style').customSelect();
    $('.trial-select-style').customSelect();

    // Match heights

    $('.team-container').matchHeight();
    $('.thumb-description').matchHeight();
    $('.standards-tile').matchHeight();
    $('.resources-listing li').matchHeight();
    $('.video-post').matchHeight();
    $('.page-contact .content').matchHeight();
    $('.heightMatch').matchHeight();

    $('#sb-site').imagesLoaded().always(function (instance) {

        //$('.callout').matchHeight();
        //$('.funding-featured_slider .callout .content').customMatchHeight();

    })


    // Home slider
    $('.home-callout_slider').slick({
        centerMode: true,
        slidesToShow: 3,
        centerPadding: '135px',
        initialSlide: 2,
        arrows: true,
        autoPlay: true,
        nextArrow: "<i class='fa fa-chevron-right slick-next slider-circle'></i><span class='sr-only'>Next Slide</span>",
        prevArrow: "<i class='fa fa-chevron-left slick-prev slider-circle'></i><span class='sr-only'>Previous Slide</span>",
        responsive: [
            {
                breakpoint: 1199,
                settings: {
                    slidesToShow: 2,
                    slidesToScroll: 1
                }
            },
            {
                breakpoint: 991,
                settings: {
                    slidesToShow: 2,
                    centerPadding: '115px'
                }
            },
            {
                breakpoint: 767,
                settings: {
                    initialSlide: 1,
                    slidesToShow: 1,
                    slidesToScroll: 1,
                    centerPadding: '115px'
                }
            },

            {
                breakpoint: 640,
                settings: {
                    initialSlide: 1,
                    slidesToShow: 1,
                    slidesToScroll: 1,
                    centerPadding: '100px'
                }
            },

            {
                breakpoint: 546,
                settings: {
                    initialSlide: 1,
                    slidesToShow: 1,
                    slidesToScroll: 1,
                    centerPadding: '0px'
                }

            }
        ]
    });

    // Funding slider
    $('.funding-featured_slider').slick({
        centerMode: true,
        slidesToShow: 1,
        centerPadding: '350px',
        initialSlide: 0,
        arrows: true,
        autoPlay: true,
        nextArrow: "<i class='fa fa-chevron-right slick-next slider-circle'></i><span class='sr-only'>Next Slide</span>",
        prevArrow: "<i class='fa fa-chevron-left slick-prev slider-circle'></i><span class='sr-only'>Previous Slide</span>",
        responsive: [
            {
                breakpoint: 1199,
                settings: {
                    initialSlide: 1,
                    slidesToShow: 1,
                    slidesToScroll: 1,
                    centerPadding: '250px'
                }
            },
            {
                breakpoint: 991,
                settings: {
                    initialSlide: 1,
                    slidesToShow: 1,
                    slidesToScroll: 1,
                    centerPadding: '150px'
                }
            },

            {
                breakpoint: 767,
                settings: {
                    initialSlide: 1,
                    slidesToShow: 1,
                    slidesToScroll: 1,
                    centerPadding: '60px'
                }
            },

            {
                breakpoint: 546,
                settings: {
                    initialSlide: 1,
                    slidesToShow: 1,
                    slidesToScroll: 1,
                    centerPadding: '0px'
                }

            }
        ]
    });

    $('.slider--featured').slick({

        slidesToShow: 1,
        arrows: true,
        autoPlay: false,
        dots: true,
        slidesToScroll: 1,
        infinite: true
    });

    $('.products_top-slider').slick({

        slidesToShow: 1,
        arrows: true,
        autoPlay: true,
        nextArrow: "<i class='fa fa-chevron-right slick-next slider-circle dark'><span class='sr-only'>Next Slide</span></i>",
        prevArrow: "<i class='fa fa-chevron-left slick-prev slider-circle dark'><span class='sr-only'>Previous Slide</span></i>",
    });

    $('#sliderAwards').slick({
        slidesToShow: 1,
        arrows: true,
        autoPlay: false,
        adaptiveHeight: false,
        dots: true,
        prevArrow: "<a class='widget-slider__arrow widget-slider__arrow-left' title='previous'><span class='sr-only'>Next Award</span></a>",
        nextArrow: "<a class='widget-slider__arrow widget-slider__arrow-right' title='next'><span class='sr-only'>Previous Award</span></a>"
    });

    $('#sliderTestimonials').slick({
        slidesToShow: 1,
        arrows: true,
        autoPlay: false,
        adaptiveHeight: false,
        dots: true,
        prevArrow: "<a class='widget-slider__arrow widget-slider__arrow-left' title='previous'><span class='sr-only'>Next Testimonial</span></a>",
        nextArrow: "<a class='widget-slider__arrow widget-slider__arrow-right' title='next'><span class='sr-only'>Previous Testimonial</span></a>"
    });

    $('.teacher-slider').slick({
        slidesToShow: 1,
        arrows: true,
        //autoplay: true,
        autoplaySpeed: 5000,
        prevArrow: "<a class='slick-prev' title='previous'><span class='sr-only'>Next Testimonial</span></a>",
        nextArrow: "<a class='slick-next' title='next'><span class='sr-only'>Previous Testimonial</span></a>"

    });

    slickSizer();

    $('.hoverfade').hover(function () {
        $(this).find('.h-fade').animate({ opacity: 0.8 }, "fast");
    }, function () {
        $(this).find('.h-fade').animate({ opacity: 1 }, "fast");
    });

    // Clickable function
    $(".clickable a").click(function (e) {
        e.stopPropagation();
    });

    $(".clickable").click(function () {
        if ($(this).find("a").attr("rel") == "external") {
            window.parent.open($(this).find("a").attr("href"))
        } else {
            if ($(this).find("a").attr("target") == "_blank") {
                window.parent.open($(this).find("a").attr("href"))
            } else {
                window.parent.location = $(this).find("a").attr("href"); return false;
                return;
            }
        }
    });

    // Alert Bar Close Button
    $("#stickyBar__wrap .close").click(function (e) {
        $('#stickyBar__wrap').addClass("d-none");
    });

    // Headroom JS
    if ($('#productDetailBanner').length) {

        $("#subNav").headroom({
            offset: $('#productDetailBanner').offset().top
        });

        $("#productDetailBanner").headroom({
            offset: $('#productDetailBanner').offset().top
        });

        $('#subNav').addClass('hasProductDetail');


        $(".main-content").headroom({
            offset: $('#productDetailBanner').offset().top
        });

        if ($('#subNav').length) {

            $("#subNav").headroom({
                offset: $('#subNav').offset().top
            });

            $("#productDetailBanner").headroom({
                offset: $('#subNav').offset().top
            });
        }
    }




    //else if ($('#subNav').length) {

    //    $("#subNav").headroom({
    //        offset: $('#subNav').offset().top
    //    });

    //    $("#productDetailBanner").headroom({
    //        offset: $('#subNav').offset().top
    //    });
    //}

    var megamenuOpen = false;

    // Accessibility dropdown menu focus
    $('a.primary-nav-href').focus(function () {

        // Resets
        $('body').removeClass('menuoverlay-active');

        // Show overlay if menu item has a submenu
        if (!($(this).parent().hasClass('no-dropdown')) && !($('body').hasClass('menuoverlay-active'))) {
            $('body').addClass('menuoverlay-active');
        }

        // Close any open containers
        $('.megamenu-container').removeClass('is-active');
        // Open desired container
        $(this).siblings('.megamenu-container').addClass('is-active');

        // Remove is-active from all primary-nav-href
        $('.primary-nav-href').removeClass('is-active');
        // Add is-active to desired primary-nav-href
        $(this).addClass('is-active');

        // Set open variable
        megamenuOpen = true;
    });

    $('a.primary-nav-href').hover(function () {

        // Resets
        $('body').removeClass('menuoverlay-active');

        // Show overlay if menu item has a submenu
        if (!($(this).parent().hasClass('no-dropdown')) && !($('body').hasClass('menuoverlay-active'))) {
            $('body').addClass('menuoverlay-active');
        }

        // Close any open containers
        $('.megamenu-container').removeClass('is-active');
        // Open desired container
        $(this).siblings('.megamenu-container').addClass('is-active');

        // Remove is-active from all primary-nav-href
        $('.primary-nav-href').removeClass('is-active');
        // Add is-active to desired primary-nav-href
        $(this).addClass('is-active');

        // Set open variable
        megamenuOpen = true;
    });

    $(".megamenu-container").mouseleave(function () {
        $('body').removeClass('menuoverlay-active');
        $('.megamenu-container').removeClass('is-active');
        $('.primary-nav-href').removeClass('is-active');
        megamenuOpen = false;

    });

    $(".learning-navbar .navigation").mouseleave(function () {
        if (megamenuOpen) {
            $('body').removeClass('menuoverlay-active');
            $('.megamenu-container').removeClass('is-active');
            $('.primary-nav-href').removeClass('is-active');
            megamenuOpen = false;
        }
    });

    // Close megamenu if body is clicked
    $(document).mouseup(function (e) {
        var container = $(".primary-nav-link");
        if (!container.is(e.target) // if the target of the click isn't the megamenu ...
            && container.has(e.target).length === 0) // ... nor a descendant of the megamenu
        {
            // Close open megamenu
            $('body').removeClass('menuoverlay-active');
            $('.megamenu-container').removeClass('is-active');
            $('.primary-nav-href').removeClass('is-active');
            megamenuOpen = false;
        }
    });

    $(".primary-nav-link .administrators").click(function () {
        $(".nav-tabs-red li").removeClass("active");
        $('a[href*="#administrators"]').parent(".nav-tabs-red li").addClass("active");
        $(".tab-pane").removeClass("active");
        $(".tab-pane#administrators").addClass("active");
    });

    $(".primary-nav-link .teachers").click(function () {
        $(".nav-tabs-red li").removeClass("active");
        $('a[href*="#teachers"]').parent(".nav-tabs-red li").addClass("active");
        $(".tab-pane").removeClass("active");
        $(".tab-pane#teachers").addClass("active");
    });

    $(".primary-nav-link .parents").click(function () {
        $(".nav-tabs-red li").removeClass("active");
        $('a[href*="#parents"]').parent(".nav-tabs-red li").addClass("active");
        $(".tab-pane").removeClass("active");
        $(".tab-pane#parents").addClass("active");
    });


    // Calling LayerSlider on the target element
    $('#layerslider').layerSlider({
        showCircleTimer: false,
        skin: 'fullwidthdark',
        skinsPath: '/Assets/skins/',
        pauseOnHover: false,
        //autoStart: false,

        // Slider options goes here,
        // please check the 'List of slider options' section in the documentation
    });

    // Slidebar Flyout Menu
    $.slidebars();

    $('[data-toggle="tooltip"]').tooltip();

    // Slidebars Submenus
    $('.sb-toggle-submenu').off('click').on('click', function () {
        $submenu = $(this).parent().children('.sb-submenu');
        $(this).add($submenu).toggleClass('sb-submenu-active');


        $(this).add($submenu).parent().siblings().children('a').removeClass('sb-submenu-active');


        $submenu.slideToggle(200);


        $(this).add($submenu).parent().siblings().children('.sb-submenu').slideUp(200);;// Toggle active class.
    });

    handleAnimation();

    // Live chat button
    $(".livechatbutton").click(function () {
        LazMarketingChat.openChatWindow($(this).data("serverenv"));
    });

    if ($('.accordion').length) {
        $('.accordion-toggle').click(function (e) {
            // Grab current anchor value
            var currentAttrValue = $(this).attr('href');


            if ($(this).hasClass('active')) {

                close_accordion_section();

            } else {

                close_accordion_section();

                // Add active class to section title
                $(this).addClass('active');
                // Open up the hidden content panel
                $('.accordion ' + currentAttrValue).slideDown(300).addClass('open');
            }

            e.preventDefault();
        });
    }

    setupVideoJs();

    $('.close-button').click(function () {
        var selector = $(this).data('for');

        $(selector).toggleClass('closed');
    });


    $('.pd-contact').click(function () {
        $("#contact-pd_select-state").val(0).trigger('change.customSelect');
    });

});

function close_accordion_section() {
    $('.accordion .accordion-toggle').removeClass('active');
    $('.accordion .accordion-section-content').slideUp(300).removeClass('open');
}


    $("#search-toggle").click(function (e) {
        e.stopPropagation();
        $(this).toggleClass('search-open');
        $(".learning-navbar .search-bar").toggleClass('active');
        if ($(".learning-navbar .search-bar").hasClass('active')) {
            $(".learning-navbar .search-bar input").focus();
        }
    });

    $(document).click(function (event) {
        if (!$(event.target).closest('.learning-navbar .search-bar').length) {
            if ($(".search-bar").hasClass('active')) {
                $(".search-bar").removeClass('active');
                $("#toggle-search").removeClass('search-open');
            }
        }
    });


var setupVideoJs = function () {

    setTimeout(function () {

        if ($('#laz-video').length) {

            videojs('laz-video').ready(function () {
                var self = this;

                //setTimeout(function () {
                //    self.posterImage.update();
                //}, 200);

                // Disable captions by default
                var tracks = self.textTracks();
                for (var i = 0; i < tracks.length; i++) {
                    var track = tracks[i];
                    if (track.kind === 'captions' || track.language === 'subtitles') {
                        track.mode = 'hidden';
                    }
                }

            });
        };
    }, 300);

};

// Resize functions
window.onresize = function () {
    clearTimeout(resizeTimeout);
    resizeTimout = setTimeout(function () {
        $('.select-style').trigger('render');
        $('.trial-select-style').trigger('render');
        slickSizer();
        //$.slidebars.close();
        if ($(window).width() <= 767) {
            $('.home-callout_slider').slick("slickGoTo", 1);
        } else {
            $('.home-callout_slider').slick("slickGoTo", 2);
        }
    }, 100);
};

// Javascript to enable link to tab
$(window).on('load', function () {
    if ($('#resources').length) {
        var url = document.location.toString();
        if ($('.nav-tabs-red').length) {
            if (url.match('#')) {

                $('.nav-tabs-red a[href="#' + url.split('#')[1] + '"]').tab('show');
                let resources = $('#resources').offset().top;
                $(window).scrollTop(resources);
            }

            $('.nav-tabs-red a').on('shown.bs.tab', function (e) {
                window.location.hash = e.target.hash;
                let resources = $('#resources').offset().top;
                $(window).scrollTop(resources);
            });

        } else {
            if (url.match('#')) {

                $('.nav-tabs a[href="#' + url.split('#')[1] + '"]').tab('show');
                let resources = $('#resources').offset().top;
                $(window).scrollTop(resources);
            }

            $('.nav-tabs a').on('shown.bs.tab', function (e) {
                window.location.hash = e.target.hash;
                let resources = $('#resources').offset().top;
                $(window).scrollTop(resources);
            });
        }
    }
});

if ($('#resources').length) {
    $(window).on('hashchange', function (e) {
        var url = document.location.toString();
        if ($('.nav-tavs-red').length) {

            if (url.match('#')) {
                $('.nav-tabs-red a[href="#' + url.split('#')[1] + '"]').tab('show');
                let resources = $('#resources').offset().top;
                $(window).scrollTop(resources);
            }

            // Change hash for page-reload
            $('.nav-tabs-red a').on('shown.bs.tab', function (e) {
                window.location.hash = e.target.hash;
            })
            let resources = $('#resources').offset().top;
            $(window).scrollTop(resources);
        } else {
            if (url.match('#')) {
                $('.nav-tabs a[href="#' + url.split('#')[1] + '"]').tab('show');
                let resources = $('#resources').offset().top;
                $(window).scrollTop(resources);
            }

            // Change hash for page-reload
            $('.nav-tabs a').on('shown.bs.tab', function (e) {
                window.location.hash = e.target.hash;
            })
            let resources = $('#resources').offset().top;
            $(window).scrollTop(resources);
        }
    })
};

$.fn.isOnScreen = function () {
    var element = this.get(0);
    var bounds = element.getBoundingClientRect();
    return bounds.top < window.innerHeight;
}

function handleAnimation() {
    var animate = [];

    $(".animate, [class^='arrow-down']").each(function (index) {
        animate[index] = $(this);
    });

    setTimeout(function () {
        for (var x in animate) {
            if (animate[x].isOnScreen()) {
                animate[x].addClass('active');
            } else {
                animate[x].removeClass('active');
            }
        }
    }, 500);
}

function handlePopovers() {
    $('[data-toggle="popover"]').popover({
        html: true,
        content: function () {
            return $(this).next('.popover-content').html();
        },
        sanitizeFn: function (content) {
            return DOMPurify.sanitize(content)
        }
    });
}

scrollHandler = function () {
    handleAnimation();
    handlePopovers();
}

window.onscroll = scrollHandler;
;
//const links = document.querySelectorAll('a');

//const targetDomain = 'localhost';
//const targetDomainLaz = "learninga-z.com";
//const referralCodeQuerystringParameter = "referralCode";
//const referralCodeElement = document.getElementById("referral-code");

//if (referralCodeElement) {
//    const referralCode = referralCodeElement.innerText;
//    const variableToAdd = referralCodeQuerystringParameter + "=" + referralCode;

//if (!referralCode) {
//    return;
//}

//    links.forEach(link => {
//        if (link.hasAttribute('data-target')) {
//            return;
//        }

//        let href = link.getAttribute('href');
//        let hrefClass = link.getAttribute('class');

//        //if (hrefClass) {
//        //    alert("class: " + hrefClass);
//        //}

//        if (hrefClass && hrefClass.includes('modallink')) {
//            alert('modal');
//            return;
//        }

//        if (href && (href.startsWith('#') || href.includes('#'))) {
//            return;
//        }

//        if (href && (href.includes(targetDomain) || href.includes(targetDomainLaz) || href.startsWith('/'))) {
//            if (hrefClass && hrefClass.includes('accordion')) {
//                console.log(href);
//            }
//            if (!href.includes(variableToAdd) && !href.includes('referral=')) {
//                if (href.includes('?')) {
//                    href += `&${variableToAdd}`;
//                } else {
//                    href += `?${variableToAdd}`;
//                }

//                link.setAttribute('href', href);
//            }
//        }
//    });
//}



$(document).ready(function () {
    const $links = $('a').not('[href^="#"]').not('[href^="javascript:"]');

    const targetDomain = 'localhost';
    const targetDomainLaz = "learninga-z.com";
    const referralCodeQuerystringParameter = "referralCode";
    const referralCodeElement = $("#referral-code");

    if (referralCodeElement) {
        const referralCode = referralCodeElement.text();

        if (!referralCode) {
            return;
        }

        const variableToAdd = referralCodeQuerystringParameter + "=" + referralCode;

        $links.each(function () {
            const $link = $(this);
            let href = $link.attr('href');

            if (!href) {
                return;
            }

            if (href.includes('#')) {
                return;
            }

            if (href.includes(targetDomain) || href.includes(targetDomainLaz) || href.startsWith('/')) {
                if (!href.includes(variableToAdd) && !href.includes('referral=')) {
                    if (href.includes('?')) {
                        href += `&${variableToAdd}`;
                    } else {
                        href += `?${variableToAdd}`;
                    }

                    $link.attr('href', href);
                }
            }
        });
    }
});;
