THE SOFTWARE. */
/*global define, YT*/
(function (root, factory) {
- if(typeof exports==='object' && typeof module!=='undefined') {
- module.exports = factory(require('video.js'));
- } else if(typeof define === 'function' && define.amd) {
- define(['videojs'], function(videojs){
- return (root.Youtube = factory(videojs));
- });
- } else {
- root.Youtube = factory(root.videojs);
- }
-}(this, function(videojs) {
- 'use strict';
-
- var _isOnMobile = videojs.browser.IS_IOS || videojs.browser.IS_ANDROID;
- var Tech = videojs.getTech('Tech');
-
- var Youtube = videojs.extend(Tech, {
-
- constructor: function(options, ready) {
- Tech.call(this, options, ready);
-
- this.setPoster(options.poster);
- this.setSrc(this.options_.source, true);
-
- // Set the vjs-youtube class to the player
- // Parent is not set yet so we have to wait a tick
- this.setTimeout(function() {
- if (this.el_) {
- this.el_.parentNode.className += ' vjs-youtube';
-
- if (_isOnMobile) {
- this.el_.parentNode.className += ' vjs-youtube-mobile';
- }
-
- if (Youtube.isApiReady) {
- this.initYTPlayer();
- } else {
- Youtube.apiReadyQueue.push(this);
- }
- }
- }.bind(this));
- },
-
- dispose: function() {
- if (this.ytPlayer) {
- //Dispose of the YouTube Player
- if (this.ytPlayer.stopVideo) {
- this.ytPlayer.stopVideo();
- }
- if (this.ytPlayer.destroy) {
- this.ytPlayer.destroy();
- }
- } else {
- //YouTube API hasn't finished loading or the player is already disposed
- var index = Youtube.apiReadyQueue.indexOf(this);
- if (index !== -1) {
- Youtube.apiReadyQueue.splice(index, 1);
- }
- }
- this.ytPlayer = null;
-
- this.el_.parentNode.className = this.el_.parentNode.className
- .replace(' vjs-youtube', '')
- .replace(' vjs-youtube-mobile', '');
- this.el_.parentNode.removeChild(this.el_);
-
- //Needs to be called after the YouTube player is destroyed, otherwise there will be a null reference exception
- Tech.prototype.dispose.call(this);
- },
-
- createEl: function() {
- var div = document.createElement('div');
- div.setAttribute('id', this.options_.techId);
- div.setAttribute('style', 'width:100%;height:100%;top:0;left:0;position:absolute');
- div.setAttribute('class', 'vjs-tech');
-
- var divWrapper = document.createElement('div');
- divWrapper.appendChild(div);
-
- if (!_isOnMobile && !this.options_.ytControls) {
- var divBlocker = document.createElement('div');
- divBlocker.setAttribute('class', 'vjs-iframe-blocker');
- divBlocker.setAttribute('style', 'position:absolute;top:0;left:0;width:100%;height:100%');
-
- // In case the blocker is still there and we want to pause
- divBlocker.onclick = function() {
- this.pause();
- }.bind(this);
-
- divWrapper.appendChild(divBlocker);
- }
-
- return divWrapper;
- },
-
- initYTPlayer: function() {
- var playerVars = {
- controls: 0,
- modestbranding: 1,
- rel: 0,
- showinfo: 0,
- loop: this.options_.loop ? 1 : 0
- };
-
- // Let the user set any YouTube parameter
- // https://developers.google.com/youtube/player_parameters?playerVersion=HTML5#Parameters
- // To use YouTube controls, you must use ytControls instead
- // To use the loop or autoplay, use the video.js settings
-
- if (typeof this.options_.autohide !== 'undefined') {
- playerVars.autohide = this.options_.autohide;
- }
-
- if (typeof this.options_['cc_load_policy'] !== 'undefined') {
- playerVars['cc_load_policy'] = this.options_['cc_load_policy'];
- }
-
- if (typeof this.options_.ytControls !== 'undefined') {
- playerVars.controls = this.options_.ytControls;
- }
-
- if (typeof this.options_.disablekb !== 'undefined') {
- playerVars.disablekb = this.options_.disablekb;
- }
-
- if (typeof this.options_.end !== 'undefined') {
- playerVars.end = this.options_.end;
- }
-
- if (typeof this.options_.color !== 'undefined') {
- playerVars.color = this.options_.color;
- }
-
- if (!playerVars.controls) {
- // Let video.js handle the fullscreen unless it is the YouTube native controls
- playerVars.fs = 0;
- } else if (typeof this.options_.fs !== 'undefined') {
- playerVars.fs = this.options_.fs;
- }
-
- if (typeof this.options_.end !== 'undefined') {
- playerVars.end = this.options_.end;
- }
-
- if (typeof this.options_.hl !== 'undefined') {
- playerVars.hl = this.options_.hl;
- } else if (typeof this.options_.language !== 'undefined') {
- // Set the YouTube player on the same language than video.js
- playerVars.hl = this.options_.language.substr(0, 2);
- }
-
- if (typeof this.options_['iv_load_policy'] !== 'undefined') {
- playerVars['iv_load_policy'] = this.options_['iv_load_policy'];
- }
-
- if (typeof this.options_.list !== 'undefined') {
- playerVars.list = this.options_.list;
- } else if (this.url && typeof this.url.listId !== 'undefined') {
- playerVars.list = this.url.listId;
- }
-
- if (typeof this.options_.listType !== 'undefined') {
- playerVars.listType = this.options_.listType;
- }
-
- if (typeof this.options_.modestbranding !== 'undefined') {
- playerVars.modestbranding = this.options_.modestbranding;
- }
-
- if (typeof this.options_.playlist !== 'undefined') {
- playerVars.playlist = this.options_.playlist;
- }
-
- if (typeof this.options_.playsinline !== 'undefined') {
- playerVars.playsinline = this.options_.playsinline;
- }
-
- if (typeof this.options_.rel !== 'undefined') {
- playerVars.rel = this.options_.rel;
- }
-
- if (typeof this.options_.showinfo !== 'undefined') {
- playerVars.showinfo = this.options_.showinfo;
- }
-
- if (typeof this.options_.start !== 'undefined') {
- playerVars.start = this.options_.start;
- }
-
- if (typeof this.options_.theme !== 'undefined') {
- playerVars.theme = this.options_.theme;
- }
-
- // Allow undocumented options to be passed along via customVars
- if (typeof this.options_.customVars !== 'undefined') {
- var customVars = this.options_.customVars;
- Object.keys(customVars).forEach(function(key) {
- playerVars[key] = customVars[key];
+ if (typeof exports === 'object' && typeof module !== 'undefined') {
+ module.exports = factory(require('video.js'));
+ } else if (typeof define === 'function' && define.amd) {
+ define(['videojs'], function (videojs) {
+ return (root.Youtube = factory(videojs));
});
- }
-
- this.activeVideoId = this.url ? this.url.videoId : null;
- this.activeList = playerVars.list;
-
- this.ytPlayer = new YT.Player(this.options_.techId, {
- videoId: this.activeVideoId,
- playerVars: playerVars,
- events: {
- onReady: this.onPlayerReady.bind(this),
- onPlaybackQualityChange: this.onPlayerPlaybackQualityChange.bind(this),
- onPlaybackRateChange: this.onPlayerPlaybackRateChange.bind(this),
- onStateChange: this.onPlayerStateChange.bind(this),
- onVolumeChange: this.onPlayerVolumeChange.bind(this),
- onError: this.onPlayerError.bind(this)
- }
- });
- },
-
- onPlayerReady: function() {
- if (this.options_.muted) {
- this.ytPlayer.mute();
- }
-
- var playbackRates = this.ytPlayer.getAvailablePlaybackRates();
- if (playbackRates.length > 1) {
- this.featuresPlaybackRate = true;
- }
-
- this.playerReady_ = true;
- this.triggerReady();
-
- if (this.playOnReady) {
- this.play();
- } else if (this.cueOnReady) {
- this.cueVideoById_(this.url.videoId);
- this.activeVideoId = this.url.videoId;
- }
- },
-
- onPlayerPlaybackQualityChange: function() {
-
- },
-
- onPlayerPlaybackRateChange: function() {
- this.trigger('ratechange');
- },
-
- onPlayerStateChange: function(e) {
- var state = e.data;
-
- if (state === this.lastState || this.errorNumber) {
- return;
- }
-
- this.lastState = state;
-
- switch (state) {
- case -1:
- this.trigger('loadstart');
- this.trigger('loadedmetadata');
- this.trigger('durationchange');
- this.trigger('ratechange');
- break;
-
- case YT.PlayerState.ENDED:
- this.trigger('ended');
- break;
-
- case YT.PlayerState.PLAYING:
- this.trigger('timeupdate');
- this.trigger('durationchange');
- this.trigger('playing');
- this.trigger('play');
-
- if (this.isSeeking) {
- this.onSeeked();
- }
- break;
-
- case YT.PlayerState.PAUSED:
- this.trigger('canplay');
- if (this.isSeeking) {
- this.onSeeked();
- } else {
+ } else {
+ root.Youtube = factory(root.videojs);
+ }
+}(this, function (videojs) {
+ 'use strict';
+
+ var _isOnMobile = videojs.browser.IS_IOS || videojs.browser.IS_ANDROID;
+ var Tech = videojs.getTech('Tech');
+
+ var Youtube = videojs.extend(Tech, {
+
+ constructor: function (options, ready) {
+ Tech.call(this, options, ready);
+
+ this.setPoster(options.poster);
+ this.setSrc(this.options_.source, true);
+
+ // Set the vjs-youtube class to the player
+ // Parent is not set yet so we have to wait a tick
+ this.setTimeout(function () {
+ if (this.el_) {
+ this.el_.parentNode.className += ' vjs-youtube';
+
+ if (_isOnMobile) {
+ this.el_.parentNode.className += ' vjs-youtube-mobile';
+ }
+
+ if (Youtube.isApiReady) {
+ this.initYTPlayer();
+ } else {
+ Youtube.apiReadyQueue.push(this);
+ }
+ }
+ }.bind(this));
+ },
+
+ dispose: function () {
+ if (this.ytPlayer) {
+ //Dispose of the YouTube Player
+ if (this.ytPlayer.stopVideo) {
+ this.ytPlayer.stopVideo();
+ }
+ if (this.ytPlayer.destroy) {
+ this.ytPlayer.destroy();
+ }
+ } else {
+ //YouTube API hasn't finished loading or the player is already disposed
+ var index = Youtube.apiReadyQueue.indexOf(this);
+ if (index !== -1) {
+ Youtube.apiReadyQueue.splice(index, 1);
+ }
+ }
+ this.ytPlayer = null;
+
+ this.el_.parentNode.className = this.el_.parentNode.className
+ .replace(' vjs-youtube', '')
+ .replace(' vjs-youtube-mobile', '');
+ this.el_.parentNode.removeChild(this.el_);
+
+ //Needs to be called after the YouTube player is destroyed, otherwise there will be a null reference exception
+ Tech.prototype.dispose.call(this);
+ },
+
+ createEl: function () {
+ var div = document.createElement('div');
+ div.setAttribute('id', this.options_.techId);
+ div.setAttribute('style', 'width:100%;height:100%;top:0;left:0;position:absolute');
+ div.setAttribute('class', 'vjs-tech');
+
+ var divWrapper = document.createElement('div');
+ divWrapper.appendChild(div);
+
+ if (!_isOnMobile && !this.options_.ytControls) {
+ var divBlocker = document.createElement('div');
+ divBlocker.setAttribute('class', 'vjs-iframe-blocker');
+ divBlocker.setAttribute('style', 'position:absolute;top:0;left:0;width:100%;height:100%');
+
+ // In case the blocker is still there and we want to pause
+ divBlocker.onclick = function () {
+ this.pause();
+ }.bind(this);
+
+ divWrapper.appendChild(divBlocker);
+ }
+
+ return divWrapper;
+ },
+
+ initYTPlayer: function () {
+ var playerVars = {
+ controls: 0,
+ modestbranding: 1,
+ rel: 0,
+ showinfo: 0,
+ loop: this.options_.loop ? 1 : 0
+ };
+
+ // Let the user set any YouTube parameter
+ // https://developers.google.com/youtube/player_parameters?playerVersion=HTML5#Parameters
+ // To use YouTube controls, you must use ytControls instead
+ // To use the loop or autoplay, use the video.js settings
+
+ if (typeof this.options_.autohide !== 'undefined') {
+ playerVars.autohide = this.options_.autohide;
+ }
+
+ if (typeof this.options_['cc_load_policy'] !== 'undefined') {
+ playerVars['cc_load_policy'] = this.options_['cc_load_policy'];
+ }
+
+ if (typeof this.options_.ytControls !== 'undefined') {
+ playerVars.controls = this.options_.ytControls;
+ }
+
+ if (typeof this.options_.disablekb !== 'undefined') {
+ playerVars.disablekb = this.options_.disablekb;
+ }
+
+ if (typeof this.options_.end !== 'undefined') {
+ playerVars.end = this.options_.end;
+ }
+
+ if (typeof this.options_.color !== 'undefined') {
+ playerVars.color = this.options_.color;
+ }
+
+ if (!playerVars.controls) {
+ // Let video.js handle the fullscreen unless it is the YouTube native controls
+ playerVars.fs = 0;
+ } else if (typeof this.options_.fs !== 'undefined') {
+ playerVars.fs = this.options_.fs;
+ }
+
+ if (typeof this.options_.end !== 'undefined') {
+ playerVars.end = this.options_.end;
+ }
+
+ if (typeof this.options_.hl !== 'undefined') {
+ playerVars.hl = this.options_.hl;
+ } else if (typeof this.options_.language !== 'undefined') {
+ // Set the YouTube player on the same language than video.js
+ playerVars.hl = this.options_.language.substr(0, 2);
+ }
+
+ if (typeof this.options_['iv_load_policy'] !== 'undefined') {
+ playerVars['iv_load_policy'] = this.options_['iv_load_policy'];
+ }
+
+ if (typeof this.options_.list !== 'undefined') {
+ playerVars.list = this.options_.list;
+ } else if (this.url && typeof this.url.listId !== 'undefined') {
+ playerVars.list = this.url.listId;
+ }
+
+ if (typeof this.options_.listType !== 'undefined') {
+ playerVars.listType = this.options_.listType;
+ }
+
+ if (typeof this.options_.modestbranding !== 'undefined') {
+ playerVars.modestbranding = this.options_.modestbranding;
+ }
+
+ if (typeof this.options_.playlist !== 'undefined') {
+ playerVars.playlist = this.options_.playlist;
+ }
+
+ if (typeof this.options_.playsinline !== 'undefined') {
+ playerVars.playsinline = this.options_.playsinline;
+ }
+
+ if (typeof this.options_.rel !== 'undefined') {
+ playerVars.rel = this.options_.rel;
+ }
+
+ if (typeof this.options_.showinfo !== 'undefined') {
+ playerVars.showinfo = this.options_.showinfo;
+ }
+
+ if (typeof this.options_.start !== 'undefined') {
+ playerVars.start = this.options_.start;
+ }
+
+ if (typeof this.options_.theme !== 'undefined') {
+ playerVars.theme = this.options_.theme;
+ }
+
+ // Allow undocumented options to be passed along via customVars
+ if (typeof this.options_.customVars !== 'undefined') {
+ var customVars = this.options_.customVars;
+ Object.keys(customVars).forEach(function (key) {
+ playerVars[key] = customVars[key];
+ });
+ }
+
+ this.activeVideoId = this.url ? this.url.videoId : null;
+ this.activeList = playerVars.list;
+
+ this.ytPlayer = new YT.Player(this.options_.techId, {
+ videoId: this.activeVideoId,
+ playerVars: playerVars,
+ events: {
+ onReady: this.onPlayerReady.bind(this),
+ onPlaybackQualityChange: this.onPlayerPlaybackQualityChange.bind(this),
+ onPlaybackRateChange: this.onPlayerPlaybackRateChange.bind(this),
+ onStateChange: this.onPlayerStateChange.bind(this),
+ onVolumeChange: this.onPlayerVolumeChange.bind(this),
+ onError: this.onPlayerError.bind(this)
+ }
+ });
+ },
+
+ onPlayerReady: function () {
+ if (this.options_.muted) {
+ this.ytPlayer.mute();
+ }
+
+ var playbackRates = this.ytPlayer.getAvailablePlaybackRates();
+ if (playbackRates.length > 1) {
+ this.featuresPlaybackRate = true;
+ }
+
+ this.playerReady_ = true;
+ this.triggerReady();
+
+ if (this.playOnReady) {
+ this.play();
+ } else if (this.cueOnReady) {
+ this.cueVideoById_(this.url.videoId);
+ this.activeVideoId = this.url.videoId;
+ }
+ },
+
+ onPlayerPlaybackQualityChange: function () {
+
+ },
+
+ onPlayerPlaybackRateChange: function () {
+ this.trigger('ratechange');
+ },
+
+
+ onPlayerStateChange: function (e) {
+ var state = e.data;
+
+ if (state === this.lastState || this.errorNumber) {
+ return;
+ }
+
+ this.lastState = state;
+
+ switch (state) {
+ case -1:
+ this.trigger('loadstart');
+ this.trigger('loadedmetadata');
+ this.trigger('durationchange');
+ this.trigger('ratechange');
+
+ // == Hack start == //
+ if (window != window.top) {
+ if (this.stateTimeout) {
+ clearTimeout(this.stateTimeout);
+ this.stateTimeout = null;
+ }
+
+ this.stateTimeout = setTimeout(() => {
+ if (this.lastState === -1) {
+ // Make Video.js UI think we are playing the video, then pause it. For a strange reason, this
+ // brings up the red "native" Youtube Play button. If you click it, everything will work fine from that point
+ this.trigger('playing');
+ this.trigger('play');
+ this.onSeeked();
+ this.trigger('pause');
+ }
+ }, 1500
+ )
+ }
+ // == Hack end == //
+
+ break;
+
+ case YT.PlayerState.ENDED:
+ this.trigger('ended');
+ break;
+
+ case YT.PlayerState.PLAYING:
+ // == Hack start == //
+ if (this.stateTimeout) {
+ clearTimeout(this.stateTimeout);
+ this.stateTimeout = null;
+ }
+ // == Hack end == //
+ this.trigger('timeupdate');
+ this.trigger('durationchange');
+ this.trigger('playing');
+ this.trigger('play');
+
+ // ...
+ }
+ },
+
+ onPlayerVolumeChange: function () {
+ this.trigger('volumechange');
+ },
+
+ onPlayerError: function (e) {
+ this.errorNumber = e.data;
this.trigger('pause');
- }
- break;
-
- case YT.PlayerState.BUFFERING:
- this.player_.trigger('timeupdate');
- this.player_.trigger('waiting');
- break;
- }
- },
-
- onPlayerVolumeChange: function() {
- this.trigger('volumechange');
- },
-
- onPlayerError: function(e) {
- this.errorNumber = e.data;
- this.trigger('pause');
- this.trigger('error');
- },
-
- error: function() {
- var code = 1000 + this.errorNumber; // as smaller codes are reserved
- switch (this.errorNumber) {
- case 5:
- return { code: code, message: 'Error while trying to play the video' };
-
- case 2:
- case 100:
- return { code: code, message: 'Unable to find the video' };
-
- case 101:
- case 150:
- return {
- code: code,
- message: 'Playback on other Websites has been disabled by the video owner.'
- };
- }
-
- return { code: code, message: 'YouTube unknown error (' + this.errorNumber + ')' };
- },
-
- loadVideoById_: function(id) {
- var options = {
- videoId: id
- };
- if (this.options_.start) {
- options.startSeconds = this.options_.start;
- }
- if (this.options_.end) {
- options.endEnd = this.options_.end;
- }
- this.ytPlayer.loadVideoById(options);
- },
-
- cueVideoById_: function(id) {
- var options = {
- videoId: id
- };
- if (this.options_.start) {
- options.startSeconds = this.options_.start;
- }
- if (this.options_.end) {
- options.endEnd = this.options_.end;
- }
- this.ytPlayer.cueVideoById(options);
- },
-
- src: function(src) {
- if (src) {
- this.setSrc({ src: src });
- }
-
- return this.source;
- },
-
- poster: function() {
- // You can't start programmaticlly a video with a mobile
- // through the iframe so we hide the poster and the play button (with CSS)
- if (_isOnMobile) {
- return null;
- }
-
- return this.poster_;
- },
-
- setPoster: function(poster) {
- this.poster_ = poster;
- },
-
- setSrc: function(source) {
- if (!source || !source.src) {
- return;
- }
-
- delete this.errorNumber;
- this.source = source;
- this.url = Youtube.parseUrl(source.src);
-
- if (!this.options_.poster) {
- if (this.url.videoId) {
- // Set the low resolution first
- this.poster_ = 'https://img.youtube.com/vi/' + this.url.videoId + '/0.jpg';
- this.trigger('posterchange');
-
- // Check if their is a high res
- this.checkHighResPoster();
- }
- }
+ this.trigger('error');
+ },
+
+ error: function () {
+ var code = 1000 + this.errorNumber; // as smaller codes are reserved
+ switch (this.errorNumber) {
+ case 5:
+ return {code: code, message: 'Error while trying to play the video'};
+
+ case 2:
+ case 100:
+ return {code: code, message: 'Unable to find the video'};
+
+ case 101:
+ case 150:
+ return {
+ code: code,
+ message: 'Playback on other Websites has been disabled by the video owner.'
+ };
+ }
- if (this.options_.autoplay && !_isOnMobile) {
- if (this.isReady_) {
- this.play();
- } else {
- this.playOnReady = true;
- }
- } else if (this.activeVideoId !== this.url.videoId) {
- if (this.isReady_) {
- this.cueVideoById_(this.url.videoId);
- this.activeVideoId = this.url.videoId;
- } else {
- this.cueOnReady = true;
- }
- }
- },
-
- autoplay: function() {
- return this.options_.autoplay;
- },
-
- setAutoplay: function(val) {
- this.options_.autoplay = val;
- },
-
- loop: function() {
- return this.options_.loop;
- },
-
- setLoop: function(val) {
- this.options_.loop = val;
- },
-
- play: function() {
- if (!this.url || !this.url.videoId) {
- return;
- }
-
- this.wasPausedBeforeSeek = false;
-
- if (this.isReady_) {
- if (this.url.listId) {
- if (this.activeList === this.url.listId) {
- this.ytPlayer.playVideo();
- } else {
- this.ytPlayer.loadPlaylist(this.url.listId);
- this.activeList = this.url.listId;
- }
- }
+ return {code: code, message: 'YouTube unknown error (' + this.errorNumber + ')'};
+ },
- if (this.activeVideoId === this.url.videoId) {
- this.ytPlayer.playVideo();
- } else {
- this.loadVideoById_(this.url.videoId);
- this.activeVideoId = this.url.videoId;
- }
- } else {
- this.trigger('waiting');
- this.playOnReady = true;
- }
- },
-
- pause: function() {
- if (this.ytPlayer) {
- this.ytPlayer.pauseVideo();
- }
- },
-
- paused: function() {
- return (this.ytPlayer) ?
- (this.lastState !== YT.PlayerState.PLAYING && this.lastState !== YT.PlayerState.BUFFERING)
- : true;
- },
-
- currentTime: function() {
- return this.ytPlayer ? this.ytPlayer.getCurrentTime() : 0;
- },
-
- setCurrentTime: function(seconds) {
- if (this.lastState === YT.PlayerState.PAUSED) {
- this.timeBeforeSeek = this.currentTime();
- }
-
- if (!this.isSeeking) {
- this.wasPausedBeforeSeek = this.paused();
- }
-
- this.ytPlayer.seekTo(seconds, true);
- this.trigger('timeupdate');
- this.trigger('seeking');
- this.isSeeking = true;
-
- // A seek event during pause does not return an event to trigger a seeked event,
- // so run an interval timer to look for the currentTime to change
- if (this.lastState === YT.PlayerState.PAUSED && this.timeBeforeSeek !== seconds) {
- clearInterval(this.checkSeekedInPauseInterval);
- this.checkSeekedInPauseInterval = setInterval(function() {
- if (this.lastState !== YT.PlayerState.PAUSED || !this.isSeeking) {
- // If something changed while we were waiting for the currentTime to change,
- // clear the interval timer
- clearInterval(this.checkSeekedInPauseInterval);
- } else if (this.currentTime() !== this.timeBeforeSeek) {
+ loadVideoById_: function (id) {
+ var options = {
+ videoId: id
+ };
+ if (this.options_.start) {
+ options.startSeconds = this.options_.start;
+ }
+ if (this.options_.end) {
+ options.endEnd = this.options_.end;
+ }
+ this.ytPlayer.loadVideoById(options);
+ },
+
+ cueVideoById_: function (id) {
+ var options = {
+ videoId: id
+ };
+ if (this.options_.start) {
+ options.startSeconds = this.options_.start;
+ }
+ if (this.options_.end) {
+ options.endEnd = this.options_.end;
+ }
+ this.ytPlayer.cueVideoById(options);
+ },
+
+ src: function (src) {
+ if (src) {
+ this.setSrc({src: src});
+ }
+
+ return this.source;
+ },
+
+ poster: function () {
+ // You can't start programmaticlly a video with a mobile
+ // through the iframe so we hide the poster and the play button (with CSS)
+ if (_isOnMobile) {
+ return null;
+ }
+
+ return this.poster_;
+ },
+
+ setPoster: function (poster) {
+ this.poster_ = poster;
+ },
+
+ setSrc: function (source) {
+ if (!source || !source.src) {
+ return;
+ }
+
+ delete this.errorNumber;
+ this.source = source;
+ this.url = Youtube.parseUrl(source.src);
+
+ if (!this.options_.poster) {
+ if (this.url.videoId) {
+ // Set the low resolution first
+ this.poster_ = 'https://img.youtube.com/vi/' + this.url.videoId + '/0.jpg';
+ this.trigger('posterchange');
+
+ // Check if their is a high res
+ this.checkHighResPoster();
+ }
+ }
+
+ if (this.options_.autoplay && !_isOnMobile) {
+ if (this.isReady_) {
+ this.play();
+ } else {
+ this.playOnReady = true;
+ }
+ } else if (this.activeVideoId !== this.url.videoId) {
+ if (this.isReady_) {
+ this.cueVideoById_(this.url.videoId);
+ this.activeVideoId = this.url.videoId;
+ } else {
+ this.cueOnReady = true;
+ }
+ }
+ },
+
+ autoplay: function () {
+ return this.options_.autoplay;
+ },
+
+ setAutoplay: function (val) {
+ this.options_.autoplay = val;
+ },
+
+ loop: function () {
+ return this.options_.loop;
+ },
+
+ setLoop: function (val) {
+ this.options_.loop = val;
+ },
+
+ play: function () {
+ if (!this.url || !this.url.videoId) {
+ return;
+ }
+
+ this.wasPausedBeforeSeek = false;
+
+ if (this.isReady_) {
+ if (this.url.listId) {
+ if (this.activeList === this.url.listId) {
+ this.ytPlayer.playVideo();
+ } else {
+ this.ytPlayer.loadPlaylist(this.url.listId);
+ this.activeList = this.url.listId;
+ }
+ }
+
+ if (this.activeVideoId === this.url.videoId) {
+ this.ytPlayer.playVideo();
+ } else {
+ this.loadVideoById_(this.url.videoId);
+ this.activeVideoId = this.url.videoId;
+ }
+ } else {
+ this.trigger('waiting');
+ this.playOnReady = true;
+ }
+ },
+
+ pause: function () {
+ if (this.ytPlayer) {
+ this.ytPlayer.pauseVideo();
+ }
+ },
+
+ paused: function () {
+ return (this.ytPlayer) ?
+ (this.lastState !== YT.PlayerState.PLAYING && this.lastState !== YT.PlayerState.BUFFERING)
+ : true;
+ },
+
+ currentTime: function () {
+ return this.ytPlayer ? this.ytPlayer.getCurrentTime() : 0;
+ },
+
+ setCurrentTime: function (seconds) {
+ if (this.lastState === YT.PlayerState.PAUSED) {
+ this.timeBeforeSeek = this.currentTime();
+ }
+
+ if (!this.isSeeking) {
+ this.wasPausedBeforeSeek = this.paused();
+ }
+
+ this.ytPlayer.seekTo(seconds, true);
this.trigger('timeupdate');
- this.onSeeked();
- }
- }.bind(this), 250);
- }
- },
-
- seeking: function () {
- return this.isSeeking;
- },
-
- seekable: function () {
- if(!this.ytPlayer) {
- return videojs.createTimeRange();
- }
-
- return videojs.createTimeRange(0, this.ytPlayer.getDuration());
- },
-
- onSeeked: function() {
- clearInterval(this.checkSeekedInPauseInterval);
- this.isSeeking = false;
-
- if (this.wasPausedBeforeSeek) {
- this.pause();
- }
-
- this.trigger('seeked');
- },
-
- playbackRate: function() {
- return this.ytPlayer ? this.ytPlayer.getPlaybackRate() : 1;
- },
-
- setPlaybackRate: function(suggestedRate) {
- if (!this.ytPlayer) {
- return;
- }
-
- this.ytPlayer.setPlaybackRate(suggestedRate);
- },
-
- duration: function() {
- return this.ytPlayer ? this.ytPlayer.getDuration() : 0;
- },
-
- currentSrc: function() {
- return this.source && this.source.src;
- },
-
- ended: function() {
- return this.ytPlayer ? (this.lastState === YT.PlayerState.ENDED) : false;
- },
-
- volume: function() {
- return this.ytPlayer ? this.ytPlayer.getVolume() / 100.0 : 1;
- },
-
- setVolume: function(percentAsDecimal) {
- if (!this.ytPlayer) {
- return;
- }
-
- this.ytPlayer.setVolume(percentAsDecimal * 100.0);
- },
-
- muted: function() {
- return this.ytPlayer ? this.ytPlayer.isMuted() : false;
- },
-
- setMuted: function(mute) {
- if (!this.ytPlayer) {
- return;
- }
- else{
- this.muted(true);
- }
-
- if (mute) {
- this.ytPlayer.mute();
- } else {
- this.ytPlayer.unMute();
- }
- this.setTimeout( function(){
- this.trigger('volumechange');
- }, 50);
- },
-
- buffered: function() {
- if(!this.ytPlayer || !this.ytPlayer.getVideoLoadedFraction) {
- return videojs.createTimeRange();
- }
-
- var bufferedEnd = this.ytPlayer.getVideoLoadedFraction() * this.ytPlayer.getDuration();
-
- return videojs.createTimeRange(0, bufferedEnd);
- },
-
- // TODO: Can we really do something with this on YouTUbe?
- preload: function() {},
- load: function() {},
- reset: function() {},
-
- supportsFullScreen: function() {
- return true;
- },
-
- // Tries to get the highest resolution thumbnail available for the video
- checkHighResPoster: function(){
- var uri = 'https://img.youtube.com/vi/' + this.url.videoId + '/maxresdefault.jpg';
-
- try {
- var image = new Image();
- image.onload = function(){
- // Onload may still be called if YouTube returns the 120x90 error thumbnail
- if('naturalHeight' in image){
- if (image.naturalHeight <= 90 || image.naturalWidth <= 120) {
- return;
- }
- } else if(image.height <= 90 || image.width <= 120) {
- return;
- }
-
- this.poster_ = uri;
- this.trigger('posterchange');
- }.bind(this);
- image.onerror = function(){};
- image.src = uri;
- }
- catch(e){}
- }
- });
+ this.trigger('seeking');
+ this.isSeeking = true;
+
+ // A seek event during pause does not return an event to trigger a seeked event,
+ // so run an interval timer to look for the currentTime to change
+ if (this.lastState === YT.PlayerState.PAUSED && this.timeBeforeSeek !== seconds) {
+ clearInterval(this.checkSeekedInPauseInterval);
+ this.checkSeekedInPauseInterval = setInterval(function () {
+ if (this.lastState !== YT.PlayerState.PAUSED || !this.isSeeking) {
+ // If something changed while we were waiting for the currentTime to change,
+ // clear the interval timer
+ clearInterval(this.checkSeekedInPauseInterval);
+ } else if (this.currentTime() !== this.timeBeforeSeek) {
+ this.trigger('timeupdate');
+ this.onSeeked();
+ }
+ }.bind(this), 250);
+ }
+ },
- Youtube.isSupported = function() {
- return true;
- };
+ seeking: function () {
+ return this.isSeeking;
+ },
- Youtube.canPlaySource = function(e) {
- return Youtube.canPlayType(e.type);
- };
+ seekable: function () {
+ if (!this.ytPlayer) {
+ return videojs.createTimeRange();
+ }
- Youtube.canPlayType = function(e) {
- return (e === 'video/youtube');
- };
+ return videojs.createTimeRange(0, this.ytPlayer.getDuration());
+ },
- Youtube.parseUrl = function(url) {
- var result = {
- videoId: null
- };
+ onSeeked: function () {
+ clearInterval(this.checkSeekedInPauseInterval);
+ this.isSeeking = false;
- var regex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
- var match = url.match(regex);
+ if (this.wasPausedBeforeSeek) {
+ this.pause();
+ }
- if (match && match[2].length === 11) {
- result.videoId = match[2];
- }
+ this.trigger('seeked');
+ },
- var regPlaylist = /[?&]list=([^#\&\?]+)/;
- match = url.match(regPlaylist);
+ playbackRate: function () {
+ return this.ytPlayer ? this.ytPlayer.getPlaybackRate() : 1;
+ },
- if(match && match[1]) {
- result.listId = match[1];
- }
+ setPlaybackRate: function (suggestedRate) {
+ if (!this.ytPlayer) {
+ return;
+ }
+
+ this.ytPlayer.setPlaybackRate(suggestedRate);
+ },
+
+ duration: function () {
+ return this.ytPlayer ? this.ytPlayer.getDuration() : 0;
+ },
+
+ currentSrc: function () {
+ return this.source && this.source.src;
+ },
+
+ ended: function () {
+ return this.ytPlayer ? (this.lastState === YT.PlayerState.ENDED) : false;
+ },
+
+ volume: function () {
+ return this.ytPlayer ? this.ytPlayer.getVolume() / 100.0 : 1;
+ },
- return result;
- };
+ setVolume: function (percentAsDecimal) {
+ if (!this.ytPlayer) {
+ return;
+ }
+
+ this.ytPlayer.setVolume(percentAsDecimal * 100.0);
+ },
+
+ muted: function () {
+ return this.ytPlayer ? this.ytPlayer.isMuted() : false;
+ },
+
+ setMuted: function (mute) {
+ if (!this.ytPlayer) {
+ return;
+ } else {
+ this.muted(true);
+ }
- function apiLoaded() {
- YT.ready(function() {
- Youtube.isApiReady = true;
+ if (mute) {
+ this.ytPlayer.mute();
+ } else {
+ this.ytPlayer.unMute();
+ }
+ this.setTimeout(function () {
+ this.trigger('volumechange');
+ }, 50);
+ },
+
+ buffered: function () {
+ if (!this.ytPlayer || !this.ytPlayer.getVideoLoadedFraction) {
+ return videojs.createTimeRange();
+ }
- for (var i = 0; i < Youtube.apiReadyQueue.length; ++i) {
- Youtube.apiReadyQueue[i].initYTPlayer();
- }
+ var bufferedEnd = this.ytPlayer.getVideoLoadedFraction() * this.ytPlayer.getDuration();
+
+ return videojs.createTimeRange(0, bufferedEnd);
+ },
+
+ // TODO: Can we really do something with this on YouTUbe?
+ preload: function () {
+ },
+ load: function () {
+ },
+ reset: function () {
+ },
+
+ supportsFullScreen: function () {
+ return true;
+ },
+
+ // Tries to get the highest resolution thumbnail available for the video
+ checkHighResPoster: function () {
+ var uri = 'https://img.youtube.com/vi/' + this.url.videoId + '/maxresdefault.jpg';
+
+ try {
+ var image = new Image();
+ image.onload = function () {
+ // Onload may still be called if YouTube returns the 120x90 error thumbnail
+ if ('naturalHeight' in image) {
+ if (image.naturalHeight <= 90 || image.naturalWidth <= 120) {
+ return;
+ }
+ } else if (image.height <= 90 || image.width <= 120) {
+ return;
+ }
+
+ this.poster_ = uri;
+ this.trigger('posterchange');
+ }.bind(this);
+ image.onerror = function () {
+ };
+ image.src = uri;
+ } catch (e) {
+ }
+ }
});
- }
-
- function loadScript(src, callback) {
- var loaded = false;
- var tag = document.createElement('script');
- var firstScriptTag = document.getElementsByTagName('script')[0];
- firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
- tag.onload = function () {
- if (!loaded) {
- loaded = true;
- callback();
- }
+
+ Youtube.isSupported = function () {
+ return true;
};
- tag.onreadystatechange = function () {
- if (!loaded && (this.readyState === 'complete' || this.readyState === 'loaded')) {
- loaded = true;
- callback();
- }
+
+ Youtube.canPlaySource = function (e) {
+ return Youtube.canPlayType(e.type);
};
- tag.src = src;
- }
- function injectCss() {
- var css = // iframe blocker to catch mouse events
- '.vjs-youtube .vjs-iframe-blocker { display: none; }' +
- '.vjs-youtube.vjs-user-inactive .vjs-iframe-blocker { display: block; }' +
- '.vjs-youtube .vjs-poster { background-size: cover; }' +
- '.vjs-youtube-mobile .vjs-big-play-button { display: none; }';
+ Youtube.canPlayType = function (e) {
+ return (e === 'video/youtube');
+ };
- var head = document.head || document.getElementsByTagName('head')[0];
+ Youtube.parseUrl = function (url) {
+ var result = {
+ videoId: null
+ };
- var style = document.createElement('style');
- style.type = 'text/css';
+ var regex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
+ var match = url.match(regex);
- if (style.styleSheet){
- style.styleSheet.cssText = css;
- } else {
- style.appendChild(document.createTextNode(css));
+ if (match && match[2].length === 11) {
+ result.videoId = match[2];
+ }
+
+ var regPlaylist = /[?&]list=([^#\&\?]+)/;
+ match = url.match(regPlaylist);
+
+ if (match && match[1]) {
+ result.listId = match[1];
+ }
+
+ return result;
+ };
+
+ function apiLoaded() {
+ YT.ready(function () {
+ Youtube.isApiReady = true;
+
+ for (var i = 0; i < Youtube.apiReadyQueue.length; ++i) {
+ Youtube.apiReadyQueue[i].initYTPlayer();
+ }
+ });
+ }
+
+ function loadScript(src, callback) {
+ var loaded = false;
+ var tag = document.createElement('script');
+ var firstScriptTag = document.getElementsByTagName('script')[0];
+ firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
+ tag.onload = function () {
+ if (!loaded) {
+ loaded = true;
+ callback();
+ }
+ };
+ tag.onreadystatechange = function () {
+ if (!loaded && (this.readyState === 'complete' || this.readyState === 'loaded')) {
+ loaded = true;
+ callback();
+ }
+ };
+ tag.src = src;
}
- head.appendChild(style);
- }
+ function injectCss() {
+ var css = // iframe blocker to catch mouse events
+ '.vjs-youtube .vjs-iframe-blocker { display: none; }' +
+ '.vjs-youtube.vjs-user-inactive .vjs-iframe-blocker { display: block; }' +
+ '.vjs-youtube .vjs-poster { background-size: cover; }' +
+ '.vjs-youtube-mobile .vjs-big-play-button { display: none; }';
- Youtube.apiReadyQueue = [];
+ var head = document.head || document.getElementsByTagName('head')[0];
- if (typeof document !== 'undefined'){
- loadScript('https://www.youtube.com/iframe_api', apiLoaded);
- injectCss();
- }
+ var style = document.createElement('style');
+ style.type = 'text/css';
- // Older versions of VJS5 doesn't have the registerTech function
- if (typeof videojs.registerTech !== 'undefined') {
- videojs.registerTech('Youtube', Youtube);
- } else {
- videojs.registerComponent('Youtube', Youtube);
- }
+ if (style.styleSheet) {
+ style.styleSheet.cssText = css;
+ } else {
+ style.appendChild(document.createTextNode(css));
+ }
+
+ head.appendChild(style);
+ }
+
+ Youtube.apiReadyQueue = [];
+
+ if (typeof document !== 'undefined') {
+ loadScript('https://www.youtube.com/iframe_api', apiLoaded);
+ injectCss();
+ }
+
+ // Older versions of VJS5 doesn't have the registerTech function
+ if (typeof videojs.registerTech !== 'undefined') {
+ videojs.registerTech('Youtube', Youtube);
+ } else {
+ videojs.registerComponent('Youtube', Youtube);
+ }
}));
-videojs.addLanguage("ar",{
- "Play": "تشغيل",
- "Pause": "إيقاف",
- "Current Time": "الوقت الحالي",
- "Duration Time": "مدة",
- "Remaining Time": "الوقت المتبقي",
- "Stream Type": "نوع التيار",
- "LIVE": "مباشر",
- "Loaded": "تم التحميل",
- "Progress": "التقدم",
- "Fullscreen": "ملء الشاشة",
- "Non-Fullscreen": "تعطيل ملء الشاشة",
- "Mute": "صامت",
- "Unmute": "غير الصامت",
- "Playback Rate": "معدل التشغيل",
- "Subtitles": "الترجمة",
- "subtitles off": "إيقاف الترجمة",
- "Captions": "التعليقات",
- "captions off": "إيقاف التعليقات",
- "Chapters": "فصول",
- "You aborted the media playback": "لقد ألغيت تشغيل الفيديو",
- "A network error caused the media download to fail part-way.": "تسبب خطأ في الشبكة بفشل تحميل الفيديو بالكامل.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "لا يمكن تحميل الفيديو بسبب فشل في الخادوم أو الشبكة ، أو فشل بسبب عدم إمكانية قراءة تنسيق الفيديو.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "تم إيقاف تشغيل الفيديو بسبب مشكلة فساد أو لأن الفيديو المستخدم يستخدم ميزات غير مدعومة من متصفحك.",
- "No compatible source was found for this media.": "فشل العثور على أي مصدر متوافق مع هذا الفيديو.",
- "Play Video": "تشغيل الفيديو",
- "Close": "أغلق",
- "Modal Window": "نافذة مشروطة",
- "This is a modal window": "هذه نافذة مشروطة",
- "This modal can be closed by pressing the Escape key or activating the close button.": "يمكن غلق هذه النافذة المشروطة عن طريق الضغط على زر الخروج أو تفعيل زر الإغلاق",
- ", opens captions settings dialog": ", تفتح نافذة خيارات التعليقات",
- ", opens subtitles settings dialog": ", تفتح نافذة خيارات الترجمة",
- ", selected": ", مختار"
+videojs.addLanguage('ar', {
+ "Play": "تشغيل",
+ "Pause": "إيقاف",
+ "Current Time": "الوقت الحالي",
+ "Duration": "مدة",
+ "Remaining Time": "الوقت المتبقي",
+ "Stream Type": "نوع التيار",
+ "LIVE": "مباشر",
+ "Loaded": "تم التحميل",
+ "Progress": "التقدم",
+ "Fullscreen": "ملء الشاشة",
+ "Non-Fullscreen": "تعطيل ملء الشاشة",
+ "Mute": "صامت",
+ "Unmute": "غير الصامت",
+ "Playback Rate": "معدل التشغيل",
+ "Subtitles": "الترجمة",
+ "subtitles off": "إيقاف الترجمة",
+ "Captions": "التعليقات",
+ "captions off": "إيقاف التعليقات",
+ "Chapters": "فصول",
+ "You aborted the media playback": "لقد ألغيت تشغيل الفيديو",
+ "A network error caused the media download to fail part-way.": "تسبب خطأ في الشبكة بفشل تحميل الفيديو بالكامل.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "لا يمكن تحميل الفيديو بسبب فشل في الخادوم أو الشبكة ، أو فشل بسبب عدم إمكانية قراءة تنسيق الفيديو.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "تم إيقاف تشغيل الفيديو بسبب مشكلة فساد أو لأن الفيديو المستخدم يستخدم ميزات غير مدعومة من متصفحك.",
+ "No compatible source was found for this media.": "فشل العثور على أي مصدر متوافق مع هذا الفيديو.",
+ "Play Video": "تشغيل الفيديو",
+ "Close": "أغلق",
+ "Modal Window": "نافذة مشروطة",
+ "This is a modal window": "هذه نافذة مشروطة",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "يمكن غلق هذه النافذة المشروطة عن طريق الضغط على زر الخروج أو تفعيل زر الإغلاق",
+ ", opens captions settings dialog": ", تفتح نافذة خيارات التعليقات",
+ ", opens subtitles settings dialog": ", تفتح نافذة خيارات الترجمة",
+ ", selected": ", مختار",
+ "Audio Player": "مشغل الصوت",
+ "Video Player": "مشغل الفيديو",
+ "Replay": "إعادة التشغيل",
+ "Seek to live, currently behind live": "ذهاب إلى نقطة البث المباشر، متأخر عن البث المباشر حاليًا",
+ "Seek to live, currently playing live": "ذهاب إلى نقطة البث المباشر، البث المباشر قيد التشغيل حاليًا",
+ "Progress Bar": "شريط التقدم",
+ "Descriptions": "الأوصاف",
+ "descriptions off": "إخفاء الأوصاف",
+ "Audio Track": "المسار الصوتي",
+ "Volume Level": "مستوى الصوت",
+ "The media is encrypted and we do not have the keys to decrypt it.": "الوسائط مشفرة وليس لدينا الرموز اللازمة لفك شفرتها.",
+ "Close Modal Dialog": "إغلاق مربع الحوار المشروط",
+ ", opens descriptions settings dialog": "، يفتح مربع حوار إعدادات الأوصاف",
+ "captions settings": "إعدادات التعليقات التوضيحية",
+ "subtitles settings": "إعدادات الترجمات",
+ "descriptions settings": "إعدادات الأوصاف",
+ "Text": "النص",
+ "White": "أبيض",
+ "Black": "أسود",
+ "Red": "أحمر",
+ "Green": "أخضر",
+ "Blue": "أزرق",
+ "Yellow": "أصفر",
+ "Magenta": "أرجواني",
+ "Cyan": "أزرق سماوي",
+ "Background": "الخلفية",
+ "Window": "نافذة",
+ "Transparent": "شفاف",
+ "Semi-Transparent": "نصف شفاف",
+ "Opaque": "معتم",
+ "Font Size": "حجم الخط",
+ "Text Edge Style": "نمط حواف النص",
+ "None": "لا شيء",
+ "Raised": "بارز",
+ "Depressed": "منخفض",
+ "Uniform": "منتظم",
+ "Dropshadow": "ظل خلفي",
+ "Font Family": "عائلة الخطوط",
+ "Proportional Sans-Serif": "Proportional Sans-Serif",
+ "Monospace Sans-Serif": "Monospace Sans-Serif",
+ "Proportional Serif": "Proportional Serif",
+ "Monospace Serif": "Monospace Serif",
+ "Casual": "Casual",
+ "Script": "Script",
+ "Small Caps": "Small Caps",
+ "Reset": "إعادة الضبط",
+ "restore all settings to the default values": "استعادة كل الإعدادات إلى القيم الافتراضية",
+ "Done": "تم",
+ "Caption Settings Dialog": "مربع حوار إعدادات التعليقات التوضيحية",
+ "Beginning of dialog window. Escape will cancel and close the window.": "بداية نافذة مربع حوار. الضغط على زر \"Escape\" سيؤدي إلى الإلغاء وإغلاق النافذة.",
+ "End of dialog window.": "نهاية نافذة مربع حوار.",
+ "{1} is loading.": "{1} قيد التحميل."
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "تشغيل",
+ "Pause": "إيقاف",
+ "Current Time": "الوقت الحالي",
+ "Duration": "مدة",
+ "Remaining Time": "الوقت المتبقي",
+ "Stream Type": "نوع التيار",
+ "LIVE": "مباشر",
+ "Loaded": "تم التحميل",
+ "Progress": "التقدم",
+ "Fullscreen": "ملء الشاشة",
+ "Non-Fullscreen": "تعطيل ملء الشاشة",
+ "Mute": "صامت",
+ "Unmute": "غير الصامت",
+ "Playback Rate": "معدل التشغيل",
+ "Subtitles": "الترجمة",
+ "subtitles off": "إيقاف الترجمة",
+ "Captions": "التعليقات",
+ "captions off": "إيقاف التعليقات",
+ "Chapters": "فصول",
+ "You aborted the media playback": "لقد ألغيت تشغيل الفيديو",
+ "A network error caused the media download to fail part-way.": "تسبب خطأ في الشبكة بفشل تحميل الفيديو بالكامل.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "لا يمكن تحميل الفيديو بسبب فشل في الخادوم أو الشبكة ، أو فشل بسبب عدم إمكانية قراءة تنسيق الفيديو.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "تم إيقاف تشغيل الفيديو بسبب مشكلة فساد أو لأن الفيديو المستخدم يستخدم ميزات غير مدعومة من متصفحك.",
+ "No compatible source was found for this media.": "فشل العثور على أي مصدر متوافق مع هذا الفيديو.",
+ "Play Video": "تشغيل الفيديو",
+ "Close": "أغلق",
+ "Modal Window": "نافذة مشروطة",
+ "This is a modal window": "هذه نافذة مشروطة",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "يمكن غلق هذه النافذة المشروطة عن طريق الضغط على زر الخروج أو تفعيل زر الإغلاق",
+ ", opens captions settings dialog": ", تفتح نافذة خيارات التعليقات",
+ ", opens subtitles settings dialog": ", تفتح نافذة خيارات الترجمة",
+ ", selected": ", مختار",
+ "Audio Player": "مشغل الصوت",
+ "Video Player": "مشغل الفيديو",
+ "Replay": "إعادة التشغيل",
+ "Seek to live, currently behind live": "ذهاب إلى نقطة البث المباشر، متأخر عن البث المباشر حاليًا",
+ "Seek to live, currently playing live": "ذهاب إلى نقطة البث المباشر، البث المباشر قيد التشغيل حاليًا",
+ "Progress Bar": "شريط التقدم",
+ "Descriptions": "الأوصاف",
+ "descriptions off": "إخفاء الأوصاف",
+ "Audio Track": "المسار الصوتي",
+ "Volume Level": "مستوى الصوت",
+ "The media is encrypted and we do not have the keys to decrypt it.": "الوسائط مشفرة وليس لدينا الرموز اللازمة لفك شفرتها.",
+ "Close Modal Dialog": "إغلاق مربع الحوار المشروط",
+ ", opens descriptions settings dialog": "، يفتح مربع حوار إعدادات الأوصاف",
+ "captions settings": "إعدادات التعليقات التوضيحية",
+ "subtitles settings": "إعدادات الترجمات",
+ "descriptions settings": "إعدادات الأوصاف",
+ "Text": "النص",
+ "White": "أبيض",
+ "Black": "أسود",
+ "Red": "أحمر",
+ "Green": "أخضر",
+ "Blue": "أزرق",
+ "Yellow": "أصفر",
+ "Magenta": "أرجواني",
+ "Cyan": "أزرق سماوي",
+ "Background": "الخلفية",
+ "Window": "نافذة",
+ "Transparent": "شفاف",
+ "Semi-Transparent": "نصف شفاف",
+ "Opaque": "معتم",
+ "Font Size": "حجم الخط",
+ "Text Edge Style": "نمط حواف النص",
+ "None": "لا شيء",
+ "Raised": "بارز",
+ "Depressed": "منخفض",
+ "Uniform": "منتظم",
+ "Dropshadow": "ظل خلفي",
+ "Font Family": "عائلة الخطوط",
+ "Proportional Sans-Serif": "Proportional Sans-Serif",
+ "Monospace Sans-Serif": "Monospace Sans-Serif",
+ "Proportional Serif": "Proportional Serif",
+ "Monospace Serif": "Monospace Serif",
+ "Casual": "Casual",
+ "Script": "Script",
+ "Small Caps": "Small Caps",
+ "Reset": "إعادة الضبط",
+ "restore all settings to the default values": "استعادة كل الإعدادات إلى القيم الافتراضية",
+ "Done": "تم",
+ "Caption Settings Dialog": "مربع حوار إعدادات التعليقات التوضيحية",
+ "Beginning of dialog window. Escape will cancel and close the window.": "بداية نافذة مربع حوار. الضغط على زر \"Escape\" سيؤدي إلى الإلغاء وإغلاق النافذة.",
+ "End of dialog window.": "نهاية نافذة مربع حوار.",
+ "{1} is loading.": "{1} قيد التحميل."
+}
-videojs.addLanguage("ba",{
- "Play": "Pusti",
- "Pause": "Pauza",
- "Current Time": "Trenutno vrijeme",
- "Duration Time": "Vrijeme trajanja",
- "Remaining Time": "Preostalo vrijeme",
- "Stream Type": "Način strimovanja",
- "LIVE": "UŽIVO",
- "Loaded": "Učitan",
- "Progress": "Progres",
- "Fullscreen": "Puni ekran",
- "Non-Fullscreen": "Mali ekran",
- "Mute": "Prigušen",
- "Unmute": "Ne-prigušen",
- "Playback Rate": "Stopa reprodukcije",
- "Subtitles": "Podnaslov",
- "subtitles off": "Podnaslov deaktiviran",
- "Captions": "Titlovi",
- "captions off": "Titlovi deaktivirani",
- "Chapters": "Poglavlja",
- "You aborted the media playback": "Isključili ste reprodukciju videa.",
- "A network error caused the media download to fail part-way.": "Video se prestao preuzimati zbog greške na mreži.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video se ne može reproducirati zbog servera, greške u mreži ili je format ne podržan.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Reprodukcija videa je zaustavljenja zbog greške u formatu ili zbog verzije vašeg pretraživača.",
- "No compatible source was found for this media.": "Nije nađen nijedan kompatibilan izvor ovog videa."
+videojs.addLanguage('ba', {
+ "Play": "Pusti",
+ "Pause": "Pauza",
+ "Current Time": "Trenutno vrijeme",
+ "Duration": "Vrijeme trajanja",
+ "Remaining Time": "Preostalo vrijeme",
+ "Stream Type": "Način strimovanja",
+ "LIVE": "UŽIVO",
+ "Loaded": "Učitan",
+ "Progress": "Progres",
+ "Fullscreen": "Puni ekran",
+ "Non-Fullscreen": "Mali ekran",
+ "Mute": "Prigušen",
+ "Unmute": "Ne-prigušen",
+ "Playback Rate": "Stopa reprodukcije",
+ "Subtitles": "Podnaslov",
+ "subtitles off": "Podnaslov deaktiviran",
+ "Captions": "Titlovi",
+ "captions off": "Titlovi deaktivirani",
+ "Chapters": "Poglavlja",
+ "You aborted the media playback": "Isključili ste reprodukciju videa.",
+ "A network error caused the media download to fail part-way.": "Video se prestao preuzimati zbog greške na mreži.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video se ne može reproducirati zbog servera, greške u mreži ili je format ne podržan.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Reprodukcija videa je zaustavljenja zbog greške u formatu ili zbog verzije vašeg pretraživača.",
+ "No compatible source was found for this media.": "Nije nađen nijedan kompatibilan izvor ovog videa."
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Pusti",
+ "Pause": "Pauza",
+ "Current Time": "Trenutno vrijeme",
+ "Duration": "Vrijeme trajanja",
+ "Remaining Time": "Preostalo vrijeme",
+ "Stream Type": "Način strimovanja",
+ "LIVE": "UŽIVO",
+ "Loaded": "Učitan",
+ "Progress": "Progres",
+ "Fullscreen": "Puni ekran",
+ "Non-Fullscreen": "Mali ekran",
+ "Mute": "Prigušen",
+ "Unmute": "Ne-prigušen",
+ "Playback Rate": "Stopa reprodukcije",
+ "Subtitles": "Podnaslov",
+ "subtitles off": "Podnaslov deaktiviran",
+ "Captions": "Titlovi",
+ "captions off": "Titlovi deaktivirani",
+ "Chapters": "Poglavlja",
+ "You aborted the media playback": "Isključili ste reprodukciju videa.",
+ "A network error caused the media download to fail part-way.": "Video se prestao preuzimati zbog greške na mreži.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video se ne može reproducirati zbog servera, greške u mreži ili je format ne podržan.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Reprodukcija videa je zaustavljenja zbog greške u formatu ili zbog verzije vašeg pretraživača.",
+ "No compatible source was found for this media.": "Nije nađen nijedan kompatibilan izvor ovog videa."
+}
-videojs.addLanguage("bg",{
- "Play": "Възпроизвеждане",
- "Pause": "Пауза",
- "Current Time": "Текущо време",
- "Duration Time": "Продължителност",
- "Remaining Time": "Оставащо време",
- "Stream Type": "Тип на потока",
- "LIVE": "НА ЖИВО",
- "Loaded": "Заредено",
- "Progress": "Прогрес",
- "Fullscreen": "Цял екран",
- "Non-Fullscreen": "Спиране на цял екран",
- "Mute": "Без звук",
- "Unmute": "Със звук",
- "Playback Rate": "Скорост на възпроизвеждане",
- "Subtitles": "Субтитри",
- "subtitles off": "Спряни субтитри",
- "Captions": "Аудио надписи",
- "captions off": "Спряни аудио надписи",
- "Chapters": "Глави",
- "You aborted the media playback": "Спряхте възпроизвеждането на видеото",
- "A network error caused the media download to fail part-way.": "Грешка в мрежата провали изтеглянето на видеото.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Видеото не може да бъде заредено заради проблем със сървъра или мрежата или защото този формат не е поддържан.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Възпроизвеждането на видеото беше прекъснато заради проблем с файла или защото видеото използва опции които браузърът Ви не поддържа.",
- "No compatible source was found for this media.": "Не беше намерен съвместим източник за това видео."
+videojs.addLanguage('bg', {
+ "Play": "Възпроизвеждане",
+ "Pause": "Пауза",
+ "Current Time": "Текущо време",
+ "Duration": "Продължителност",
+ "Remaining Time": "Оставащо време",
+ "Stream Type": "Тип на потока",
+ "LIVE": "НА ЖИВО",
+ "Loaded": "Заредено",
+ "Progress": "Прогрес",
+ "Fullscreen": "Цял екран",
+ "Non-Fullscreen": "Спиране на цял екран",
+ "Mute": "Без звук",
+ "Unmute": "Със звук",
+ "Playback Rate": "Скорост на възпроизвеждане",
+ "Subtitles": "Субтитри",
+ "subtitles off": "Спряни субтитри",
+ "Captions": "Аудио надписи",
+ "captions off": "Спряни аудио надписи",
+ "Chapters": "Глави",
+ "You aborted the media playback": "Спряхте възпроизвеждането на видеото",
+ "A network error caused the media download to fail part-way.": "Грешка в мрежата провали изтеглянето на видеото.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Видеото не може да бъде заредено заради проблем със сървъра или мрежата или защото този формат не е поддържан.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Възпроизвеждането на видеото беше прекъснато заради проблем с файла или защото видеото използва опции които браузърът Ви не поддържа.",
+ "No compatible source was found for this media.": "Не беше намерен съвместим източник за това видео."
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Възпроизвеждане",
+ "Pause": "Пауза",
+ "Current Time": "Текущо време",
+ "Duration": "Продължителност",
+ "Remaining Time": "Оставащо време",
+ "Stream Type": "Тип на потока",
+ "LIVE": "НА ЖИВО",
+ "Loaded": "Заредено",
+ "Progress": "Прогрес",
+ "Fullscreen": "Цял екран",
+ "Non-Fullscreen": "Спиране на цял екран",
+ "Mute": "Без звук",
+ "Unmute": "Със звук",
+ "Playback Rate": "Скорост на възпроизвеждане",
+ "Subtitles": "Субтитри",
+ "subtitles off": "Спряни субтитри",
+ "Captions": "Аудио надписи",
+ "captions off": "Спряни аудио надписи",
+ "Chapters": "Глави",
+ "You aborted the media playback": "Спряхте възпроизвеждането на видеото",
+ "A network error caused the media download to fail part-way.": "Грешка в мрежата провали изтеглянето на видеото.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Видеото не може да бъде заредено заради проблем със сървъра или мрежата или защото този формат не е поддържан.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Възпроизвеждането на видеото беше прекъснато заради проблем с файла или защото видеото използва опции които браузърът Ви не поддържа.",
+ "No compatible source was found for this media.": "Не беше намерен съвместим източник за това видео."
+}
-videojs.addLanguage("ca",{
- "Play": "Reproducció",
- "Pause": "Pausa",
- "Current Time": "Temps reproduït",
- "Duration Time": "Durada total",
- "Remaining Time": "Temps restant",
- "Stream Type": "Tipus de seqüència",
- "LIVE": "EN DIRECTE",
- "Loaded": "Carregat",
- "Progress": "Progrés",
- "Fullscreen": "Pantalla completa",
- "Non-Fullscreen": "Pantalla no completa",
- "Mute": "Silencia",
- "Unmute": "Amb so",
- "Playback Rate": "Velocitat de reproducció",
- "Subtitles": "Subtítols",
- "subtitles off": "Subtítols desactivats",
- "Captions": "Llegendes",
- "captions off": "Llegendes desactivades",
- "Chapters": "Capítols",
- "You aborted the media playback": "Heu interromput la reproducció del vídeo.",
- "A network error caused the media download to fail part-way.": "Un error de la xarxa ha interromput la baixada del vídeo.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "No s'ha pogut carregar el vídeo perquè el servidor o la xarxa han fallat, o bé perquè el seu format no és compatible.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La reproducció de vídeo s'ha interrumput per un problema de corrupció de dades o bé perquè el vídeo demanava funcions que el vostre navegador no ofereix.",
- "No compatible source was found for this media.": "No s'ha trobat cap font compatible amb el vídeo."
+videojs.addLanguage('ca', {
+ "Play": "Reproducció",
+ "Pause": "Pausa",
+ "Current Time": "Temps reproduït",
+ "Duration": "Durada total",
+ "Remaining Time": "Temps restant",
+ "Stream Type": "Tipus de seqüència",
+ "LIVE": "EN DIRECTE",
+ "Loaded": "Carregat",
+ "Progress": "Progrés",
+ "Fullscreen": "Pantalla completa",
+ "Non-Fullscreen": "Pantalla no completa",
+ "Mute": "Silencia",
+ "Unmute": "Amb so",
+ "Playback Rate": "Velocitat de reproducció",
+ "Subtitles": "Subtítols",
+ "subtitles off": "Subtítols desactivats",
+ "Captions": "Llegendes",
+ "captions off": "Llegendes desactivades",
+ "Chapters": "Capítols",
+ "You aborted the media playback": "Heu interromput la reproducció del vídeo.",
+ "A network error caused the media download to fail part-way.": "Un error de la xarxa ha interromput la baixada del vídeo.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "No s'ha pogut carregar el vídeo perquè el servidor o la xarxa han fallat, o bé perquè el seu format no és compatible.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La reproducció de vídeo s'ha interrumput per un problema de corrupció de dades o bé perquè el vídeo demanava funcions que el vostre navegador no ofereix.",
+ "No compatible source was found for this media.": "No s'ha trobat cap font compatible amb el vídeo."
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Reproducció",
+ "Pause": "Pausa",
+ "Current Time": "Temps reproduït",
+ "Duration": "Durada total",
+ "Remaining Time": "Temps restant",
+ "Stream Type": "Tipus de seqüència",
+ "LIVE": "EN DIRECTE",
+ "Loaded": "Carregat",
+ "Progress": "Progrés",
+ "Fullscreen": "Pantalla completa",
+ "Non-Fullscreen": "Pantalla no completa",
+ "Mute": "Silencia",
+ "Unmute": "Amb so",
+ "Playback Rate": "Velocitat de reproducció",
+ "Subtitles": "Subtítols",
+ "subtitles off": "Subtítols desactivats",
+ "Captions": "Llegendes",
+ "captions off": "Llegendes desactivades",
+ "Chapters": "Capítols",
+ "You aborted the media playback": "Heu interromput la reproducció del vídeo.",
+ "A network error caused the media download to fail part-way.": "Un error de la xarxa ha interromput la baixada del vídeo.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "No s'ha pogut carregar el vídeo perquè el servidor o la xarxa han fallat, o bé perquè el seu format no és compatible.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La reproducció de vídeo s'ha interrumput per un problema de corrupció de dades o bé perquè el vídeo demanava funcions que el vostre navegador no ofereix.",
+ "No compatible source was found for this media.": "No s'ha trobat cap font compatible amb el vídeo."
+}
-videojs.addLanguage("cs",{
- "Play": "Přehrát",
- "Pause": "Pauza",
- "Current Time": "Aktuální čas",
- "Duration Time": "Doba trvání",
- "Remaining Time": "Zbývající čas",
- "Stream Type": "Stream Type",
- "LIVE": "ŽIVĚ",
- "Loaded": "Načteno",
- "Progress": "Stav",
- "Fullscreen": "Celá obrazovka",
- "Non-Fullscreen": "Zmenšená obrazovka",
- "Mute": "Ztlumit zvuk",
- "Unmute": "Přehrát zvuk",
- "Playback Rate": "Rychlost přehrávání",
- "Subtitles": "Titulky",
- "subtitles off": "Titulky vypnuty",
- "Captions": "Popisky",
- "captions off": "Popisky vypnuty",
- "Chapters": "Kapitoly",
- "You aborted the media playback": "Přehrávání videa je přerušeno.",
- "A network error caused the media download to fail part-way.": "Video nemohlo být načteno, kvůli chybě v síti.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video nemohlo být načteno, buď kvůli chybě serveru nebo sítě nebo proto, že daný formát není podporován.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Váš prohlížeč nepodporuje formát videa.",
- "No compatible source was found for this media.": "Špatně zadaný zdroj videa."
+videojs.addLanguage('cs', {
+ "Audio Player": "Audio Přehravač",
+ "Video Player": "Video Přehravač",
+ "Play": "Přehrát",
+ "Pause": "Pauza",
+ "Replay": "Spustit znovu",
+ "Current Time": "Aktuální čas",
+ "Duration": "Doba trvání",
+ "Remaining Time": "Zbývající čas",
+ "Stream Type": "Typ streamu",
+ "LIVE": "ŽIVĚ",
+ "Loaded": "Načteno",
+ "Progress": "Stav",
+ "Progress Bar": "Ukazatel průběhu",
+ "progress bar timing: currentTime={1} duration={2}": "{1} z {2}",
+ "Fullscreen": "Celá obrazovka",
+ "Non-Fullscreen": "Běžné zobrazení",
+ "Mute": "Ztlumit zvuk",
+ "Unmute": "Zapnout zvuk",
+ "Playback Rate": "Rychlost přehrávání",
+ "Subtitles": "Titulky",
+ "subtitles off": "Bez titulků",
+ "Captions": "Popisky",
+ "captions off": "Popisky vypnuty",
+ "Chapters": "Kapitoly",
+ "Descriptions": "Popisy",
+ "descriptions off": "Bez popisů",
+ "Audio Track": "Zvuková stopa",
+ "Volume Level": "Hlasitost",
+ "You aborted the media playback": "Přehrávání videa bylo přerušeno.",
+ "A network error caused the media download to fail part-way.": "Video nemohlo být načteno kvůli chybě v síti.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video nemohlo být načteno, buď kvůli chybě serveru, sítě nebo proto, že daný formát není podporován.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Váš prohlížeč nepodporuje tento formát videa.",
+ "No compatible source was found for this media.": "Nevalidní zadaný zdroj videa.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Chyba při dešifrování videa.",
+ "Play Video": "Přehrát video",
+ "Close": "Zavřit",
+ "Close Modal Dialog": "Zavřít okno",
+ "Modal Window": "Modální okno",
+ "This is a modal window": "Toto je modální okno",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Toto okno se dá zavřít křížkem nebo klávesou Esc.",
+ ", opens captions settings dialog": ", otevřít okno pro nastavení popisků",
+ ", opens subtitles settings dialog": ", otevřít okno pro nastavení titulků",
+ ", opens descriptions settings dialog": ", otevře okno pro nastavení popisků pro nevidomé",
+ ", selected": ", vybráno",
+ "captions settings": "nastavení popisků",
+ "subtitles settings": "nastavení titulků",
+ "descriptions settings": "nastavení popisků pro nevidomé",
+ "Text": "Titulky",
+ "White": "Bílé",
+ "Black": "Černé",
+ "Red": "Červené",
+ "Green": "Zelené",
+ "Blue": "Modré",
+ "Yellow": "Žluté",
+ "Magenta": "Fialové",
+ "Cyan": "Azurové",
+ "Background": "Pozadí titulků",
+ "Window": "Okno",
+ "Transparent": "Průhledné",
+ "Semi-Transparent": "Poloprůhledné",
+ "Opaque": "Neprůhledné",
+ "Font Size": "Velikost písma",
+ "Text Edge Style": "Okraje písma",
+ "None": "Bez okraje",
+ "Raised": "Zvýšený",
+ "Depressed": "Propadlý",
+ "Uniform": "Rovnoměrný",
+ "Dropshadow": "Stínovaný",
+ "Font Family": "Rodina písma",
+ "Proportional Sans-Serif": "Proporcionální bezpatkové",
+ "Monospace Sans-Serif": "Monospace bezpatkové",
+ "Proportional Serif": "Proporcionální patkové",
+ "Monospace Serif": "Monospace patkové",
+ "Casual": "Hravé",
+ "Script": "Ručně psané",
+ "Small Caps": "Malé kapitálky",
+ "Reset": "Obnovit",
+ "restore all settings to the default values": "Vrátit nastavení do výchozího stavu",
+ "Done": "Hotovo",
+ "Caption Settings Dialog": "Okno s nastavením titulků",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Začátek dialogového okna. Klávesa Esc okno zavře.",
+ "End of dialog window.": "Konec dialogového okna.",
+ "{1} is loading.": "{1} se načítá."
});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Audio Přehravač",
+ "Video Player": "Video Přehravač",
+ "Play": "Přehrát",
+ "Pause": "Pauza",
+ "Replay": "Spustit znovu",
+ "Current Time": "Aktuální čas",
+ "Duration": "Doba trvání",
+ "Remaining Time": "Zbývající čas",
+ "Stream Type": "Typ streamu",
+ "LIVE": "ŽIVĚ",
+ "Loaded": "Načteno",
+ "Progress": "Stav",
+ "Progress Bar": "Ukazatel průběhu",
+ "progress bar timing: currentTime={1} duration={2}": "{1} z {2}",
+ "Fullscreen": "Celá obrazovka",
+ "Non-Fullscreen": "Běžné zobrazení",
+ "Mute": "Ztlumit zvuk",
+ "Unmute": "Zapnout zvuk",
+ "Playback Rate": "Rychlost přehrávání",
+ "Subtitles": "Titulky",
+ "subtitles off": "Bez titulků",
+ "Captions": "Popisky",
+ "captions off": "Popisky vypnuty",
+ "Chapters": "Kapitoly",
+ "Descriptions": "Popisy",
+ "descriptions off": "Bez popisů",
+ "Audio Track": "Zvuková stopa",
+ "Volume Level": "Hlasitost",
+ "You aborted the media playback": "Přehrávání videa bylo přerušeno.",
+ "A network error caused the media download to fail part-way.": "Video nemohlo být načteno kvůli chybě v síti.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video nemohlo být načteno, buď kvůli chybě serveru, sítě nebo proto, že daný formát není podporován.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Váš prohlížeč nepodporuje tento formát videa.",
+ "No compatible source was found for this media.": "Nevalidní zadaný zdroj videa.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Chyba při dešifrování videa.",
+ "Play Video": "Přehrát video",
+ "Close": "Zavřit",
+ "Close Modal Dialog": "Zavřít okno",
+ "Modal Window": "Modální okno",
+ "This is a modal window": "Toto je modální okno",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Toto okno se dá zavřít křížkem nebo klávesou Esc.",
+ ", opens captions settings dialog": ", otevřít okno pro nastavení popisků",
+ ", opens subtitles settings dialog": ", otevřít okno pro nastavení titulků",
+ ", opens descriptions settings dialog": ", otevře okno pro nastavení popisků pro nevidomé",
+ ", selected": ", vybráno",
+ "captions settings": "nastavení popisků",
+ "subtitles settings": "nastavení titulků",
+ "descriptions settings": "nastavení popisků pro nevidomé",
+ "Text": "Titulky",
+ "White": "Bílé",
+ "Black": "Černé",
+ "Red": "Červené",
+ "Green": "Zelené",
+ "Blue": "Modré",
+ "Yellow": "Žluté",
+ "Magenta": "Fialové",
+ "Cyan": "Azurové",
+ "Background": "Pozadí titulků",
+ "Window": "Okno",
+ "Transparent": "Průhledné",
+ "Semi-Transparent": "Poloprůhledné",
+ "Opaque": "Neprůhledné",
+ "Font Size": "Velikost písma",
+ "Text Edge Style": "Okraje písma",
+ "None": "Bez okraje",
+ "Raised": "Zvýšený",
+ "Depressed": "Propadlý",
+ "Uniform": "Rovnoměrný",
+ "Dropshadow": "Stínovaný",
+ "Font Family": "Rodina písma",
+ "Proportional Sans-Serif": "Proporcionální bezpatkové",
+ "Monospace Sans-Serif": "Monospace bezpatkové",
+ "Proportional Serif": "Proporcionální patkové",
+ "Monospace Serif": "Monospace patkové",
+ "Casual": "Hravé",
+ "Script": "Ručně psané",
+ "Small Caps": "Malé kapitálky",
+ "Reset": "Obnovit",
+ "restore all settings to the default values": "Vrátit nastavení do výchozího stavu",
+ "Done": "Hotovo",
+ "Caption Settings Dialog": "Okno s nastavením titulků",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Začátek dialogového okna. Klávesa Esc okno zavře.",
+ "End of dialog window.": "Konec dialogového okna.",
+ "{1} is loading.": "{1} se načítá."
+}
--- /dev/null
+videojs.addLanguage('cy', {
+ "Audio Player": "Chwaraewr sain",
+ "Video Player": "Chwaraewr fideo",
+ "Play": "Chwarae",
+ "Pause": "Oedi",
+ "Replay": "Ailchwarae",
+ "Current Time": "Amser Cyfredol",
+ "Duration": "Parhad",
+ "Remaining Time": "Amser ar ôl",
+ "Stream Type": "Math o Ffrwd",
+ "LIVE": "YN FYW",
+ "Loaded": "Llwythwyd",
+ "Progress": "Cynnydd",
+ "Progress Bar": "Bar Cynnydd",
+ "progress bar timing: currentTime={1} duration={2}": "{1} o {2}",
+ "Fullscreen": "Sgrîn Lawn",
+ "Non-Fullscreen": "Ffenestr",
+ "Mute": "Pylu",
+ "Unmute": "Dad-bylu",
+ "Playback Rate": "Cyfradd Chwarae",
+ "Subtitles": "Isdeitlau",
+ "subtitles off": "Isdeitlau i ffwrdd",
+ "Captions": "Capsiynau",
+ "captions off": "Capsiynau i ffwrdd",
+ "Chapters": "Penodau",
+ "Descriptions": "Disgrifiadau",
+ "descriptions off": "disgrifiadau i ffwrdd",
+ "Audio Track": "Trac Sain",
+ "Volume Level": "Lefel Sain",
+ "You aborted the media playback": "Atalwyd y fideo gennych",
+ "A network error caused the media download to fail part-way.": "Mae gwall rhwydwaith wedi achosi methiant lawrlwytho.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Ni lwythodd y fideo, oherwydd methiant gweinydd neu rwydwaith, neu achos nid yw'r system yn cefnogi'r fformat.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Atalwyd y fideo oherwydd problem llygredd data neu oherwydd nid yw'ch porwr yn cefnogi nodweddion penodol o'r fideo.",
+ "No compatible source was found for this media.": "Nid oedd modd canfod ffynhonnell cytûn am y fideo hwn.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Mae'r fideo wedi ei amgryptio ac nid oes allweddion gennym.",
+ "Play Video": "Chwarae Fideo",
+ "Close": "Cau",
+ "Close Modal Dialog": "Cau Blwch Deialog Moddol",
+ "Modal Window": "Ffenestr Foddol",
+ "This is a modal window": "Mae hon yn ffenestr foddol",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Gallech chi gau'r ffenestr foddol hon trwy wasgu Escape neu glicio'r botwm cau.",
+ ", opens captions settings dialog": ", yn agor gosodiadau capsiynau",
+ ", opens subtitles settings dialog": ", yn agor gosodiadau isdeitlau",
+ ", opens descriptions settings dialog": ", yn agor gosodiadau disgrifiadau",
+ ", selected": ", detholwyd",
+ "captions settings": "gosodiadau capsiynau",
+ "subtitles settings": "gosodiadau isdeitlau",
+ "descriptions settings": "gosodiadau disgrifiadau",
+ "Text": "Testun",
+ "White": "Gwyn",
+ "Black": "Du",
+ "Red": "Coch",
+ "Green": "Gwyrdd",
+ "Blue": "Glas",
+ "Yellow": "Melyn",
+ "Magenta": "Piws",
+ "Cyan": "Cyan",
+ "Background": "Cefndir",
+ "Window": "Ffenestr",
+ "Transparent": "Tryloyw",
+ "Semi-Transparent": "Hanner-dryloyw",
+ "Opaque": "Di-draidd",
+ "Font Size": "Maint y Ffont",
+ "Text Edge Style": "Arddull Ymylon Testun",
+ "None": "Dim",
+ "Raised": "Uwch",
+ "Depressed": "Is",
+ "Uniform": "Unffurf",
+ "Dropshadow": "Cysgod cefn",
+ "Font Family": "Teulu y Ffont",
+ "Proportional Sans-Serif": "Heb-Seriff Cyfraneddol",
+ "Monospace Sans-Serif": "Heb-Seriff Unlled",
+ "Proportional Serif": "Seriff Gyfraneddol",
+ "Monospace Serif": "Seriff Unlled",
+ "Casual": "Llawysgrif",
+ "Script": "Sgript",
+ "Small Caps": "Prif Lythyrennau Bychain",
+ "Reset": "Ailosod",
+ "restore all settings to the default values": "Adfer yr holl osodiadau diofyn",
+ "Done": "Gorffenwyd",
+ "Caption Settings Dialog": "Blwch Gosodiadau Capsiynau",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Dechrau ffenestr deialog. Bydd Escape yn canslo a chau'r ffenestr.",
+ "End of dialog window.": "Diwedd ffenestr deialog.",
+ "{1} is loading.": "{1} yn llwytho."
+});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player":"Chwaraewr sain",
+ "Video Player":"Chwaraewr fideo",
+ "Play":"Chwarae",
+ "Pause":"Oedi",
+ "Replay":"Ailchwarae",
+ "Current Time":"Amser Cyfredol",
+ "Duration":"Parhad",
+ "Remaining Time":"Amser ar ôl",
+ "Stream Type":"Math o Ffrwd",
+ "LIVE":"YN FYW",
+ "Loaded":"Llwythwyd",
+ "Progress":"Cynnydd",
+ "Progress Bar":"Bar Cynnydd",
+ "progress bar timing: currentTime={1} duration={2}":"{1} o {2}",
+ "Fullscreen":"Sgrîn Lawn",
+ "Non-Fullscreen":"Ffenestr",
+ "Mute":"Pylu",
+ "Unmute":"Dad-bylu",
+ "Playback Rate":"Cyfradd Chwarae",
+ "Subtitles":"Isdeitlau",
+ "subtitles off":"Isdeitlau i ffwrdd",
+ "Captions":"Capsiynau",
+ "captions off":"Capsiynau i ffwrdd",
+ "Chapters":"Penodau",
+ "Descriptions":"Disgrifiadau",
+ "descriptions off":"disgrifiadau i ffwrdd",
+ "Audio Track":"Trac Sain",
+ "Volume Level":"Lefel Sain",
+ "You aborted the media playback":"Atalwyd y fideo gennych",
+ "A network error caused the media download to fail part-way.":"Mae gwall rhwydwaith wedi achosi methiant lawrlwytho.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.":"Ni lwythodd y fideo, oherwydd methiant gweinydd neu rwydwaith, neu achos nid yw'r system yn cefnogi'r fformat.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.":"Atalwyd y fideo oherwydd problem llygredd data neu oherwydd nid yw'ch porwr yn cefnogi nodweddion penodol o'r fideo.",
+ "No compatible source was found for this media.":"Nid oedd modd canfod ffynhonnell cytûn am y fideo hwn.",
+ "The media is encrypted and we do not have the keys to decrypt it.":"Mae'r fideo wedi ei amgryptio ac nid oes allweddion gennym.",
+ "Play Video":"Chwarae Fideo",
+ "Close":"Cau",
+ "Close Modal Dialog":"Cau Blwch Deialog Moddol",
+ "Modal Window":"Ffenestr Foddol",
+ "This is a modal window":"Mae hon yn ffenestr foddol",
+ "This modal can be closed by pressing the Escape key or activating the close button.":"Gallech chi gau'r ffenestr foddol hon trwy wasgu Escape neu glicio'r botwm cau.",
+ ", opens captions settings dialog":", yn agor gosodiadau capsiynau",
+ ", opens subtitles settings dialog":", yn agor gosodiadau isdeitlau",
+ ", opens descriptions settings dialog":", yn agor gosodiadau disgrifiadau",
+ ", selected":", detholwyd",
+ "captions settings":"gosodiadau capsiynau",
+ "subtitles settings":"gosodiadau isdeitlau",
+ "descriptions settings":"gosodiadau disgrifiadau",
+ "Text":"Testun",
+ "White":"Gwyn",
+ "Black":"Du",
+ "Red":"Coch",
+ "Green":"Gwyrdd",
+ "Blue":"Glas",
+ "Yellow":"Melyn",
+ "Magenta":"Piws",
+ "Cyan":"Cyan",
+ "Background":"Cefndir",
+ "Window":"Ffenestr",
+ "Transparent":"Tryloyw",
+ "Semi-Transparent":"Hanner-dryloyw",
+ "Opaque":"Di-draidd",
+ "Font Size":"Maint y Ffont",
+ "Text Edge Style":"Arddull Ymylon Testun",
+ "None":"Dim",
+ "Raised":"Uwch",
+ "Depressed":"Is",
+ "Uniform":"Unffurf",
+ "Dropshadow":"Cysgod cefn",
+ "Font Family":"Teulu y Ffont",
+ "Proportional Sans-Serif":"Heb-Seriff Cyfraneddol",
+ "Monospace Sans-Serif":"Heb-Seriff Unlled",
+ "Proportional Serif":"Seriff Gyfraneddol",
+ "Monospace Serif":"Seriff Unlled",
+ "Casual":"Llawysgrif",
+ "Script":"Sgript",
+ "Small Caps":"Prif Lythyrennau Bychain",
+ "Reset":"Ailosod",
+ "restore all settings to the default values":"Adfer yr holl osodiadau diofyn",
+ "Done":"Gorffenwyd",
+ "Caption Settings Dialog":"Blwch Gosodiadau Capsiynau",
+ "Beginning of dialog window. Escape will cancel and close the window.":"Dechrau ffenestr deialog. Bydd Escape yn canslo a chau'r ffenestr.",
+ "End of dialog window.":"Diwedd ffenestr deialog.",
+ "{1} is loading.": "{1} yn llwytho."
+}
-videojs.addLanguage("da",{
- "Play": "Afspil",
- "Pause": "Pause",
- "Current Time": "Aktuel tid",
- "Duration Time": "Varighed",
- "Remaining Time": "Resterende tid",
- "Stream Type": "Stream-type",
- "LIVE": "LIVE",
- "Loaded": "Indlæst",
- "Progress": "Status",
- "Fullscreen": "Fuldskærm",
- "Non-Fullscreen": "Luk fuldskærm",
- "Mute": "Uden lyd",
- "Unmute": "Med lyd",
- "Playback Rate": "Afspilningsrate",
- "Subtitles": "Undertekster",
- "subtitles off": "Uden undertekster",
- "Captions": "Undertekster for hørehæmmede",
- "captions off": "Uden undertekster for hørehæmmede",
- "Chapters": "Kapitler",
- "You aborted the media playback": "Du afbrød videoafspilningen.",
- "A network error caused the media download to fail part-way.": "En netværksfejl fik download af videoen til at fejle.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikke indlæses, enten fordi serveren eller netværket fejlede, eller fordi formatet ikke er understøttet.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoafspilningen blev afbrudt på grund af ødelagte data eller fordi videoen benyttede faciliteter som din browser ikke understøtter.",
- "No compatible source was found for this media.": "Fandt ikke en kompatibel kilde for denne media."
+videojs.addLanguage('da', {
+ "Play": "Afspil",
+ "Pause": "Pause",
+ "Current Time": "Aktuel tid",
+ "Duration": "Varighed",
+ "Remaining Time": "Resterende tid",
+ "Stream Type": "Stream-type",
+ "LIVE": "LIVE",
+ "Loaded": "Indlæst",
+ "Progress": "Status",
+ "Fullscreen": "Fuldskærm",
+ "Non-Fullscreen": "Luk fuldskærm",
+ "Mute": "Uden lyd",
+ "Unmute": "Med lyd",
+ "Playback Rate": "Afspilningsrate",
+ "Subtitles": "Undertekster",
+ "subtitles off": "Uden undertekster",
+ "Captions": "Undertekster for hørehæmmede",
+ "captions off": "Uden undertekster for hørehæmmede",
+ "Chapters": "Kapitler",
+ "You aborted the media playback": "Du afbrød videoafspilningen.",
+ "A network error caused the media download to fail part-way.": "En netværksfejl fik download af videoen til at fejle.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikke indlæses, enten fordi serveren eller netværket fejlede, eller fordi formatet ikke er understøttet.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoafspilningen blev afbrudt på grund af ødelagte data eller fordi videoen benyttede faciliteter som din browser ikke understøtter.",
+ "No compatible source was found for this media.": "Fandt ikke en kompatibel kilde for denne media."
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Afspil",
+ "Pause": "Pause",
+ "Current Time": "Aktuel tid",
+ "Duration": "Varighed",
+ "Remaining Time": "Resterende tid",
+ "Stream Type": "Stream-type",
+ "LIVE": "LIVE",
+ "Loaded": "Indlæst",
+ "Progress": "Status",
+ "Fullscreen": "Fuldskærm",
+ "Non-Fullscreen": "Luk fuldskærm",
+ "Mute": "Uden lyd",
+ "Unmute": "Med lyd",
+ "Playback Rate": "Afspilningsrate",
+ "Subtitles": "Undertekster",
+ "subtitles off": "Uden undertekster",
+ "Captions": "Undertekster for hørehæmmede",
+ "captions off": "Uden undertekster for hørehæmmede",
+ "Chapters": "Kapitler",
+ "You aborted the media playback": "Du afbrød videoafspilningen.",
+ "A network error caused the media download to fail part-way.": "En netværksfejl fik download af videoen til at fejle.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikke indlæses, enten fordi serveren eller netværket fejlede, eller fordi formatet ikke er understøttet.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoafspilningen blev afbrudt på grund af ødelagte data eller fordi videoen benyttede faciliteter som din browser ikke understøtter.",
+ "No compatible source was found for this media.": "Fandt ikke en kompatibel kilde for denne media."
+}
-videojs.addLanguage("de",{
- "Play": "Wiedergabe",
- "Pause": "Pause",
- "Replay": "Erneut abspielen",
- "Current Time": "Aktueller Zeitpunkt",
- "Duration Time": "Dauer",
- "Remaining Time": "Verbleibende Zeit",
- "Stream Type": "Streamtyp",
- "LIVE": "LIVE",
- "Loaded": "Geladen",
- "Progress": "Status",
- "Fullscreen": "Vollbild",
- "Non-Fullscreen": "Kein Vollbild",
- "Mute": "Ton aus",
- "Unmute": "Ton ein",
- "Playback Rate": "Wiedergabegeschwindigkeit",
- "Subtitles": "Untertitel",
- "subtitles off": "Untertitel aus",
- "Captions": "Untertitel",
- "captions off": "Untertitel aus",
- "Chapters": "Kapitel",
- "You aborted the media playback": "Sie haben die Videowiedergabe abgebrochen.",
- "A network error caused the media download to fail part-way.": "Der Videodownload ist aufgrund eines Netzwerkfehlers fehlgeschlagen.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Das Video konnte nicht geladen werden, da entweder ein Server- oder Netzwerkfehler auftrat oder das Format nicht unterstützt wird.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Die Videowiedergabe wurde entweder wegen eines Problems mit einem beschädigten Video oder wegen verwendeten Funktionen, die vom Browser nicht unterstützt werden, abgebrochen.",
- "No compatible source was found for this media.": "Für dieses Video wurde keine kompatible Quelle gefunden.",
- "Play Video": "Video abspielen",
- "Close": "Schließen",
- "Modal Window": "Modales Fenster",
- "This is a modal window": "Dies ist ein modales Fenster",
- "This modal can be closed by pressing the Escape key or activating the close button.": "Durch Drücken der Esc-Taste bzw. Betätigung der Schaltfläche \"Schließen\" wird dieses modale Fenster geschlossen.",
- ", opens captions settings dialog": ", öffnet Einstellungen für Untertitel",
- ", opens subtitles settings dialog": ", öffnet Einstellungen für Untertitel",
- ", selected": ", ausgewählt",
- "captions settings": "Untertiteleinstellungen",
- "subtitles settings": "Untertiteleinstellungen",
- "descriptions settings": "Einstellungen für Beschreibungen",
- "Close Modal Dialog": "Modales Fenster schließen",
- "Descriptions": "Beschreibungen",
- "descriptions off": "Beschreibungen aus",
- "The media is encrypted and we do not have the keys to decrypt it.": "Die Entschlüsselungsschlüssel für den verschlüsselten Medieninhalt sind nicht verfügbar.",
- ", opens descriptions settings dialog": ", öffnet Einstellungen für Beschreibungen",
- "Audio Track": "Tonspur",
- "Text": "Schrift",
- "White": "Weiß",
- "Black": "Schwarz",
- "Red": "Rot",
- "Green": "Grün",
- "Blue": "Blau",
- "Yellow": "Gelb",
- "Magenta": "Magenta",
- "Cyan": "Türkis",
- "Background": "Hintergrund",
- "Window": "Fenster",
- "Transparent": "Durchsichtig",
- "Semi-Transparent": "Halbdurchsichtig",
- "Opaque": "Undurchsictig",
- "Font Size": "Schriftgröße",
- "Text Edge Style": "Textkantenstil",
- "None": "Kein",
- "Raised": "Erhoben",
- "Depressed": "Gedrückt",
- "Uniform": "Uniform",
- "Dropshadow": "Schlagschatten",
- "Font Family": "Schristfamilie",
- "Proportional Sans-Serif": "Proportionale Sans-Serif",
- "Monospace Sans-Serif": "Monospace Sans-Serif",
- "Proportional Serif": "Proportionale Serif",
- "Monospace Serif": "Monospace Serif",
- "Casual": "Zwanglos",
- "Script": "Schreibeschrift",
- "Small Caps": "Small-Caps",
- "Reset": "Zurücksetzen",
- "restore all settings to the default values": "Alle Einstellungen auf die Standardwerte zurücksetzen",
- "Done": "Fertig",
- "Caption Settings Dialog": "Einstellungsdialog für Untertitel",
- "Beginning of dialog window. Escape will cancel and close the window.": "Anfang des Dialogfensters. Esc bricht ab und schließt das Fenster.",
- "End of dialog window.": "Ende des Dialogfensters.",
- "Audio Player": "Audio-Player",
- "Video Player": "Video-Player",
- "Progress Bar": "Forschrittsbalken",
- "progress bar timing: currentTime={1} duration={2}": "{1} von {2}",
- "Volume Level": "Lautstärkestufe"
+videojs.addLanguage('de', {
+ "Play": "Wiedergabe",
+ "Pause": "Pause",
+ "Replay": "Erneut abspielen",
+ "Current Time": "Aktueller Zeitpunkt",
+ "Duration": "Dauer",
+ "Remaining Time": "Verbleibende Zeit",
+ "Stream Type": "Streamtyp",
+ "LIVE": "LIVE",
+ "Loaded": "Geladen",
+ "Progress": "Status",
+ "Fullscreen": "Vollbild",
+ "Non-Fullscreen": "Vollbildmodus beenden",
+ "Mute": "Ton aus",
+ "Unmute": "Ton ein",
+ "Playback Rate": "Wiedergabegeschwindigkeit",
+ "Subtitles": "Untertitel",
+ "subtitles off": "Untertitel aus",
+ "Captions": "Untertitel",
+ "captions off": "Untertitel aus",
+ "Chapters": "Kapitel",
+ "You aborted the media playback": "Sie haben die Videowiedergabe abgebrochen.",
+ "A network error caused the media download to fail part-way.": "Der Videodownload ist aufgrund eines Netzwerkfehlers fehlgeschlagen.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Das Video konnte nicht geladen werden, da entweder ein Server- oder Netzwerkfehler auftrat oder das Format nicht unterstützt wird.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Die Videowiedergabe wurde entweder wegen eines Problems mit einem beschädigten Video oder wegen verwendeten Funktionen, die vom Browser nicht unterstützt werden, abgebrochen.",
+ "No compatible source was found for this media.": "Für dieses Video wurde keine kompatible Quelle gefunden.",
+ "Play Video": "Video abspielen",
+ "Close": "Schließen",
+ "Modal Window": "Modales Fenster",
+ "This is a modal window": "Dies ist ein modales Fenster",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Durch Drücken der Esc-Taste bzw. Betätigung der Schaltfläche \"Schließen\" wird dieses modale Fenster geschlossen.",
+ ", opens captions settings dialog": ", öffnet Einstellungen für Untertitel",
+ ", opens subtitles settings dialog": ", öffnet Einstellungen für Untertitel",
+ ", selected": ", ausgewählt",
+ "captions settings": "Untertiteleinstellungen",
+ "subtitles settings": "Untertiteleinstellungen",
+ "descriptions settings": "Einstellungen für Beschreibungen",
+ "Close Modal Dialog": "Modales Fenster schließen",
+ "Descriptions": "Beschreibungen",
+ "descriptions off": "Beschreibungen aus",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Die Entschlüsselungsschlüssel für den verschlüsselten Medieninhalt sind nicht verfügbar.",
+ ", opens descriptions settings dialog": ", öffnet Einstellungen für Beschreibungen",
+ "Audio Track": "Tonspur",
+ "Text": "Schrift",
+ "White": "Weiß",
+ "Black": "Schwarz",
+ "Red": "Rot",
+ "Green": "Grün",
+ "Blue": "Blau",
+ "Yellow": "Gelb",
+ "Magenta": "Magenta",
+ "Cyan": "Türkis",
+ "Background": "Hintergrund",
+ "Window": "Fenster",
+ "Transparent": "Durchsichtig",
+ "Semi-Transparent": "Halbdurchsichtig",
+ "Opaque": "Undurchsichtig",
+ "Font Size": "Schriftgröße",
+ "Text Edge Style": "Textkantenstil",
+ "None": "Kein",
+ "Raised": "Erhoben",
+ "Depressed": "Gedrückt",
+ "Uniform": "Uniform",
+ "Dropshadow": "Schlagschatten",
+ "Font Family": "Schriftfamilie",
+ "Proportional Sans-Serif": "Proportionale Sans-Serif",
+ "Monospace Sans-Serif": "Monospace Sans-Serif",
+ "Proportional Serif": "Proportionale Serif",
+ "Monospace Serif": "Monospace Serif",
+ "Casual": "Zwanglos",
+ "Script": "Schreibschrift",
+ "Small Caps": "Small-Caps",
+ "Reset": "Zurücksetzen",
+ "restore all settings to the default values": "Alle Einstellungen auf die Standardwerte zurücksetzen",
+ "Done": "Fertig",
+ "Caption Settings Dialog": "Einstellungsdialog für Untertitel",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Anfang des Dialogfensters. Esc bricht ab und schließt das Fenster.",
+ "End of dialog window.": "Ende des Dialogfensters.",
+ "Audio Player": "Audio-Player",
+ "Video Player": "Video-Player",
+ "Progress Bar": "Fortschrittsbalken",
+ "progress bar timing: currentTime={1} duration={2}": "{1} von {2}",
+ "Volume Level": "Lautstärke",
+ "{1} is loading.": "{1} wird geladen.",
+ "Seek to live, currently behind live": "Zur Live-Übertragung wechseln. Aktuell wird es nicht live abgespielt.",
+ "Seek to live, currently playing live": "Zur Live-Übertragung wechseln. Es wird aktuell live abgespielt.",
+ "Exit Picture-in-Picture": "Bild-im-Bild-Modus beenden",
+ "Picture-in-Picture": "Bild-im-Bild-Modus"
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Wiedergabe",
+ "Pause": "Pause",
+ "Replay": "Erneut abspielen",
+ "Current Time": "Aktueller Zeitpunkt",
+ "Duration": "Dauer",
+ "Remaining Time": "Verbleibende Zeit",
+ "Stream Type": "Streamtyp",
+ "LIVE": "LIVE",
+ "Loaded": "Geladen",
+ "Progress": "Status",
+ "Fullscreen": "Vollbild",
+ "Non-Fullscreen": "Vollbildmodus beenden",
+ "Mute": "Ton aus",
+ "Unmute": "Ton ein",
+ "Playback Rate": "Wiedergabegeschwindigkeit",
+ "Subtitles": "Untertitel",
+ "subtitles off": "Untertitel aus",
+ "Captions": "Untertitel",
+ "captions off": "Untertitel aus",
+ "Chapters": "Kapitel",
+ "You aborted the media playback": "Sie haben die Videowiedergabe abgebrochen.",
+ "A network error caused the media download to fail part-way.": "Der Videodownload ist aufgrund eines Netzwerkfehlers fehlgeschlagen.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Das Video konnte nicht geladen werden, da entweder ein Server- oder Netzwerkfehler auftrat oder das Format nicht unterstützt wird.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Die Videowiedergabe wurde entweder wegen eines Problems mit einem beschädigten Video oder wegen verwendeten Funktionen, die vom Browser nicht unterstützt werden, abgebrochen.",
+ "No compatible source was found for this media.": "Für dieses Video wurde keine kompatible Quelle gefunden.",
+ "Play Video": "Video abspielen",
+ "Close": "Schließen",
+ "Modal Window": "Modales Fenster",
+ "This is a modal window": "Dies ist ein modales Fenster",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Durch Drücken der Esc-Taste bzw. Betätigung der Schaltfläche \"Schließen\" wird dieses modale Fenster geschlossen.",
+ ", opens captions settings dialog": ", öffnet Einstellungen für Untertitel",
+ ", opens subtitles settings dialog": ", öffnet Einstellungen für Untertitel",
+ ", selected": ", ausgewählt",
+ "captions settings": "Untertiteleinstellungen",
+ "subtitles settings": "Untertiteleinstellungen",
+ "descriptions settings": "Einstellungen für Beschreibungen",
+ "Close Modal Dialog": "Modales Fenster schließen",
+ "Descriptions": "Beschreibungen",
+ "descriptions off": "Beschreibungen aus",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Die Entschlüsselungsschlüssel für den verschlüsselten Medieninhalt sind nicht verfügbar.",
+ ", opens descriptions settings dialog": ", öffnet Einstellungen für Beschreibungen",
+ "Audio Track": "Tonspur",
+ "Text": "Schrift",
+ "White": "Weiß",
+ "Black": "Schwarz",
+ "Red": "Rot",
+ "Green": "Grün",
+ "Blue": "Blau",
+ "Yellow": "Gelb",
+ "Magenta": "Magenta",
+ "Cyan": "Türkis",
+ "Background": "Hintergrund",
+ "Window": "Fenster",
+ "Transparent": "Durchsichtig",
+ "Semi-Transparent": "Halbdurchsichtig",
+ "Opaque": "Undurchsichtig",
+ "Font Size": "Schriftgröße",
+ "Text Edge Style": "Textkantenstil",
+ "None": "Kein",
+ "Raised": "Erhoben",
+ "Depressed": "Gedrückt",
+ "Uniform": "Uniform",
+ "Dropshadow": "Schlagschatten",
+ "Font Family": "Schriftfamilie",
+ "Proportional Sans-Serif": "Proportionale Sans-Serif",
+ "Monospace Sans-Serif": "Monospace Sans-Serif",
+ "Proportional Serif": "Proportionale Serif",
+ "Monospace Serif": "Monospace Serif",
+ "Casual": "Zwanglos",
+ "Script": "Schreibschrift",
+ "Small Caps": "Small-Caps",
+ "Reset": "Zurücksetzen",
+ "restore all settings to the default values": "Alle Einstellungen auf die Standardwerte zurücksetzen",
+ "Done": "Fertig",
+ "Caption Settings Dialog": "Einstellungsdialog für Untertitel",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Anfang des Dialogfensters. Esc bricht ab und schließt das Fenster.",
+ "End of dialog window.": "Ende des Dialogfensters.",
+ "Audio Player": "Audio-Player",
+ "Video Player": "Video-Player",
+ "Progress Bar": "Fortschrittsbalken",
+ "progress bar timing: currentTime={1} duration={2}": "{1} von {2}",
+ "Volume Level": "Lautstärke",
+ "{1} is loading.": "{1} wird geladen.",
+ "Seek to live, currently behind live": "Zur Live-Übertragung wechseln. Aktuell wird es nicht live abgespielt.",
+ "Seek to live, currently playing live": "Zur Live-Übertragung wechseln. Es wird aktuell live abgespielt.",
+ "Exit Picture-in-Picture": "Bild-im-Bild-Modus beenden",
+ "Picture-in-Picture": "Bild-im-Bild-Modus"
+}
+
-videojs.addLanguage("el",{
- "Play": "Aναπαραγωγή",
- "Pause": "Παύση",
- "Current Time": "Τρέχων χρόνος",
- "Duration Time": "Συνολικός χρόνος",
- "Remaining Time": "Υπολοιπόμενος χρόνος",
- "Stream Type": "Τύπος ροής",
- "LIVE": "ΖΩΝΤΑΝΑ",
- "Loaded": "Φόρτωση επιτυχής",
- "Progress": "Πρόοδος",
- "Fullscreen": "Πλήρης οθόνη",
- "Non-Fullscreen": "Έξοδος από πλήρη οθόνη",
- "Mute": "Σίγαση",
- "Unmute": "Kατάργηση σίγασης",
- "Playback Rate": "Ρυθμός αναπαραγωγής",
- "Subtitles": "Υπότιτλοι",
- "subtitles off": "απόκρυψη υπότιτλων",
- "Captions": "Λεζάντες",
- "captions off": "απόκρυψη λεζάντων",
- "Chapters": "Κεφάλαια",
- "Close Modal Dialog": "Κλείσιμο παραθύρου",
- "Descriptions": "Περιγραφές",
- "descriptions off": "απόκρυψη περιγραφών",
- "Audio Track": "Ροή ήχου",
- "You aborted the media playback": "Ακυρώσατε την αναπαραγωγή",
- "A network error caused the media download to fail part-way.": "Ένα σφάλμα δικτύου προκάλεσε την αποτυχία μεταφόρτωσης του αρχείου προς αναπαραγωγή.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Το αρχείο προς αναπαραγωγή δεν ήταν δυνατό να φορτωθεί είτε γιατί υπήρξε σφάλμα στον διακομιστή ή το δίκτυο, είτε γιατί ο τύπος του αρχείου δεν υποστηρίζεται.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Η αναπαραγωγή ακυρώθηκε είτε λόγω κατεστραμμένου αρχείου, είτε γιατί το αρχείο απαιτεί λειτουργίες που δεν υποστηρίζονται από το πρόγραμμα περιήγησης που χρησιμοποιείτε.",
- "No compatible source was found for this media.": "Δεν βρέθηκε συμβατή πηγή αναπαραγωγής για το συγκεκριμένο αρχείο.",
- "The media is encrypted and we do not have the keys to decrypt it.": "Το αρχείο προς αναπαραγωγή είναι κρυπτογραφημένo και δεν υπάρχουν τα απαραίτητα κλειδιά αποκρυπτογράφησης.",
- "Play Video": "Αναπαραγωγή βίντεο",
- "Close": "Κλείσιμο",
- "Modal Window": "Aναδυόμενο παράθυρο",
- "This is a modal window": "Το παρών είναι ένα αναδυόμενο παράθυρο",
- "This modal can be closed by pressing the Escape key or activating the close button.": "Αυτό το παράθυρο μπορεί να εξαφανιστεί πατώντας το πλήκτρο Escape ή πατώντας το κουμπί κλεισίματος.",
- ", opens captions settings dialog": ", εμφανίζει τις ρυθμίσεις για τις λεζάντες",
- ", opens subtitles settings dialog": ", εμφανίζει τις ρυθμίσεις για τους υπότιτλους",
- ", opens descriptions settings dialog": ", εμφανίζει τις ρυθμίσεις για τις περιγραφές",
- ", selected": ", επιλεγμένο"
+videojs.addLanguage('el', {
+ "Play": "Aναπαραγωγή",
+ "Pause": "Παύση",
+ "Current Time": "Τρέχων χρόνος",
+ "Duration": "Συνολικός χρόνος",
+ "Remaining Time": "Υπολοιπόμενος χρόνος",
+ "Stream Type": "Τύπος ροής",
+ "LIVE": "ΖΩΝΤΑΝΑ",
+ "Loaded": "Φόρτωση επιτυχής",
+ "Progress": "Πρόοδος",
+ "Fullscreen": "Πλήρης οθόνη",
+ "Non-Fullscreen": "Έξοδος από πλήρη οθόνη",
+ "Mute": "Σίγαση",
+ "Unmute": "Kατάργηση σίγασης",
+ "Playback Rate": "Ρυθμός αναπαραγωγής",
+ "Subtitles": "Υπότιτλοι",
+ "subtitles off": "απόκρυψη υπότιτλων",
+ "Captions": "Λεζάντες",
+ "captions off": "απόκρυψη λεζάντων",
+ "Chapters": "Κεφάλαια",
+ "Close Modal Dialog": "Κλείσιμο παραθύρου",
+ "Descriptions": "Περιγραφές",
+ "descriptions off": "απόκρυψη περιγραφών",
+ "Audio Track": "Ροή ήχου",
+ "You aborted the media playback": "Ακυρώσατε την αναπαραγωγή",
+ "A network error caused the media download to fail part-way.": "Ένα σφάλμα δικτύου προκάλεσε την αποτυχία μεταφόρτωσης του αρχείου προς αναπαραγωγή.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Το αρχείο προς αναπαραγωγή δεν ήταν δυνατό να φορτωθεί είτε γιατί υπήρξε σφάλμα στον διακομιστή ή το δίκτυο, είτε γιατί ο τύπος του αρχείου δεν υποστηρίζεται.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Η αναπαραγωγή ακυρώθηκε είτε λόγω κατεστραμμένου αρχείου, είτε γιατί το αρχείο απαιτεί λειτουργίες που δεν υποστηρίζονται από το πρόγραμμα περιήγησης που χρησιμοποιείτε.",
+ "No compatible source was found for this media.": "Δεν βρέθηκε συμβατή πηγή αναπαραγωγής για το συγκεκριμένο αρχείο.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Το αρχείο προς αναπαραγωγή είναι κρυπτογραφημένo και δεν υπάρχουν τα απαραίτητα κλειδιά αποκρυπτογράφησης.",
+ "Play Video": "Αναπαραγωγή βίντεο",
+ "Close": "Κλείσιμο",
+ "Modal Window": "Aναδυόμενο παράθυρο",
+ "This is a modal window": "Το παρών είναι ένα αναδυόμενο παράθυρο",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Αυτό το παράθυρο μπορεί να εξαφανιστεί πατώντας το πλήκτρο Escape ή πατώντας το κουμπί κλεισίματος.",
+ ", opens captions settings dialog": ", εμφανίζει τις ρυθμίσεις για τις λεζάντες",
+ ", opens subtitles settings dialog": ", εμφανίζει τις ρυθμίσεις για τους υπότιτλους",
+ ", opens descriptions settings dialog": ", εμφανίζει τις ρυθμίσεις για τις περιγραφές",
+ ", selected": ", επιλεγμένο"
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Aναπαραγωγή",
+ "Pause": "Παύση",
+ "Current Time": "Τρέχων χρόνος",
+ "Duration": "Συνολικός χρόνος",
+ "Remaining Time": "Υπολοιπόμενος χρόνος",
+ "Stream Type": "Τύπος ροής",
+ "LIVE": "ΖΩΝΤΑΝΑ",
+ "Loaded": "Φόρτωση επιτυχής",
+ "Progress": "Πρόοδος",
+ "Fullscreen": "Πλήρης οθόνη",
+ "Non-Fullscreen": "Έξοδος από πλήρη οθόνη",
+ "Mute": "Σίγαση",
+ "Unmute": "Kατάργηση σίγασης",
+ "Playback Rate": "Ρυθμός αναπαραγωγής",
+ "Subtitles": "Υπότιτλοι",
+ "subtitles off": "απόκρυψη υπότιτλων",
+ "Captions": "Λεζάντες",
+ "captions off": "απόκρυψη λεζάντων",
+ "Chapters": "Κεφάλαια",
+ "Close Modal Dialog": "Κλείσιμο παραθύρου",
+ "Descriptions": "Περιγραφές",
+ "descriptions off": "απόκρυψη περιγραφών",
+ "Audio Track": "Ροή ήχου",
+ "You aborted the media playback": "Ακυρώσατε την αναπαραγωγή",
+ "A network error caused the media download to fail part-way.": "Ένα σφάλμα δικτύου προκάλεσε την αποτυχία μεταφόρτωσης του αρχείου προς αναπαραγωγή.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Το αρχείο προς αναπαραγωγή δεν ήταν δυνατό να φορτωθεί είτε γιατί υπήρξε σφάλμα στον διακομιστή ή το δίκτυο, είτε γιατί ο τύπος του αρχείου δεν υποστηρίζεται.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Η αναπαραγωγή ακυρώθηκε είτε λόγω κατεστραμμένου αρχείου, είτε γιατί το αρχείο απαιτεί λειτουργίες που δεν υποστηρίζονται από το πρόγραμμα περιήγησης που χρησιμοποιείτε.",
+ "No compatible source was found for this media.": "Δεν βρέθηκε συμβατή πηγή αναπαραγωγής για το συγκεκριμένο αρχείο.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Το αρχείο προς αναπαραγωγή είναι κρυπτογραφημένo και δεν υπάρχουν τα απαραίτητα κλειδιά αποκρυπτογράφησης.",
+ "Play Video": "Αναπαραγωγή βίντεο",
+ "Close": "Κλείσιμο",
+ "Modal Window": "Aναδυόμενο παράθυρο",
+ "This is a modal window": "Το παρών είναι ένα αναδυόμενο παράθυρο",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Αυτό το παράθυρο μπορεί να εξαφανιστεί πατώντας το πλήκτρο Escape ή πατώντας το κουμπί κλεισίματος.",
+ ", opens captions settings dialog": ", εμφανίζει τις ρυθμίσεις για τις λεζάντες",
+ ", opens subtitles settings dialog": ", εμφανίζει τις ρυθμίσεις για τους υπότιτλους",
+ ", opens descriptions settings dialog": ", εμφανίζει τις ρυθμίσεις για τις περιγραφές",
+ ", selected": ", επιλεγμένο"
+}
-videojs.addLanguage("en",{
- "Audio Player": "Audio Player",
- "Video Player": "Video Player",
- "Play": "Play",
- "Pause": "Pause",
- "Replay": "Replay",
- "Current Time": "Current Time",
- "Duration Time": "Duration Time",
- "Remaining Time": "Remaining Time",
- "Stream Type": "Stream Type",
- "LIVE": "LIVE",
- "Loaded": "Loaded",
- "Progress": "Progress",
- "Progress Bar": "Progress Bar",
- "progress bar timing: currentTime={1} duration={2}": "{1} of {2}",
- "Fullscreen": "Fullscreen",
- "Non-Fullscreen": "Non-Fullscreen",
- "Mute": "Mute",
- "Unmute": "Unmute",
- "Playback Rate": "Playback Rate",
- "Subtitles": "Subtitles",
- "subtitles off": "subtitles off",
- "Captions": "Captions",
- "captions off": "captions off",
- "Chapters": "Chapters",
- "Descriptions": "Descriptions",
- "descriptions off": "descriptions off",
- "Audio Track": "Audio Track",
- "Volume Level": "Volume Level",
- "You aborted the media playback": "You aborted the media playback",
- "A network error caused the media download to fail part-way.": "A network error caused the media download to fail part-way.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "The media could not be loaded, either because the server or network failed or because the format is not supported.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.",
- "No compatible source was found for this media.": "No compatible source was found for this media.",
- "The media is encrypted and we do not have the keys to decrypt it.": "The media is encrypted and we do not have the keys to decrypt it.",
- "Play Video": "Play Video",
- "Close": "Close",
- "Close Modal Dialog": "Close Modal Dialog",
- "Modal Window": "Modal Window",
- "This is a modal window": "This is a modal window",
- "This modal can be closed by pressing the Escape key or activating the close button.": "This modal can be closed by pressing the Escape key or activating the close button.",
- ", opens captions settings dialog": ", opens captions settings dialog",
- ", opens subtitles settings dialog": ", opens subtitles settings dialog",
- ", opens descriptions settings dialog": ", opens descriptions settings dialog",
- ", selected": ", selected",
- "captions settings": "captions settings",
- "subtitles settings": "subititles settings",
- "descriptions settings": "descriptions settings",
- "Text": "Text",
- "White": "White",
- "Black": "Black",
- "Red": "Red",
- "Green": "Green",
- "Blue": "Blue",
- "Yellow": "Yellow",
- "Magenta": "Magenta",
- "Cyan": "Cyan",
- "Background": "Background",
- "Window": "Window",
- "Transparent": "Transparent",
- "Semi-Transparent": "Semi-Transparent",
- "Opaque": "Opaque",
- "Font Size": "Font Size",
- "Text Edge Style": "Text Edge Style",
- "None": "None",
- "Raised": "Raised",
- "Depressed": "Depressed",
- "Uniform": "Uniform",
- "Dropshadow": "Dropshadow",
- "Font Family": "Font Family",
- "Proportional Sans-Serif": "Proportional Sans-Serif",
- "Monospace Sans-Serif": "Monospace Sans-Serif",
- "Proportional Serif": "Proportional Serif",
- "Monospace Serif": "Monospace Serif",
- "Casual": "Casual",
- "Script": "Script",
- "Small Caps": "Small Caps",
- "Reset": "Reset",
- "restore all settings to the default values": "restore all settings to the default values",
- "Done": "Done",
- "Caption Settings Dialog": "Caption Settings Dialog",
- "Beginning of dialog window. Escape will cancel and close the window.": "Beginning of dialog window. Escape will cancel and close the window.",
- "End of dialog window.": "End of dialog window."
+videojs.addLanguage('en', {
+ "Audio Player": "Audio Player",
+ "Video Player": "Video Player",
+ "Play": "Play",
+ "Pause": "Pause",
+ "Replay": "Replay",
+ "Current Time": "Current Time",
+ "Duration": "Duration",
+ "Remaining Time": "Remaining Time",
+ "Stream Type": "Stream Type",
+ "LIVE": "LIVE",
+ "Seek to live, currently behind live": "Seek to live, currently behind live",
+ "Seek to live, currently playing live": "Seek to live, currently playing live",
+ "Loaded": "Loaded",
+ "Progress": "Progress",
+ "Progress Bar": "Progress Bar",
+ "progress bar timing: currentTime={1} duration={2}": "{1} of {2}",
+ "Fullscreen": "Fullscreen",
+ "Non-Fullscreen": "Exit Fullscreen",
+ "Mute": "Mute",
+ "Unmute": "Unmute",
+ "Playback Rate": "Playback Rate",
+ "Subtitles": "Subtitles",
+ "subtitles off": "subtitles off",
+ "Captions": "Captions",
+ "captions off": "captions off",
+ "Chapters": "Chapters",
+ "Descriptions": "Descriptions",
+ "descriptions off": "descriptions off",
+ "Audio Track": "Audio Track",
+ "Volume Level": "Volume Level",
+ "You aborted the media playback": "You aborted the media playback",
+ "A network error caused the media download to fail part-way.": "A network error caused the media download to fail part-way.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "The media could not be loaded, either because the server or network failed or because the format is not supported.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.",
+ "No compatible source was found for this media.": "No compatible source was found for this media.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "The media is encrypted and we do not have the keys to decrypt it.",
+ "Play Video": "Play Video",
+ "Close": "Close",
+ "Close Modal Dialog": "Close Modal Dialog",
+ "Modal Window": "Modal Window",
+ "This is a modal window": "This is a modal window",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "This modal can be closed by pressing the Escape key or activating the close button.",
+ ", opens captions settings dialog": ", opens captions settings dialog",
+ ", opens subtitles settings dialog": ", opens subtitles settings dialog",
+ ", opens descriptions settings dialog": ", opens descriptions settings dialog",
+ ", selected": ", selected",
+ "captions settings": "captions settings",
+ "subtitles settings": "subtitles settings",
+ "descriptions settings": "descriptions settings",
+ "Text": "Text",
+ "White": "White",
+ "Black": "Black",
+ "Red": "Red",
+ "Green": "Green",
+ "Blue": "Blue",
+ "Yellow": "Yellow",
+ "Magenta": "Magenta",
+ "Cyan": "Cyan",
+ "Background": "Background",
+ "Window": "Window",
+ "Transparent": "Transparent",
+ "Semi-Transparent": "Semi-Transparent",
+ "Opaque": "Opaque",
+ "Font Size": "Font Size",
+ "Text Edge Style": "Text Edge Style",
+ "None": "None",
+ "Raised": "Raised",
+ "Depressed": "Depressed",
+ "Uniform": "Uniform",
+ "Dropshadow": "Dropshadow",
+ "Font Family": "Font Family",
+ "Proportional Sans-Serif": "Proportional Sans-Serif",
+ "Monospace Sans-Serif": "Monospace Sans-Serif",
+ "Proportional Serif": "Proportional Serif",
+ "Monospace Serif": "Monospace Serif",
+ "Casual": "Casual",
+ "Script": "Script",
+ "Small Caps": "Small Caps",
+ "Reset": "Reset",
+ "restore all settings to the default values": "restore all settings to the default values",
+ "Done": "Done",
+ "Caption Settings Dialog": "Caption Settings Dialog",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Beginning of dialog window. Escape will cancel and close the window.",
+ "End of dialog window.": "End of dialog window.",
+ "{1} is loading.": "{1} is loading.",
+ "Exit Picture-in-Picture": "Exit Picture-in-Picture",
+ "Picture-in-Picture": "Picture-in-Picture"
});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Audio Player",
+ "Video Player": "Video Player",
+ "Play": "Play",
+ "Pause": "Pause",
+ "Replay": "Replay",
+ "Current Time": "Current Time",
+ "Duration": "Duration",
+ "Remaining Time": "Remaining Time",
+ "Stream Type": "Stream Type",
+ "LIVE": "LIVE",
+ "Seek to live, currently behind live": "Seek to live, currently behind live",
+ "Seek to live, currently playing live": "Seek to live, currently playing live",
+ "Loaded": "Loaded",
+ "Progress": "Progress",
+ "Progress Bar": "Progress Bar",
+ "progress bar timing: currentTime={1} duration={2}": "{1} of {2}",
+ "Fullscreen": "Fullscreen",
+ "Non-Fullscreen": "Exit Fullscreen",
+ "Mute": "Mute",
+ "Unmute": "Unmute",
+ "Playback Rate": "Playback Rate",
+ "Subtitles": "Subtitles",
+ "subtitles off": "subtitles off",
+ "Captions": "Captions",
+ "captions off": "captions off",
+ "Chapters": "Chapters",
+ "Descriptions": "Descriptions",
+ "descriptions off": "descriptions off",
+ "Audio Track": "Audio Track",
+ "Volume Level": "Volume Level",
+ "You aborted the media playback": "You aborted the media playback",
+ "A network error caused the media download to fail part-way.": "A network error caused the media download to fail part-way.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "The media could not be loaded, either because the server or network failed or because the format is not supported.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.",
+ "No compatible source was found for this media.": "No compatible source was found for this media.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "The media is encrypted and we do not have the keys to decrypt it.",
+ "Play Video": "Play Video",
+ "Close": "Close",
+ "Close Modal Dialog": "Close Modal Dialog",
+ "Modal Window": "Modal Window",
+ "This is a modal window": "This is a modal window",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "This modal can be closed by pressing the Escape key or activating the close button.",
+ ", opens captions settings dialog": ", opens captions settings dialog",
+ ", opens subtitles settings dialog": ", opens subtitles settings dialog",
+ ", opens descriptions settings dialog": ", opens descriptions settings dialog",
+ ", selected": ", selected",
+ "captions settings": "captions settings",
+ "subtitles settings": "subtitles settings",
+ "descriptions settings": "descriptions settings",
+ "Text": "Text",
+ "White": "White",
+ "Black": "Black",
+ "Red": "Red",
+ "Green": "Green",
+ "Blue": "Blue",
+ "Yellow": "Yellow",
+ "Magenta": "Magenta",
+ "Cyan": "Cyan",
+ "Background": "Background",
+ "Window": "Window",
+ "Transparent": "Transparent",
+ "Semi-Transparent": "Semi-Transparent",
+ "Opaque": "Opaque",
+ "Font Size": "Font Size",
+ "Text Edge Style": "Text Edge Style",
+ "None": "None",
+ "Raised": "Raised",
+ "Depressed": "Depressed",
+ "Uniform": "Uniform",
+ "Dropshadow": "Dropshadow",
+ "Font Family": "Font Family",
+ "Proportional Sans-Serif": "Proportional Sans-Serif",
+ "Monospace Sans-Serif": "Monospace Sans-Serif",
+ "Proportional Serif": "Proportional Serif",
+ "Monospace Serif": "Monospace Serif",
+ "Casual": "Casual",
+ "Script": "Script",
+ "Small Caps": "Small Caps",
+ "Reset": "Reset",
+ "restore all settings to the default values": "restore all settings to the default values",
+ "Done": "Done",
+ "Caption Settings Dialog": "Caption Settings Dialog",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Beginning of dialog window. Escape will cancel and close the window.",
+ "End of dialog window.": "End of dialog window.",
+ "{1} is loading.": "{1} is loading.",
+ "Exit Picture-in-Picture": "Exit Picture-in-Picture",
+ "Picture-in-Picture": "Picture-in-Picture"
+}
-videojs.addLanguage("es",{
- "Play": "Reproducción",
- "Play Video": "Reproducción Vídeo",
- "Pause": "Pausa",
- "Current Time": "Tiempo reproducido",
- "Duration Time": "Duración total",
- "Remaining Time": "Tiempo restante",
- "Stream Type": "Tipo de secuencia",
- "LIVE": "DIRECTO",
- "Loaded": "Cargado",
- "Progress": "Progreso",
- "Fullscreen": "Pantalla completa",
- "Non-Fullscreen": "Pantalla no completa",
- "Mute": "Silenciar",
- "Unmute": "No silenciado",
- "Playback Rate": "Velocidad de reproducción",
- "Subtitles": "Subtítulos",
- "subtitles off": "Subtítulos desactivados",
- "Captions": "Subtítulos especiales",
- "captions off": "Subtítulos especiales desactivados",
- "Chapters": "Capítulos",
- "You aborted the media playback": "Ha interrumpido la reproducción del vídeo.",
- "A network error caused the media download to fail part-way.": "Un error de red ha interrumpido la descarga del vídeo.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "No se ha podido cargar el vídeo debido a un fallo de red o del servidor o porque el formato es incompatible.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La reproducción de vídeo se ha interrumpido por un problema de corrupción de datos o porque el vídeo precisa funciones que su navegador no ofrece.",
- "No compatible source was found for this media.": "No se ha encontrado ninguna fuente compatible con este vídeo."
+videojs.addLanguage('es', {
+ "Play": "Reproducir",
+ "Play Video": "Reproducir Vídeo",
+ "Pause": "Pausa",
+ "Current Time": "Tiempo reproducido",
+ "Duration": "Duración total",
+ "Remaining Time": "Tiempo restante",
+ "Stream Type": "Tipo de secuencia",
+ "LIVE": "DIRECTO",
+ "Loaded": "Cargado",
+ "Progress": "Progreso",
+ "Fullscreen": "Pantalla completa",
+ "Non-Fullscreen": "Pantalla no completa",
+ "Mute": "Silenciar",
+ "Unmute": "No silenciado",
+ "Playback Rate": "Velocidad de reproducción",
+ "Subtitles": "Subtítulos",
+ "subtitles off": "Subtítulos desactivados",
+ "Captions": "Subtítulos especiales",
+ "captions off": "Subtítulos especiales desactivados",
+ "Chapters": "Capítulos",
+ "You aborted the media playback": "Ha interrumpido la reproducción del vídeo.",
+ "A network error caused the media download to fail part-way.": "Un error de red ha interrumpido la descarga del vídeo.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "No se ha podido cargar el vídeo debido a un fallo de red o del servidor o porque el formato es incompatible.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La reproducción de vídeo se ha interrumpido por un problema de corrupción de datos o porque el vídeo precisa funciones que su navegador no ofrece.",
+ "No compatible source was found for this media.": "No se ha encontrado ninguna fuente compatible con este vídeo.",
+ "Audio Player": "Reproductor de audio",
+ "Video Player": "Reproductor de video",
+ "Replay": "Volver a reproducir",
+ "Seek to live, currently behind live": "Buscar en vivo, actualmente demorado con respecto a la transmisión en vivo",
+ "Seek to live, currently playing live": "Buscar en vivo, actualmente reproduciendo en vivo",
+ "Progress Bar": "Barra de progreso",
+ "progress bar timing: currentTime={1} duration={2}": "{1} de {2}",
+ "Descriptions": "Descripciones",
+ "descriptions off": "descripciones desactivadas",
+ "Audio Track": "Pista de audio",
+ "Volume Level": "Nivel de volumen",
+ "The media is encrypted and we do not have the keys to decrypt it.": "El material audiovisual está cifrado y no tenemos las claves para descifrarlo.",
+ "Close": "Cerrar",
+ "Modal Window": "Ventana modal",
+ "This is a modal window": "Esta es una ventana modal",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Esta ventana modal puede cerrarse presionando la tecla Escape o activando el botón de cierre.",
+ ", opens captions settings dialog": ", abre el diálogo de configuración de leyendas",
+ ", opens subtitles settings dialog": ", abre el diálogo de configuración de subtítulos",
+ ", selected": ", seleccionado",
+ "Close Modal Dialog": "Cierra cuadro de diálogo modal",
+ ", opens descriptions settings dialog": ", abre el diálogo de configuración de las descripciones",
+ "captions settings": "configuración de leyendas",
+ "subtitles settings": "configuración de subtítulos",
+ "descriptions settings": "configuración de descripciones",
+ "Text": "Texto",
+ "White": "Blanco",
+ "Black": "Negro",
+ "Red": "Rojo",
+ "Green": "Verde",
+ "Blue": "Azul",
+ "Yellow": "Amarillo",
+ "Magenta": "Magenta",
+ "Cyan": "Cian",
+ "Background": "Fondo",
+ "Window": "Ventana",
+ "Transparent": "Transparente",
+ "Semi-Transparent": "Semitransparente",
+ "Opaque": "Opaca",
+ "Font Size": "Tamaño de fuente",
+ "Text Edge Style": "Estilo de borde del texto",
+ "None": "Ninguno",
+ "Raised": "En relieve",
+ "Depressed": "Hundido",
+ "Uniform": "Uniforme",
+ "Dropshadow": "Sombra paralela",
+ "Font Family": "Familia de fuente",
+ "Proportional Sans-Serif": "Sans-Serif proporcional",
+ "Monospace Sans-Serif": "Sans-Serif monoespacio",
+ "Proportional Serif": "Serif proporcional",
+ "Monospace Serif": "Serif monoespacio",
+ "Casual": "Informal",
+ "Script": "Cursiva",
+ "Small Caps": "Minúsculas",
+ "Reset": "Restablecer",
+ "restore all settings to the default values": "restablece todas las configuraciones a los valores predeterminados",
+ "Done": "Listo",
+ "Caption Settings Dialog": "Diálogo de configuración de leyendas",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Comienzo de la ventana de diálogo. La tecla Escape cancelará la operación y cerrará la ventana.",
+ "End of dialog window.": "Final de la ventana de diálogo.",
+ "{1} is loading.": "{1} se está cargando.",
+ "Exit Picture-in-Picture": "Salir de imagen sobre imagen",
+ "Picture-in-Picture": "Imagen sobre imagen"
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Reproducir",
+ "Play Video": "Reproducir Vídeo",
+ "Pause": "Pausa",
+ "Current Time": "Tiempo reproducido",
+ "Duration": "Duración total",
+ "Remaining Time": "Tiempo restante",
+ "Stream Type": "Tipo de secuencia",
+ "LIVE": "DIRECTO",
+ "Loaded": "Cargado",
+ "Progress": "Progreso",
+ "Fullscreen": "Pantalla completa",
+ "Non-Fullscreen": "Pantalla no completa",
+ "Mute": "Silenciar",
+ "Unmute": "No silenciado",
+ "Playback Rate": "Velocidad de reproducción",
+ "Subtitles": "Subtítulos",
+ "subtitles off": "Subtítulos desactivados",
+ "Captions": "Subtítulos especiales",
+ "captions off": "Subtítulos especiales desactivados",
+ "Chapters": "Capítulos",
+ "You aborted the media playback": "Ha interrumpido la reproducción del vídeo.",
+ "A network error caused the media download to fail part-way.": "Un error de red ha interrumpido la descarga del vídeo.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "No se ha podido cargar el vídeo debido a un fallo de red o del servidor o porque el formato es incompatible.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La reproducción de vídeo se ha interrumpido por un problema de corrupción de datos o porque el vídeo precisa funciones que su navegador no ofrece.",
+ "No compatible source was found for this media.": "No se ha encontrado ninguna fuente compatible con este vídeo.",
+ "Audio Player": "Reproductor de audio",
+ "Video Player": "Reproductor de video",
+ "Replay": "Volver a reproducir",
+ "Seek to live, currently behind live": "Buscar en vivo, actualmente demorado con respecto a la transmisión en vivo",
+ "Seek to live, currently playing live": "Buscar en vivo, actualmente reproduciendo en vivo",
+ "Progress Bar": "Barra de progreso",
+ "progress bar timing: currentTime={1} duration={2}": "{1} de {2}",
+ "Descriptions": "Descripciones",
+ "descriptions off": "descripciones desactivadas",
+ "Audio Track": "Pista de audio",
+ "Volume Level": "Nivel de volumen",
+ "The media is encrypted and we do not have the keys to decrypt it.": "El material audiovisual está cifrado y no tenemos las claves para descifrarlo.",
+ "Close": "Cerrar",
+ "Modal Window": "Ventana modal",
+ "This is a modal window": "Esta es una ventana modal",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Esta ventana modal puede cerrarse presionando la tecla Escape o activando el botón de cierre.",
+ ", opens captions settings dialog": ", abre el diálogo de configuración de leyendas",
+ ", opens subtitles settings dialog": ", abre el diálogo de configuración de subtítulos",
+ ", selected": ", seleccionado",
+ "Close Modal Dialog": "Cierra cuadro de diálogo modal",
+ ", opens descriptions settings dialog": ", abre el diálogo de configuración de las descripciones",
+ "captions settings": "configuración de leyendas",
+ "subtitles settings": "configuración de subtítulos",
+ "descriptions settings": "configuración de descripciones",
+ "Text": "Texto",
+ "White": "Blanco",
+ "Black": "Negro",
+ "Red": "Rojo",
+ "Green": "Verde",
+ "Blue": "Azul",
+ "Yellow": "Amarillo",
+ "Magenta": "Magenta",
+ "Cyan": "Cian",
+ "Background": "Fondo",
+ "Window": "Ventana",
+ "Transparent": "Transparente",
+ "Semi-Transparent": "Semitransparente",
+ "Opaque": "Opaca",
+ "Font Size": "Tamaño de fuente",
+ "Text Edge Style": "Estilo de borde del texto",
+ "None": "Ninguno",
+ "Raised": "En relieve",
+ "Depressed": "Hundido",
+ "Uniform": "Uniforme",
+ "Dropshadow": "Sombra paralela",
+ "Font Family": "Familia de fuente",
+ "Proportional Sans-Serif": "Sans-Serif proporcional",
+ "Monospace Sans-Serif": "Sans-Serif monoespacio",
+ "Proportional Serif": "Serif proporcional",
+ "Monospace Serif": "Serif monoespacio",
+ "Casual": "Informal",
+ "Script": "Cursiva",
+ "Small Caps": "Minúsculas",
+ "Reset": "Restablecer",
+ "restore all settings to the default values": "restablece todas las configuraciones a los valores predeterminados",
+ "Done": "Listo",
+ "Caption Settings Dialog": "Diálogo de configuración de leyendas",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Comienzo de la ventana de diálogo. La tecla Escape cancelará la operación y cerrará la ventana.",
+ "End of dialog window.": "Final de la ventana de diálogo.",
+ "{1} is loading.": "{1} se está cargando.",
+ "Exit Picture-in-Picture": "Salir de imagen sobre imagen",
+ "Picture-in-Picture": "Imagen sobre imagen"
+}
-videojs.addLanguage("fa",{
- "Play": "پخش",
- "Pause": "وقفه",
- "Current Time": "زمان کنونی",
- "Duration Time": "مدت زمان",
- "Remaining Time": "زمان باقیمانده",
- "Stream Type": "نوع استریم",
- "LIVE": "زنده",
- "Loaded": "فراخوانی شده",
- "Progress": "پیشرفت",
- "Fullscreen": "تمام صفحه",
- "Non-Fullscreen": "نمایش عادی",
- "Mute": "بی صدا",
- "Unmute": "بهمراه صدا",
- "Playback Rate": "سرعت پخش",
- "Subtitles": "زیرنویس",
- "subtitles off": "بدون زیرنویس",
- "Captions": "عنوان",
- "captions off": "بدون عنوان",
- "Chapters": "فصل",
- "You aborted the media playback": "شما پخش را متوقف کردید.",
- "A network error caused the media download to fail part-way.": "مشکل در دریافت ویدئو ...",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "فرمت پشتیبانی نمیشود یا خطایی روی داده است.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "مشکل در دریافت ویدئو ...",
- "No compatible source was found for this media.": "هیچ ورودی ای برای این رسانه شناسایی نشد."
+videojs.addLanguage('fa', {
+ "Audio Player": "پخش کننده صوت",
+ "Video Player": "پخش کننده ویدیو",
+ "Play": "پخش",
+ "Pause": "توقف",
+ "Replay": "پخش مجدد",
+ "Current Time": "زمان فعلی",
+ "Duration": "مدت",
+ "Remaining Time": "زمان باقیمانده",
+ "Stream Type": "نوع استریم",
+ "LIVE": "زنده",
+ "Seek to live, currently behind live": "پخش زنده، هم اکنون عقب تر از پخش زنده",
+ "Seek to live, currently playing live": "پخش زنده، در حال پخش زنده",
+ "Loaded": "بارگیری شده",
+ "Progress": "پیشرفت",
+ "Progress Bar": "نوار پیشرفت",
+ "progress bar timing: currentTime={1} duration={2}": "{1} از {2}",
+ "Fullscreen": "تمامصفحه",
+ "Non-Fullscreen": "غیر تمامصفحه",
+ "Mute": "بی صدا",
+ "Unmute": "صدادار",
+ "Playback Rate": "سرعت پخش",
+ "Subtitles": "زیرنویس ها",
+ "subtitles off": "بدون زیرنویس",
+ "Captions": "توضیحات",
+ "captions off": "بدون توضیحات",
+ "Chapters": "بخشها",
+ "Descriptions": "توصیفات",
+ "descriptions off": "بدون توصیفات",
+ "Audio Track": "ترَک صوتی",
+ "Volume Level": "سطح صدا",
+ "You aborted the media playback": "شما پخش رسانه را قطع نمودید",
+ "A network error caused the media download to fail part-way.": "وقوع مشکلی در شبکه باعث اختلال در دانلود رسانه شد.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": ".رسانه قابل بارگیری نیست. ممکن است مشکلی در شبکه یا سرور رخ داده باشد یا فرمت رسانه در دستگاه شما پشتیبانی نشود",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "پخش رسانه به علت اشکال در آن یا عدم پشتیبانی مرورگر شما قطع شد.",
+ "No compatible source was found for this media.": "هیچ منبع سازگاری برای پخش این رسانه پیدا نشد.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "این رسانه رمزنگاری شده است و کلیدهای رمزگشایی آن موجود نیست.",
+ "Play Video": "پخش ویدیو",
+ "Close": "بستن",
+ "Close Modal Dialog": "بستن پنجره",
+ "Modal Window": "پنجره محاوره",
+ "This is a modal window": "این پنجره قابل بستن است",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "این پنجره با کلید Escape یا دکمه بستن قابل بسته شدن میباشد.",
+ ", opens captions settings dialog": ", تنظیمات توضیجات را باز میکند",
+ ", opens subtitles settings dialog": ", تنظیمات زیرنویس را باز میکند",
+ ", opens descriptions settings dialog": ", تنظیمات توصیفات را باز میکند",
+ ", selected": "، انتخاب شد",
+ "captions settings": "تنظیمات توضیحات",
+ "subtitles settings": "تنظیمات زیرنویس",
+ "descriptions settings": "تنظیمات توصیفات",
+ "Text": "متن",
+ "White": "سفید",
+ "Black": "سیاه",
+ "Red": "قرمز",
+ "Green": "سبز",
+ "Blue": "آبی",
+ "Yellow": "زرد",
+ "Magenta": "ارغوانی",
+ "Cyan": "فیروزهای",
+ "Background": "پس زمینه",
+ "Window": "پنجره",
+ "Transparent": "شفاف",
+ "Semi-Transparent": "نیمه شفاف",
+ "Opaque": "مات",
+ "Font Size": "اندازه قلم",
+ "Text Edge Style": "سبک لبه متن",
+ "None": "هیچ",
+ "Raised": "برجسته",
+ "Depressed": "فرورفته",
+ "Uniform": "یکنواخت",
+ "Dropshadow": "سایه دار",
+ "Font Family": "نوع قلم",
+ "Proportional Sans-Serif": "Sans-Serif متناسب",
+ "Monospace Sans-Serif": "Sans-Serif هم عرض",
+ "Proportional Serif": "Serif متناسب",
+ "Monospace Serif": "Serif هم عرض",
+ "Casual": "فانتزی",
+ "Script": "دست خط",
+ "Small Caps": "حروف بزرگ کوچک",
+ "Reset": "تنظیم مجدد",
+ "restore all settings to the default values": "بازنشانی همه تنظیمات به مقادیر پیشفرض",
+ "Done": "انجام",
+ "Caption Settings Dialog": "پنجره تنظیمات توضیحات",
+ "Beginning of dialog window. Escape will cancel and close the window.": "شروع پنجره محاورهای. دکمه Escape عملیات را لغو کرده و پنجره را میبندد.",
+ "End of dialog window.": "پایان پنجره محاورهای.",
+ "{1} is loading.": "{1} در حال بارگیری است.",
+ "Exit Picture-in-Picture": "خروج از حالت تصویر در تصویر",
+ "Picture-in-Picture": "تصویر در تصویر"
});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "پخش کننده صوت",
+ "Video Player": "پخش کننده ویدیو",
+ "Play": "پخش",
+ "Pause": "توقف",
+ "Replay": "پخش مجدد",
+ "Current Time": "زمان فعلی",
+ "Duration": "مدت",
+ "Remaining Time": "زمان باقیمانده",
+ "Stream Type": "نوع استریم",
+ "LIVE": "زنده",
+ "Seek to live, currently behind live": "پخش زنده، هم اکنون عقب تر از پخش زنده",
+ "Seek to live, currently playing live": "پخش زنده، در حال پخش زنده",
+ "Loaded": "بارگیری شده",
+ "Progress": "پیشرفت",
+ "Progress Bar": "نوار پیشرفت",
+ "progress bar timing: currentTime={1} duration={2}": "{1} از {2}",
+ "Fullscreen": "تمامصفحه",
+ "Non-Fullscreen": "غیر تمامصفحه",
+ "Mute": "بی صدا",
+ "Unmute": "صدادار",
+ "Playback Rate": "سرعت پخش",
+ "Subtitles": "زیرنویس ها",
+ "subtitles off": "بدون زیرنویس",
+ "Captions": "توضیحات",
+ "captions off": "بدون توضیحات",
+ "Chapters": "بخشها",
+ "Descriptions": "توصیفات",
+ "descriptions off": "بدون توصیفات",
+ "Audio Track": "ترَک صوتی",
+ "Volume Level": "سطح صدا",
+ "You aborted the media playback": "شما پخش رسانه را قطع نمودید",
+ "A network error caused the media download to fail part-way.": "وقوع مشکلی در شبکه باعث اختلال در دانلود رسانه شد.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": ".رسانه قابل بارگیری نیست. ممکن است مشکلی در شبکه یا سرور رخ داده باشد یا فرمت رسانه در دستگاه شما پشتیبانی نشود",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "پخش رسانه به علت اشکال در آن یا عدم پشتیبانی مرورگر شما قطع شد.",
+ "No compatible source was found for this media.": "هیچ منبع سازگاری برای پخش این رسانه پیدا نشد.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "این رسانه رمزنگاری شده است و کلیدهای رمزگشایی آن موجود نیست.",
+ "Play Video": "پخش ویدیو",
+ "Close": "بستن",
+ "Close Modal Dialog": "بستن پنجره",
+ "Modal Window": "پنجره محاوره",
+ "This is a modal window": "این پنجره قابل بستن است",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "این پنجره با کلید Escape یا دکمه بستن قابل بسته شدن میباشد.",
+ ", opens captions settings dialog": ", تنظیمات توضیجات را باز میکند",
+ ", opens subtitles settings dialog": ", تنظیمات زیرنویس را باز میکند",
+ ", opens descriptions settings dialog": ", تنظیمات توصیفات را باز میکند",
+ ", selected": "، انتخاب شد",
+ "captions settings": "تنظیمات توضیحات",
+ "subtitles settings": "تنظیمات زیرنویس",
+ "descriptions settings": "تنظیمات توصیفات",
+ "Text": "متن",
+ "White": "سفید",
+ "Black": "سیاه",
+ "Red": "قرمز",
+ "Green": "سبز",
+ "Blue": "آبی",
+ "Yellow": "زرد",
+ "Magenta": "ارغوانی",
+ "Cyan": "فیروزهای",
+ "Background": "پس زمینه",
+ "Window": "پنجره",
+ "Transparent": "شفاف",
+ "Semi-Transparent": "نیمه شفاف",
+ "Opaque": "مات",
+ "Font Size": "اندازه قلم",
+ "Text Edge Style": "سبک لبه متن",
+ "None": "هیچ",
+ "Raised": "برجسته",
+ "Depressed": "فرورفته",
+ "Uniform": "یکنواخت",
+ "Dropshadow": "سایه دار",
+ "Font Family": "نوع قلم",
+ "Proportional Sans-Serif": "Sans-Serif متناسب",
+ "Monospace Sans-Serif": "Sans-Serif هم عرض",
+ "Proportional Serif": "Serif متناسب",
+ "Monospace Serif": "Serif هم عرض",
+ "Casual": "فانتزی",
+ "Script": "دست خط",
+ "Small Caps": "حروف بزرگ کوچک",
+ "Reset": "تنظیم مجدد",
+ "restore all settings to the default values": "بازنشانی همه تنظیمات به مقادیر پیشفرض",
+ "Done": "انجام",
+ "Caption Settings Dialog": "پنجره تنظیمات توضیحات",
+ "Beginning of dialog window. Escape will cancel and close the window.": "شروع پنجره محاورهای. دکمه Escape عملیات را لغو کرده و پنجره را میبندد.",
+ "End of dialog window.": "پایان پنجره محاورهای.",
+ "{1} is loading.": "{1} در حال بارگیری است.",
+ "Exit Picture-in-Picture": "خروج از حالت تصویر در تصویر",
+ "Picture-in-Picture": "تصویر در تصویر"
+}
-videojs.addLanguage("fi",{
- "Play": "Toisto",
- "Pause": "Tauko",
- "Current Time": "Tämänhetkinen aika",
- "Duration Time": "Kokonaisaika",
- "Remaining Time": "Jäljellä oleva aika",
- "Stream Type": "Lähetystyyppi",
- "LIVE": "LIVE",
- "Loaded": "Ladattu",
- "Progress": "Edistyminen",
- "Fullscreen": "Koko näyttö",
- "Non-Fullscreen": "Koko näyttö pois",
- "Mute": "Ääni pois",
- "Unmute": "Ääni päällä",
- "Playback Rate": "Toistonopeus",
- "Subtitles": "Tekstitys",
- "subtitles off": "Tekstitys pois",
- "Captions": "Tekstitys",
- "captions off": "Tekstitys pois",
- "Chapters": "Kappaleet",
- "You aborted the media playback": "Olet keskeyttänyt videotoiston.",
- "A network error caused the media download to fail part-way.": "Verkkovirhe keskeytti videon latauksen.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videon lataus ei onnistunut joko palvelin- tai verkkovirheestä tai väärästä formaatista johtuen.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videon toisto keskeytyi, koska media on vaurioitunut tai käyttää käyttää toimintoja, joita selaimesi ei tue.",
- "No compatible source was found for this media.": "Tälle videolle ei löytynyt yhteensopivaa lähdettä."
+videojs.addLanguage('fi', {
+ "Play": "Toisto",
+ "Pause": "Tauko",
+ "Current Time": "Tämänhetkinen aika",
+ "Duration": "Kokonaisaika",
+ "Remaining Time": "Jäljellä oleva aika",
+ "Stream Type": "Lähetystyyppi",
+ "LIVE": "LIVE",
+ "Loaded": "Ladattu",
+ "Progress": "Edistyminen",
+ "Fullscreen": "Koko näyttö",
+ "Non-Fullscreen": "Koko näyttö pois",
+ "Mute": "Ääni pois",
+ "Unmute": "Ääni päällä",
+ "Playback Rate": "Toistonopeus",
+ "Subtitles": "Tekstitys",
+ "subtitles off": "Tekstitys pois",
+ "Captions": "Tekstitys",
+ "captions off": "Tekstitys pois",
+ "Chapters": "Kappaleet",
+ "You aborted the media playback": "Olet keskeyttänyt videotoiston.",
+ "A network error caused the media download to fail part-way.": "Verkkovirhe keskeytti videon latauksen.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videon lataus ei onnistunut joko palvelin- tai verkkovirheestä tai väärästä formaatista johtuen.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videon toisto keskeytyi, koska media on vaurioitunut tai käyttää käyttää toimintoja, joita selaimesi ei tue.",
+ "No compatible source was found for this media.": "Tälle videolle ei löytynyt yhteensopivaa lähdettä."
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Toisto",
+ "Pause": "Tauko",
+ "Current Time": "Tämänhetkinen aika",
+ "Duration": "Kokonaisaika",
+ "Remaining Time": "Jäljellä oleva aika",
+ "Stream Type": "Lähetystyyppi",
+ "LIVE": "LIVE",
+ "Loaded": "Ladattu",
+ "Progress": "Edistyminen",
+ "Fullscreen": "Koko näyttö",
+ "Non-Fullscreen": "Koko näyttö pois",
+ "Mute": "Ääni pois",
+ "Unmute": "Ääni päällä",
+ "Playback Rate": "Toistonopeus",
+ "Subtitles": "Tekstitys",
+ "subtitles off": "Tekstitys pois",
+ "Captions": "Tekstitys",
+ "captions off": "Tekstitys pois",
+ "Chapters": "Kappaleet",
+ "You aborted the media playback": "Olet keskeyttänyt videotoiston.",
+ "A network error caused the media download to fail part-way.": "Verkkovirhe keskeytti videon latauksen.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videon lataus ei onnistunut joko palvelin- tai verkkovirheestä tai väärästä formaatista johtuen.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videon toisto keskeytyi, koska media on vaurioitunut tai käyttää käyttää toimintoja, joita selaimesi ei tue.",
+ "No compatible source was found for this media.": "Tälle videolle ei löytynyt yhteensopivaa lähdettä."
+}
-videojs.addLanguage("fr",{
- "Audio Player": "Lecteur audio",
- "Video Player": "Lecteur vidéo",
- "Play": "Lecture",
- "Pause": "Pause",
- "Replay": "Revoir",
- "Current Time": "Temps actuel",
- "Duration Time": "Durée",
- "Remaining Time": "Temps restant",
- "Stream Type": "Type de flux",
- "LIVE": "EN DIRECT",
- "Loaded": "Chargé",
- "Progress": "Progression",
- "Progress Bar": "Barre de progression",
- "progress bar timing: currentTime={1} duration={2}": "{1} de {2}",
- "Fullscreen": "Plein écran",
- "Non-Fullscreen": "Fenêtré",
- "Mute": "Sourdine",
- "Unmute": "Son activé",
- "Playback Rate": "Vitesse de lecture",
- "Subtitles": "Sous-titres",
- "subtitles off": "Sous-titres désactivés",
- "Captions": "Sous-titres transcrits",
- "captions off": "Sous-titres transcrits désactivés",
- "Chapters": "Chapitres",
- "Descriptions": "Descriptions",
- "descriptions off": "descriptions désactivées",
- "Audio Track": "Piste audio",
- "Volume Level": "Niveau de volume",
- "You aborted the media playback": "Vous avez interrompu la lecture de la vidéo.",
- "A network error caused the media download to fail part-way.": "Une erreur de réseau a interrompu le téléchargement de la vidéo.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Cette vidéo n'a pas pu être chargée, soit parce que le serveur ou le réseau a échoué ou parce que le format n'est pas reconnu.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La lecture de la vidéo a été interrompue à cause d'un problème de corruption ou parce que la vidéo utilise des fonctionnalités non prises en charge par votre navigateur.",
- "No compatible source was found for this media.": "Aucune source compatible n'a été trouvée pour cette vidéo.",
- "The media is encrypted and we do not have the keys to decrypt it.": "Le média est chiffré et nous n'avons pas les clés pour le déchiffrer.",
- "Play Video": "Lire la vidéo",
- "Close": "Fermer",
- "Close Modal Dialog": "Fermer la boîte de dialogue modale",
- "Modal Window": "Fenêtre modale",
- "This is a modal window": "Ceci est une fenêtre modale",
- "This modal can be closed by pressing the Escape key or activating the close button.": "Ce modal peut être fermé en appuyant sur la touche Échap ou activer le bouton de fermeture.",
- ", opens captions settings dialog": ", ouvrir les paramètres des sous-titres transcrits",
- ", opens subtitles settings dialog": ", ouvrir les paramètres des sous-titres",
- ", opens descriptions settings dialog": ", ouvrir les paramètres des descriptions",
- ", selected": ", sélectionné",
- "captions settings": "Paramètres des sous-titres transcrits",
- "subtitles settings": "Paramètres des sous-titres",
- "descriptions settings": "Paramètres des descriptions",
- "Text": "Texte",
- "White": "Blanc",
- "Black": "Noir",
- "Red": "Rouge",
- "Green": "Vert",
- "Blue": "Bleu",
- "Yellow": "Jaune",
- "Magenta": "Magenta",
- "Cyan": "Cyan",
- "Background": "Arrière-plan",
- "Window": "Fenêtre",
- "Transparent": "Transparent",
- "Semi-Transparent": "Semi-transparent",
- "Opaque": "Opaque",
- "Font Size": "Taille des caractères",
- "Text Edge Style": "Style des contours du texte",
- "None": "Aucun",
- "Raised": "Élevé",
- "Depressed": "Enfoncé",
- "Uniform": "Uniforme",
- "Dropshadow": "Ombre portée",
- "Font Family": "Famille de polices",
- "Proportional Sans-Serif": "Polices à chasse variable sans empattement (Proportional Sans-Serif)",
- "Monospace Sans-Serif": "Polices à chasse fixe sans empattement (Monospace Sans-Serif)",
- "Proportional Serif": "Polices à chasse variable avec empattement (Proportional Serif)",
- "Monospace Serif": "Polices à chasse fixe avec empattement (Monospace Serif)",
- "Casual": "Manuscrite",
- "Script": "Scripte",
- "Small Caps": "Petites capitales",
- "Reset": "Réinitialiser",
- "restore all settings to the default values": "Restaurer tous les paramètres aux valeurs par défaut",
- "Done": "Terminé",
- "Caption Settings Dialog": "Boîte de dialogue des paramètres des sous-titres transcrits",
- "Beginning of dialog window. Escape will cancel and close the window.": "Début de la fenêtre de dialogue. La touche d'échappement annulera et fermera la fenêtre.",
- "End of dialog window.": "Fin de la fenêtre de dialogue."
+videojs.addLanguage('fr', {
+ "Audio Player": "Lecteur audio",
+ "Video Player": "Lecteur vidéo",
+ "Play": "Lecture",
+ "Pause": "Pause",
+ "Replay": "Revoir",
+ "Current Time": "Temps actuel",
+ "Duration": "Durée",
+ "Remaining Time": "Temps restant",
+ "Stream Type": "Type de flux",
+ "LIVE": "EN DIRECT",
+ "Loaded": "Chargé",
+ "Progress": "Progression",
+ "Progress Bar": "Barre de progression",
+ "progress bar timing: currentTime={1} duration={2}": "{1} de {2}",
+ "Fullscreen": "Plein écran",
+ "Non-Fullscreen": "Fenêtré",
+ "Mute": "Sourdine",
+ "Unmute": "Son activé",
+ "Playback Rate": "Vitesse de lecture",
+ "Subtitles": "Sous-titres",
+ "subtitles off": "Sous-titres désactivés",
+ "Captions": "Sous-titres transcrits",
+ "captions off": "Sous-titres transcrits désactivés",
+ "Chapters": "Chapitres",
+ "Descriptions": "Descriptions",
+ "descriptions off": "descriptions désactivées",
+ "Audio Track": "Piste audio",
+ "Volume Level": "Niveau de volume",
+ "You aborted the media playback": "Vous avez interrompu la lecture de la vidéo.",
+ "A network error caused the media download to fail part-way.": "Une erreur de réseau a interrompu le téléchargement de la vidéo.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Cette vidéo n'a pas pu être chargée, soit parce que le serveur ou le réseau a échoué ou parce que le format n'est pas reconnu.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La lecture de la vidéo a été interrompue à cause d'un problème de corruption ou parce que la vidéo utilise des fonctionnalités non prises en charge par votre navigateur.",
+ "No compatible source was found for this media.": "Aucune source compatible n'a été trouvée pour cette vidéo.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Le média est chiffré et nous n'avons pas les clés pour le déchiffrer.",
+ "Play Video": "Lire la vidéo",
+ "Close": "Fermer",
+ "Close Modal Dialog": "Fermer la boîte de dialogue modale",
+ "Modal Window": "Fenêtre modale",
+ "This is a modal window": "Ceci est une fenêtre modale",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Ce modal peut être fermé en appuyant sur la touche Échap ou activer le bouton de fermeture.",
+ ", opens captions settings dialog": ", ouvrir les paramètres des sous-titres transcrits",
+ ", opens subtitles settings dialog": ", ouvrir les paramètres des sous-titres",
+ ", opens descriptions settings dialog": ", ouvrir les paramètres des descriptions",
+ ", selected": ", sélectionné",
+ "captions settings": "Paramètres des sous-titres transcrits",
+ "subtitles settings": "Paramètres des sous-titres",
+ "descriptions settings": "Paramètres des descriptions",
+ "Text": "Texte",
+ "White": "Blanc",
+ "Black": "Noir",
+ "Red": "Rouge",
+ "Green": "Vert",
+ "Blue": "Bleu",
+ "Yellow": "Jaune",
+ "Magenta": "Magenta",
+ "Cyan": "Cyan",
+ "Background": "Arrière-plan",
+ "Window": "Fenêtre",
+ "Transparent": "Transparent",
+ "Semi-Transparent": "Semi-transparent",
+ "Opaque": "Opaque",
+ "Font Size": "Taille des caractères",
+ "Text Edge Style": "Style des contours du texte",
+ "None": "Aucun",
+ "Raised": "Élevé",
+ "Depressed": "Enfoncé",
+ "Uniform": "Uniforme",
+ "Dropshadow": "Ombre portée",
+ "Font Family": "Famille de polices",
+ "Proportional Sans-Serif": "Polices à chasse variable sans empattement (Proportional Sans-Serif)",
+ "Monospace Sans-Serif": "Polices à chasse fixe sans empattement (Monospace Sans-Serif)",
+ "Proportional Serif": "Polices à chasse variable avec empattement (Proportional Serif)",
+ "Monospace Serif": "Polices à chasse fixe avec empattement (Monospace Serif)",
+ "Casual": "Manuscrite",
+ "Script": "Scripte",
+ "Small Caps": "Petites capitales",
+ "Reset": "Réinitialiser",
+ "restore all settings to the default values": "Restaurer tous les paramètres aux valeurs par défaut",
+ "Done": "Terminé",
+ "Caption Settings Dialog": "Boîte de dialogue des paramètres des sous-titres transcrits",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Début de la fenêtre de dialogue. La touche d'échappement annulera et fermera la fenêtre.",
+ "End of dialog window.": "Fin de la fenêtre de dialogue."
});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Lecteur audio",
+ "Video Player": "Lecteur vidéo",
+ "Play": "Lecture",
+ "Pause": "Pause",
+ "Replay": "Revoir",
+ "Current Time": "Temps actuel",
+ "Duration": "Durée",
+ "Remaining Time": "Temps restant",
+ "Stream Type": "Type de flux",
+ "LIVE": "EN DIRECT",
+ "Loaded": "Chargé",
+ "Progress": "Progression",
+ "Progress Bar": "Barre de progression",
+ "progress bar timing: currentTime={1} duration={2}": "{1} de {2}",
+ "Fullscreen": "Plein écran",
+ "Non-Fullscreen": "Fenêtré",
+ "Mute": "Sourdine",
+ "Unmute": "Son activé",
+ "Playback Rate": "Vitesse de lecture",
+ "Subtitles": "Sous-titres",
+ "subtitles off": "Sous-titres désactivés",
+ "Captions": "Sous-titres transcrits",
+ "captions off": "Sous-titres transcrits désactivés",
+ "Chapters": "Chapitres",
+ "Descriptions": "Descriptions",
+ "descriptions off": "descriptions désactivées",
+ "Audio Track": "Piste audio",
+ "Volume Level": "Niveau de volume",
+ "You aborted the media playback": "Vous avez interrompu la lecture de la vidéo.",
+ "A network error caused the media download to fail part-way.": "Une erreur de réseau a interrompu le téléchargement de la vidéo.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Cette vidéo n'a pas pu être chargée, soit parce que le serveur ou le réseau a échoué ou parce que le format n'est pas reconnu.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La lecture de la vidéo a été interrompue à cause d'un problème de corruption ou parce que la vidéo utilise des fonctionnalités non prises en charge par votre navigateur.",
+ "No compatible source was found for this media.": "Aucune source compatible n'a été trouvée pour cette vidéo.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Le média est chiffré et nous n'avons pas les clés pour le déchiffrer.",
+ "Play Video": "Lire la vidéo",
+ "Close": "Fermer",
+ "Close Modal Dialog": "Fermer la boîte de dialogue modale",
+ "Modal Window": "Fenêtre modale",
+ "This is a modal window": "Ceci est une fenêtre modale",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Ce modal peut être fermé en appuyant sur la touche Échap ou activer le bouton de fermeture.",
+ ", opens captions settings dialog": ", ouvrir les paramètres des sous-titres transcrits",
+ ", opens subtitles settings dialog": ", ouvrir les paramètres des sous-titres",
+ ", opens descriptions settings dialog": ", ouvrir les paramètres des descriptions",
+ ", selected": ", sélectionné",
+ "captions settings": "Paramètres des sous-titres transcrits",
+ "subtitles settings": "Paramètres des sous-titres",
+ "descriptions settings": "Paramètres des descriptions",
+ "Text": "Texte",
+ "White": "Blanc",
+ "Black": "Noir",
+ "Red": "Rouge",
+ "Green": "Vert",
+ "Blue": "Bleu",
+ "Yellow": "Jaune",
+ "Magenta": "Magenta",
+ "Cyan": "Cyan",
+ "Background": "Arrière-plan",
+ "Window": "Fenêtre",
+ "Transparent": "Transparent",
+ "Semi-Transparent": "Semi-transparent",
+ "Opaque": "Opaque",
+ "Font Size": "Taille des caractères",
+ "Text Edge Style": "Style des contours du texte",
+ "None": "Aucun",
+ "Raised": "Élevé",
+ "Depressed": "Enfoncé",
+ "Uniform": "Uniforme",
+ "Dropshadow": "Ombre portée",
+ "Font Family": "Famille de polices",
+ "Proportional Sans-Serif": "Polices à chasse variable sans empattement (Proportional Sans-Serif)",
+ "Monospace Sans-Serif": "Polices à chasse fixe sans empattement (Monospace Sans-Serif)",
+ "Proportional Serif": "Polices à chasse variable avec empattement (Proportional Serif)",
+ "Monospace Serif": "Polices à chasse fixe avec empattement (Monospace Serif)",
+ "Casual": "Manuscrite",
+ "Script": "Scripte",
+ "Small Caps": "Petites capitales",
+ "Reset": "Réinitialiser",
+ "restore all settings to the default values": "Restaurer tous les paramètres aux valeurs par défaut",
+ "Done": "Terminé",
+ "Caption Settings Dialog": "Boîte de dialogue des paramètres des sous-titres transcrits",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Début de la fenêtre de dialogue. La touche d'échappement annulera et fermera la fenêtre.",
+ "End of dialog window.": "Fin de la fenêtre de dialogue."
+}
--- /dev/null
+videojs.addLanguage('gd', {
+ "Audio Player": "Cluicheadair fuaime",
+ "Video Player": "Cluicheadair video",
+ "Play": "Cluich",
+ "Pause": "Cuir ’na stad",
+ "Replay": "Cluich a-rithist",
+ "Current Time": "An ùine làithreach",
+ "Duration": "Faide",
+ "Remaining Time": "An ùine air fhàgail",
+ "Stream Type": "Seòrsa an t-sruthaidh",
+ "LIVE": "BEÒ",
+ "Seek to live, currently behind live": "A’ sireadh sruth beò ’s air dheireadh",
+ "Seek to live, currently playing live": "A’ sireadh sruth beò ’s ‘ga chluich",
+ "Loaded": "Air a luchdadh",
+ "Progress": "Adhartas",
+ "Progress Bar": "Bàr adhartais",
+ "progress bar timing: currentTime={1} duration={2}": "{1} à {2}",
+ "Fullscreen": "Làn-sgrìn",
+ "Non-Fullscreen": "Fàg modh làn-sgrìn",
+ "Mute": "Mùch",
+ "Unmute": "Dì-mhùch",
+ "Playback Rate": "Reat na cluiche",
+ "Subtitles": "Fo-thiotalan",
+ "subtitles off": "fo-thiotalan dheth",
+ "Captions": "Caipseanan",
+ "captions off": "caipseanan dheth",
+ "Chapters": "Caibideil",
+ "Descriptions": "Tuairisgeulan",
+ "descriptions off": "tuairisgeulan dheth",
+ "Audio Track": "Traca fuaime",
+ "Volume Level": "Àirde na fuaime",
+ "You aborted the media playback": "Sguir thu de chluich a’ mheadhain",
+ "A network error caused the media download to fail part-way.": "Cha deach leinn an còrr dhen mheadhan a luchdadh a-nuas ri linn mearachd lìonraidh.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Cha b’ urrainn dhuinn am meadhan a luchdadh – dh’fhaoidte gun do dh’fhàillig leis an fhrithealaiche no an lìonra no nach cuir sinn taic ris an fhòrmat.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Sguir sinn de chluich a’ mheadhain – dh’fhaoidte gu bheil e coirbte no gu bheil gleus aig a’ mheadhan nach cuir am brabhsair taic ris.",
+ "No compatible source was found for this media.": "Cha ceach tùs co-chòrdail a lorg airson a’ mheadhain seo.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Tha am meadhan crioptaichte ’s chan eil iuchair dì-chrioptachaidh againn dha.",
+ "Play Video": "Cluich video",
+ "Close": "Dùin",
+ "Close Modal Dialog": "Dùin an còmhradh",
+ "Modal Window": "Uinneag mòdach",
+ "This is a modal window": "Seo uinneag mòdach",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "’S urrainn dhut seo a dhùnadh leis an iuchair Escape no leis a’ phutan dùnaidh.",
+ ", opens captions settings dialog": ", fosglaidh e còmhradh nan roghainnean",
+ ", opens subtitles settings dialog": ", fosglaidh e còmhradh nam fo-thiotalan",
+ ", opens descriptions settings dialog": ", fosglaidh e còmhradh roghainnean nan tuairisgeulan",
+ ", selected": ", air a thaghadh",
+ "captions settings": "roghainnean nan caipseanan",
+ "subtitles settings": "roghainnean nam fo-thiotalan",
+ "descriptions settings": "roghainnean nan tuairisgeulan",
+ "Text": "Teacsa",
+ "White": "Geal",
+ "Black": "Dubh",
+ "Red": "Dearg",
+ "Green": "Uaine",
+ "Blue": "Gorm",
+ "Yellow": "Buidhe",
+ "Magenta": "Magenta",
+ "Cyan": "Saidhean",
+ "Background": "Cùlaibh",
+ "Window": "Uinneag",
+ "Transparent": "Trìd-shoilleir",
+ "Semi-Transparent": "Leth-thrìd-shoilleir",
+ "Opaque": "Trìd-dhoilleir",
+ "Font Size": "Meud a’ chrutha-chlò",
+ "Text Edge Style": "Stoidhle oir an teacsa",
+ "None": "Chan eil gin",
+ "Raised": "Àrdaichte",
+ "Depressed": "Air a bhrùthadh",
+ "Uniform": "Cunbhalach",
+ "Dropshadow": "Sgàil",
+ "Font Family": "Teaghlach a’ chrutha-chlò",
+ "Proportional Sans-Serif": "Sans-serif co-rèireach",
+ "Monospace Sans-Serif": "Sans-serif aon-leud",
+ "Proportional Serif": "Serif co-rèireach",
+ "Monospace Serif": "Serif aon-leud",
+ "Casual": "Fuasgailte",
+ "Script": "Sgriobt",
+ "Small Caps": "Ceann-litrichean beaga",
+ "Reset": "Ath-shuidhich",
+ "restore all settings to the default values": "till dhan a h-uile bun-roghainn",
+ "Done": "Deiseil",
+ "Caption Settings Dialog": "Còmhradh roghainnean nan caipseanan",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Toiseach uinneag còmhraidh. Sguiridh Escape dheth ’s dùinidh e an uinneag",
+ "End of dialog window.": "Deireadh uinneag còmhraidh.",
+ "{1} is loading.": "Tha {1} ’ga luchdadh."
+});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Cluicheadair fuaime",
+ "Video Player": "Cluicheadair video",
+ "Play": "Cluich",
+ "Pause": "Cuir ’na stad",
+ "Replay": "Cluich a-rithist",
+ "Current Time": "An ùine làithreach",
+ "Duration": "Faide",
+ "Remaining Time": "An ùine air fhàgail",
+ "Stream Type": "Seòrsa an t-sruthaidh",
+ "LIVE": "BEÒ",
+ "Seek to live, currently behind live": "A’ sireadh sruth beò ’s air dheireadh",
+ "Seek to live, currently playing live": "A’ sireadh sruth beò ’s ‘ga chluich",
+ "Loaded": "Air a luchdadh",
+ "Progress": "Adhartas",
+ "Progress Bar": "Bàr adhartais",
+ "progress bar timing: currentTime={1} duration={2}": "{1} à {2}",
+ "Fullscreen": "Làn-sgrìn",
+ "Non-Fullscreen": "Fàg modh làn-sgrìn",
+ "Mute": "Mùch",
+ "Unmute": "Dì-mhùch",
+ "Playback Rate": "Reat na cluiche",
+ "Subtitles": "Fo-thiotalan",
+ "subtitles off": "fo-thiotalan dheth",
+ "Captions": "Caipseanan",
+ "captions off": "caipseanan dheth",
+ "Chapters": "Caibideil",
+ "Descriptions": "Tuairisgeulan",
+ "descriptions off": "tuairisgeulan dheth",
+ "Audio Track": "Traca fuaime",
+ "Volume Level": "Àirde na fuaime",
+ "You aborted the media playback": "Sguir thu de chluich a’ mheadhain",
+ "A network error caused the media download to fail part-way.": "Cha deach leinn an còrr dhen mheadhan a luchdadh a-nuas ri linn mearachd lìonraidh.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Cha b’ urrainn dhuinn am meadhan a luchdadh – dh’fhaoidte gun do dh’fhàillig leis an fhrithealaiche no an lìonra no nach cuir sinn taic ris an fhòrmat.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Sguir sinn de chluich a’ mheadhain – dh’fhaoidte gu bheil e coirbte no gu bheil gleus aig a’ mheadhan nach cuir am brabhsair taic ris.",
+ "No compatible source was found for this media.": "Cha ceach tùs co-chòrdail a lorg airson a’ mheadhain seo.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Tha am meadhan crioptaichte ’s chan eil iuchair dì-chrioptachaidh againn dha.",
+ "Play Video": "Cluich video",
+ "Close": "Dùin",
+ "Close Modal Dialog": "Dùin an còmhradh",
+ "Modal Window": "Uinneag mòdach",
+ "This is a modal window": "Seo uinneag mòdach",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "’S urrainn dhut seo a dhùnadh leis an iuchair Escape no leis a’ phutan dùnaidh.",
+ ", opens captions settings dialog": ", fosglaidh e còmhradh nan roghainnean",
+ ", opens subtitles settings dialog": ", fosglaidh e còmhradh nam fo-thiotalan",
+ ", opens descriptions settings dialog": ", fosglaidh e còmhradh roghainnean nan tuairisgeulan",
+ ", selected": ", air a thaghadh",
+ "captions settings": "roghainnean nan caipseanan",
+ "subtitles settings": "roghainnean nam fo-thiotalan",
+ "descriptions settings": "roghainnean nan tuairisgeulan",
+ "Text": "Teacsa",
+ "White": "Geal",
+ "Black": "Dubh",
+ "Red": "Dearg",
+ "Green": "Uaine",
+ "Blue": "Gorm",
+ "Yellow": "Buidhe",
+ "Magenta": "Magenta",
+ "Cyan": "Saidhean",
+ "Background": "Cùlaibh",
+ "Window": "Uinneag",
+ "Transparent": "Trìd-shoilleir",
+ "Semi-Transparent": "Leth-thrìd-shoilleir",
+ "Opaque": "Trìd-dhoilleir",
+ "Font Size": "Meud a’ chrutha-chlò",
+ "Text Edge Style": "Stoidhle oir an teacsa",
+ "None": "Chan eil gin",
+ "Raised": "Àrdaichte",
+ "Depressed": "Air a bhrùthadh",
+ "Uniform": "Cunbhalach",
+ "Dropshadow": "Sgàil",
+ "Font Family": "Teaghlach a’ chrutha-chlò",
+ "Proportional Sans-Serif": "Sans-serif co-rèireach",
+ "Monospace Sans-Serif": "Sans-serif aon-leud",
+ "Proportional Serif": "Serif co-rèireach",
+ "Monospace Serif": "Serif aon-leud",
+ "Casual": "Fuasgailte",
+ "Script": "Sgriobt",
+ "Small Caps": "Ceann-litrichean beaga",
+ "Reset": "Ath-shuidhich",
+ "restore all settings to the default values": "till dhan a h-uile bun-roghainn",
+ "Done": "Deiseil",
+ "Caption Settings Dialog": "Còmhradh roghainnean nan caipseanan",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Toiseach uinneag còmhraidh. Sguiridh Escape dheth ’s dùinidh e an uinneag",
+ "End of dialog window.": "Deireadh uinneag còmhraidh.",
+ "{1} is loading.": "Tha {1} ’ga luchdadh."
+}
-videojs.addLanguage("gl",{
- "Play": "Reprodución",
- "Play Video": "Reprodución Vídeo",
- "Pause": "Pausa",
- "Current Time": "Tempo reproducido",
- "Duration Time": "Duración total",
- "Remaining Time": "Tempo restante",
- "Stream Type": "Tipo de secuencia",
- "LIVE": "DIRECTO",
- "Loaded": "Cargado",
- "Progress": "Progreso",
- "Fullscreen": "Pantalla completa",
- "Non-Fullscreen": "Pantalla non completa",
- "Mute": "Silenciar",
- "Unmute": "Non silenciado",
- "Playback Rate": "Velocidade de reprodución",
- "Subtitles": "Subtítulos",
- "subtitles off": "Subtítulos desactivados",
- "Captions": "Subtítulos con lenda",
- "captions off": "Subtítulos con lenda desactivados",
- "Chapters": "Capítulos",
- "You aborted the media playback": "Interrompeches a reprodución do vídeo.",
- "A network error caused the media download to fail part-way.": "Un erro de rede interrompeu a descarga do vídeo.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Non se puido cargar o vídeo debido a un fallo de rede ou do servidor ou porque o formato é incompatible.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "A reproducción de vídeo interrompeuse por un problema de corrupción de datos ou porque o vídeo precisa funcións que o teu navegador non ofrece.",
- "No compatible source was found for this media.": "Non se atopou ningunha fonte compatible con este vídeo."
+videojs.addLanguage('gl', {
+ "Audio Player": "Reprodutor de son",
+ "Video Player": "Reprodutor de vídeo",
+ "Play": "Reproducir",
+ "Pause": "Pausa",
+ "Replay": "Repetir",
+ "Current Time": "Tempo reproducido",
+ "Duration": "Duración",
+ "Remaining Time": "Tempo restante",
+ "Stream Type": "Tipo de fluxo",
+ "LIVE": "EN DIRECTO",
+ "Seek to live, currently behind live": "Buscando directo, actualmente tras en directo",
+ "Seek to live, currently playing live": "Buscando directo, actualmente reproducindo en directo",
+ "Loaded": "Cargado",
+ "Progress": "Progresión",
+ "Progress Bar": "Barra de progreso",
+ "progress bar timing: currentTime={1} duration={2}": "{1} de {2}",
+ "Fullscreen": "Pantalla completa",
+ "Non-Fullscreen": "Xanela",
+ "Mute": "Silenciar",
+ "Unmute": "Son activado",
+ "Playback Rate": "Velocidade de reprodución",
+ "Subtitles": "Subtítulos",
+ "subtitles off": "subtítulos desactivados",
+ "Captions": "Subtítulos para xordos",
+ "captions off": "subtítulos para xordos desactivados",
+ "Chapters": "Capítulos",
+ "Descriptions": "Descricións",
+ "descriptions off": "descricións desactivadas",
+ "Audio Track": "Pista de son",
+ "Volume Level": "Nivel do volume",
+ "You aborted the media playback": "Vostede interrompeu a reprodución do medio.",
+ "A network error caused the media download to fail part-way.": "Un erro de rede interrompeu a descarga do medio.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Non foi posíbel cargar o medio por mor dun fallo de rede ou do servidor ou porque o formato non é compatíbel.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Interrompeuse a reprodución do medio por mor dun problema de estragamento dos datos ou porque o medio precisa funcións que o seu navegador non ofrece.",
+ "No compatible source was found for this media.": "Non se atopou ningunha orixe compatíbel con este vídeo.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "O medio está cifrado e non temos as chaves para descifralo .",
+ "Play Video": "Reproducir vídeo",
+ "Close": "Pechar",
+ "Close Modal Dialog": "Pechar a caixa de diálogo modal",
+ "Modal Window": "Xanela modal",
+ "This is a modal window": "Esta é unha xanela modal",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Este diálogo modal pódese pechar premendo a tecla Escape ou activando o botón de pechar.",
+ ", opens captions settings dialog": ", abre o diálogo de axustes dos subtítulos para xordos",
+ ", opens subtitles settings dialog": ", abre o diálogo de axustes dos subtítulos",
+ ", opens descriptions settings dialog": ", abre o diálogo de axustes das descricións",
+ ", selected": ", séleccionado",
+ "captions settings": "axustes dos subtítulos para xordos",
+ "subtitles settings": "axustes dos subtítulos",
+ "descriptions settings": "axustes das descricións",
+ "Text": "Texto",
+ "White": "Branco",
+ "Black": "Negro",
+ "Red": "Vermello",
+ "Green": "Verde",
+ "Blue": "Azul",
+ "Yellow": "Marelo",
+ "Magenta": "Maxenta",
+ "Cyan": "Cian",
+ "Background": "Fondo",
+ "Window": "Xanela",
+ "Transparent": "Transparente",
+ "Semi-Transparent": "Semi-transparente",
+ "Opaque": "Opaca",
+ "Font Size": "Tamaño das letras",
+ "Text Edge Style": "Estilo do bordos do texto",
+ "None": "Ningún",
+ "Raised": "Érguida",
+ "Depressed": "Caída",
+ "Uniform": "Uniforme",
+ "Dropshadow": "Sombra caída",
+ "Font Family": "Familia de letras",
+ "Proportional Sans-Serif": "Sans-Serif proporcional",
+ "Monospace Sans-Serif": "Sans-Serif monoespazo (caixa fixa)",
+ "Proportional Serif": "Serif proporcional",
+ "Monospace Serif": "Serif monoespazo (caixa fixa)",
+ "Casual": "Manuscrito",
+ "Script": "Itálica",
+ "Small Caps": "Pequenas maiúsculas",
+ "Reset": "Reiniciar",
+ "restore all settings to the default values": "restaurar todos os axustes aos valores predeterminados",
+ "Done": "Feito",
+ "Caption Settings Dialog": "Diálogo de axustes dos subtítulos para xordos",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Inicio da xanela de diálogo. A tecla Escape cancelará e pechará a xanela.",
+ "End of dialog window.": "Fin da xanela de diálogo.",
+ "{1} is loading.": "{1} está a cargar."
});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Reprodutor de son",
+ "Video Player": "Reprodutor de vídeo",
+ "Play": "Reproducir",
+ "Pause": "Pausa",
+ "Replay": "Repetir",
+ "Current Time": "Tempo reproducido",
+ "Duration": "Duración",
+ "Remaining Time": "Tempo restante",
+ "Stream Type": "Tipo de fluxo",
+ "LIVE": "EN DIRECTO",
+ "Seek to live, currently behind live": "Buscando directo, actualmente tras en directo",
+ "Seek to live, currently playing live": "Buscando directo, actualmente reproducindo en directo",
+ "Loaded": "Cargado",
+ "Progress": "Progresión",
+ "Progress Bar": "Barra de progreso",
+ "progress bar timing: currentTime={1} duration={2}": "{1} de {2}",
+ "Fullscreen": "Pantalla completa",
+ "Non-Fullscreen": "Xanela",
+ "Mute": "Silenciar",
+ "Unmute": "Son activado",
+ "Playback Rate": "Velocidade de reprodución",
+ "Subtitles": "Subtítulos",
+ "subtitles off": "subtítulos desactivados",
+ "Captions": "Subtítulos para xordos",
+ "captions off": "subtítulos para xordos desactivados",
+ "Chapters": "Capítulos",
+ "Descriptions": "Descricións",
+ "descriptions off": "descricións desactivadas",
+ "Audio Track": "Pista de son",
+ "Volume Level": "Nivel do volume",
+ "You aborted the media playback": "Vostede interrompeu a reprodución do medio.",
+ "A network error caused the media download to fail part-way.": "Un erro de rede interrompeu a descarga do medio.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Non foi posíbel cargar o medio por mor dun fallo de rede ou do servidor ou porque o formato non é compatíbel.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Interrompeuse a reprodución do medio por mor dun problema de estragamento dos datos ou porque o medio precisa funcións que o seu navegador non ofrece.",
+ "No compatible source was found for this media.": "Non se atopou ningunha orixe compatíbel con este vídeo.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "O medio está cifrado e non temos as chaves para descifralo .",
+ "Play Video": "Reproducir vídeo",
+ "Close": "Pechar",
+ "Close Modal Dialog": "Pechar a caixa de diálogo modal",
+ "Modal Window": "Xanela modal",
+ "This is a modal window": "Esta é unha xanela modal",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Este diálogo modal pódese pechar premendo a tecla Escape ou activando o botón de pechar.",
+ ", opens captions settings dialog": ", abre o diálogo de axustes dos subtítulos para xordos",
+ ", opens subtitles settings dialog": ", abre o diálogo de axustes dos subtítulos",
+ ", opens descriptions settings dialog": ", abre o diálogo de axustes das descricións",
+ ", selected": ", séleccionado",
+ "captions settings": "axustes dos subtítulos para xordos",
+ "subtitles settings": "axustes dos subtítulos",
+ "descriptions settings": "axustes das descricións",
+ "Text": "Texto",
+ "White": "Branco",
+ "Black": "Negro",
+ "Red": "Vermello",
+ "Green": "Verde",
+ "Blue": "Azul",
+ "Yellow": "Marelo",
+ "Magenta": "Maxenta",
+ "Cyan": "Cian",
+ "Background": "Fondo",
+ "Window": "Xanela",
+ "Transparent": "Transparente",
+ "Semi-Transparent": "Semi-transparente",
+ "Opaque": "Opaca",
+ "Font Size": "Tamaño das letras",
+ "Text Edge Style": "Estilo do bordos do texto",
+ "None": "Ningún",
+ "Raised": "Érguida",
+ "Depressed": "Caída",
+ "Uniform": "Uniforme",
+ "Dropshadow": "Sombra caída",
+ "Font Family": "Familia de letras",
+ "Proportional Sans-Serif": "Sans-Serif proporcional",
+ "Monospace Sans-Serif": "Sans-Serif monoespazo (caixa fixa)",
+ "Proportional Serif": "Serif proporcional",
+ "Monospace Serif": "Serif monoespazo (caixa fixa)",
+ "Casual": "Manuscrito",
+ "Script": "Itálica",
+ "Small Caps": "Pequenas maiúsculas",
+ "Reset": "Reiniciar",
+ "restore all settings to the default values": "restaurar todos os axustes aos valores predeterminados",
+ "Done": "Feito",
+ "Caption Settings Dialog": "Diálogo de axustes dos subtítulos para xordos",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Inicio da xanela de diálogo. A tecla Escape cancelará e pechará a xanela.",
+ "End of dialog window.": "Fin da xanela de diálogo.",
+ "{1} is loading.": "{1} está a cargar."
+}
-videojs.addLanguage("he",{
- "Audio Player": "נַגָּן שמע",
- "Video Player": "נַגָּן וידאו",
- "Play": "נַגֵּן",
- "Pause": "השהה",
- "Replay": "נַגֵּן שוב",
- "Current Time": "זמן נוכחי",
- "Duration Time": "זמן כולל",
- "Remaining Time": "זמן נותר",
- "Stream Type": "סוג Stream",
- "LIVE": "שידור חי",
- "Loaded": "נטען",
- "Progress": "התקדמות",
- "Progress Bar": "סרגל התקדמות",
- "progress bar timing: currentTime={1} duration={2}": "{1} מתוך {2}",
- "Fullscreen": "מסך מלא",
- "Non-Fullscreen": "מסך לא מלא",
- "Mute": "השתק",
- "Unmute": "בטל השתקה",
- "Playback Rate": "קצב ניגון",
- "Subtitles": "כתוביות",
- "subtitles off": "כתוביות כבויות",
- "Captions": "כיתובים",
- "captions off": "כיתובים כבויים",
- "Chapters": "פרקים",
- "Descriptions": "תיאורים",
- "descriptions off": "תיאורים כבויים",
- "Audio Track": "רצועת שמע",
- "Volume Level": "רמת ווליום",
- "You aborted the media playback": "ביטלת את השמעת המדיה",
- "A network error caused the media download to fail part-way.": "שגיאת רשת גרמה להורדת המדיה להיכשל באמצע.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "לא ניתן לטעון את המדיה, או מכיוון שהרשת או השרת כשלו או מכיוון שהפורמט אינו נתמך.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "השמעת המדיה בוטלה בשל בעית השחטת מידע או מכיוון שהמדיה עשתה שימוש בתכונות שהדפדפן שלך לא תמך בהן.",
- "No compatible source was found for this media.": "לא נמצא מקור תואם עבור מדיה זו.",
- "The media is encrypted and we do not have the keys to decrypt it.": "המדיה מוצפנת ואין בידינו את המפתח כדי לפענח אותה.",
- "Play Video": "נַגֵּן וידאו",
- "Close": "סְגוֹר",
- "Close Modal Dialog": "סְגוֹר דו-שיח מודאלי",
- "Modal Window": "חלון מודאלי",
- "This is a modal window": "זהו חלון מודאלי",
- "This modal can be closed by pressing the Escape key or activating the close button.": "ניתן לסגור חלון מודאלי זה ע\"י לחיצה על כפתור ה-Escape או הפעלת כפתור הסגירה.",
- ", opens captions settings dialog": ", פותח חלון הגדרות כיתובים",
- ", opens subtitles settings dialog": ", פותח חלון הגדרות כתוביות",
- ", opens descriptions settings dialog": ", פותח חלון הגדרות תיאורים",
- ", selected": ", נבחר/ו",
- "captions settings": "הגדרות כיתובים",
- "subtitles settings": "הגדרות כתוביות",
- "descriptions settings": "הגדרות תיאורים",
- "Text": "טקסט",
- "White": "לבן",
- "Black": "שחור",
- "Red": "אדום",
- "Green": "ירוק",
- "Blue": "כחול",
- "Yellow": "צהוב",
- "Magenta": "מַגֶ'נטָה",
- "Cyan": "טורקיז",
- "Background": "רקע",
- "Window": "חלון",
- "Transparent": "שקוף",
- "Semi-Transparent": "שקוף למחצה",
- "Opaque": "אָטוּם",
- "Font Size": "גודל גופן",
- "Text Edge Style": "סגנון קצוות טקסט",
- "None": "ללא",
- "Raised": "מורם",
- "Depressed": "מורד",
- "Uniform": "אחיד",
- "Dropshadow": "הטלת צל",
- "Font Family": "משפחת גופן",
- "Proportional Sans-Serif": "פרופורציוני וללא תגיות (Proportional Sans-Serif)",
- "Monospace Sans-Serif": "ברוחב אחיד וללא תגיות (Monospace Sans-Serif)",
- "Proportional Serif": "פרופורציוני ועם תגיות (Proportional Serif)",
- "Monospace Serif": "ברוחב אחיד ועם תגיות (Monospace Serif)",
- "Casual": "אַגָבִי",
- "Script": "תסריט",
- "Small Caps": "אותיות קטנות",
- "Reset": "אִפּוּס",
- "restore all settings to the default values": "שחזר את כל ההגדרות לערכי ברירת המחדל",
- "Done": "בוצע",
- "Caption Settings Dialog": "דו-שיח הגדרות כיתובים",
- "Beginning of dialog window. Escape will cancel and close the window.": "תחילת חלון דו-שיח. Escape יבטל ויסגור את החלון",
- "End of dialog window.": "סוף חלון דו-שיח."
+videojs.addLanguage('he', {
+ "Audio Player": "נַגָּן שמע",
+ "Video Player": "נַגָּן וידאו",
+ "Play": "נַגֵּן",
+ "Pause": "השהה",
+ "Replay": "נַגֵּן שוב",
+ "Current Time": "זמן נוכחי",
+ "Duration": "זמן כולל",
+ "Remaining Time": "זמן נותר",
+ "Stream Type": "סוג Stream",
+ "LIVE": "שידור חי",
+ "Loaded": "נטען",
+ "Progress": "התקדמות",
+ "Progress Bar": "סרגל התקדמות",
+ "progress bar timing: currentTime={1} duration={2}": "{1} מתוך {2}",
+ "Fullscreen": "מסך מלא",
+ "Non-Fullscreen": "מסך לא מלא",
+ "Mute": "השתק",
+ "Unmute": "בטל השתקה",
+ "Playback Rate": "קצב ניגון",
+ "Subtitles": "כתוביות",
+ "subtitles off": "כתוביות כבויות",
+ "Captions": "כיתובים",
+ "captions off": "כיתובים כבויים",
+ "Chapters": "פרקים",
+ "Descriptions": "תיאורים",
+ "descriptions off": "תיאורים כבויים",
+ "Audio Track": "רצועת שמע",
+ "Volume Level": "רמת ווליום",
+ "You aborted the media playback": "ביטלת את השמעת המדיה",
+ "A network error caused the media download to fail part-way.": "שגיאת רשת גרמה להורדת המדיה להיכשל באמצע.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "לא ניתן לטעון את המדיה, או מכיוון שהרשת או השרת כשלו או מכיוון שהפורמט אינו נתמך.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "השמעת המדיה בוטלה בשל בעית השחטת מידע או מכיוון שהמדיה עשתה שימוש בתכונות שהדפדפן שלך לא תמך בהן.",
+ "No compatible source was found for this media.": "לא נמצא מקור תואם עבור מדיה זו.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "המדיה מוצפנת ואין בידינו את המפתח כדי לפענח אותה.",
+ "Play Video": "נַגֵּן וידאו",
+ "Close": "סְגוֹר",
+ "Close Modal Dialog": "סְגוֹר דו-שיח מודאלי",
+ "Modal Window": "חלון מודאלי",
+ "This is a modal window": "זהו חלון מודאלי",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "ניתן לסגור חלון מודאלי זה ע\"י לחיצה על כפתור ה-Escape או הפעלת כפתור הסגירה.",
+ ", opens captions settings dialog": ", פותח חלון הגדרות כיתובים",
+ ", opens subtitles settings dialog": ", פותח חלון הגדרות כתוביות",
+ ", opens descriptions settings dialog": ", פותח חלון הגדרות תיאורים",
+ ", selected": ", נבחר/ו",
+ "captions settings": "הגדרות כיתובים",
+ "subtitles settings": "הגדרות כתוביות",
+ "descriptions settings": "הגדרות תיאורים",
+ "Text": "טקסט",
+ "White": "לבן",
+ "Black": "שחור",
+ "Red": "אדום",
+ "Green": "ירוק",
+ "Blue": "כחול",
+ "Yellow": "צהוב",
+ "Magenta": "מַגֶ'נטָה",
+ "Cyan": "טורקיז",
+ "Background": "רקע",
+ "Window": "חלון",
+ "Transparent": "שקוף",
+ "Semi-Transparent": "שקוף למחצה",
+ "Opaque": "אָטוּם",
+ "Font Size": "גודל גופן",
+ "Text Edge Style": "סגנון קצוות טקסט",
+ "None": "ללא",
+ "Raised": "מורם",
+ "Depressed": "מורד",
+ "Uniform": "אחיד",
+ "Dropshadow": "הטלת צל",
+ "Font Family": "משפחת גופן",
+ "Proportional Sans-Serif": "פרופורציוני וללא תגיות (Proportional Sans-Serif)",
+ "Monospace Sans-Serif": "ברוחב אחיד וללא תגיות (Monospace Sans-Serif)",
+ "Proportional Serif": "פרופורציוני ועם תגיות (Proportional Serif)",
+ "Monospace Serif": "ברוחב אחיד ועם תגיות (Monospace Serif)",
+ "Casual": "אַגָבִי",
+ "Script": "תסריט",
+ "Small Caps": "אותיות קטנות",
+ "Reset": "אִפּוּס",
+ "restore all settings to the default values": "שחזר את כל ההגדרות לערכי ברירת המחדל",
+ "Done": "בוצע",
+ "Caption Settings Dialog": "דו-שיח הגדרות כיתובים",
+ "Beginning of dialog window. Escape will cancel and close the window.": "תחילת חלון דו-שיח. Escape יבטל ויסגור את החלון",
+ "End of dialog window.": "סוף חלון דו-שיח."
});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "נַגָּן שמע",
+ "Video Player": "נַגָּן וידאו",
+ "Play": "נַגֵּן",
+ "Pause": "השהה",
+ "Replay": "נַגֵּן שוב",
+ "Current Time": "זמן נוכחי",
+ "Duration": "זמן כולל",
+ "Remaining Time": "זמן נותר",
+ "Stream Type": "סוג Stream",
+ "LIVE": "שידור חי",
+ "Loaded": "נטען",
+ "Progress": "התקדמות",
+ "Progress Bar": "סרגל התקדמות",
+ "progress bar timing: currentTime={1} duration={2}": "{1} מתוך {2}",
+ "Fullscreen": "מסך מלא",
+ "Non-Fullscreen": "מסך לא מלא",
+ "Mute": "השתק",
+ "Unmute": "בטל השתקה",
+ "Playback Rate": "קצב ניגון",
+ "Subtitles": "כתוביות",
+ "subtitles off": "כתוביות כבויות",
+ "Captions": "כיתובים",
+ "captions off": "כיתובים כבויים",
+ "Chapters": "פרקים",
+ "Descriptions": "תיאורים",
+ "descriptions off": "תיאורים כבויים",
+ "Audio Track": "רצועת שמע",
+ "Volume Level": "רמת ווליום",
+ "You aborted the media playback": "ביטלת את השמעת המדיה",
+ "A network error caused the media download to fail part-way.": "שגיאת רשת גרמה להורדת המדיה להיכשל באמצע.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "לא ניתן לטעון את המדיה, או מכיוון שהרשת או השרת כשלו או מכיוון שהפורמט אינו נתמך.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "השמעת המדיה בוטלה בשל בעית השחטת מידע או מכיוון שהמדיה עשתה שימוש בתכונות שהדפדפן שלך לא תמך בהן.",
+ "No compatible source was found for this media.": "לא נמצא מקור תואם עבור מדיה זו.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "המדיה מוצפנת ואין בידינו את המפתח כדי לפענח אותה.",
+ "Play Video": "נַגֵּן וידאו",
+ "Close": "סְגוֹר",
+ "Close Modal Dialog": "סְגוֹר דו-שיח מודאלי",
+ "Modal Window": "חלון מודאלי",
+ "This is a modal window": "זהו חלון מודאלי",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "ניתן לסגור חלון מודאלי זה ע\"י לחיצה על כפתור ה-Escape או הפעלת כפתור הסגירה.",
+ ", opens captions settings dialog": ", פותח חלון הגדרות כיתובים",
+ ", opens subtitles settings dialog": ", פותח חלון הגדרות כתוביות",
+ ", opens descriptions settings dialog": ", פותח חלון הגדרות תיאורים",
+ ", selected": ", נבחר/ו",
+ "captions settings": "הגדרות כיתובים",
+ "subtitles settings": "הגדרות כתוביות",
+ "descriptions settings": "הגדרות תיאורים",
+ "Text": "טקסט",
+ "White": "לבן",
+ "Black": "שחור",
+ "Red": "אדום",
+ "Green": "ירוק",
+ "Blue": "כחול",
+ "Yellow": "צהוב",
+ "Magenta": "מַגֶ'נטָה",
+ "Cyan": "טורקיז",
+ "Background": "רקע",
+ "Window": "חלון",
+ "Transparent": "שקוף",
+ "Semi-Transparent": "שקוף למחצה",
+ "Opaque": "אָטוּם",
+ "Font Size": "גודל גופן",
+ "Text Edge Style": "סגנון קצוות טקסט",
+ "None": "ללא",
+ "Raised": "מורם",
+ "Depressed": "מורד",
+ "Uniform": "אחיד",
+ "Dropshadow": "הטלת צל",
+ "Font Family": "משפחת גופן",
+ "Proportional Sans-Serif": "פרופורציוני וללא תגיות (Proportional Sans-Serif)",
+ "Monospace Sans-Serif": "ברוחב אחיד וללא תגיות (Monospace Sans-Serif)",
+ "Proportional Serif": "פרופורציוני ועם תגיות (Proportional Serif)",
+ "Monospace Serif": "ברוחב אחיד ועם תגיות (Monospace Serif)",
+ "Casual": "אַגָבִי",
+ "Script": "תסריט",
+ "Small Caps": "אותיות קטנות",
+ "Reset": "אִפּוּס",
+ "restore all settings to the default values": "שחזר את כל ההגדרות לערכי ברירת המחדל",
+ "Done": "בוצע",
+ "Caption Settings Dialog": "דו-שיח הגדרות כיתובים",
+ "Beginning of dialog window. Escape will cancel and close the window.": "תחילת חלון דו-שיח. Escape יבטל ויסגור את החלון",
+ "End of dialog window.": "סוף חלון דו-שיח."
+}
--- /dev/null
+videojs.addLanguage('hi', {
+ "Audio Player": "ऑडियो प्लेयर",
+ "Video Player": "वीडियो प्लेयर",
+ "Play": "चलाएँ",
+ "Pause": "रोके",
+ "Replay": "फिर से चलाएँ",
+ "Current Time": "वर्तमान समय",
+ "Duration": "अवधि",
+ "Remaining Time": "शेष समय",
+ "Stream Type": "स्ट्रीम प्रकार",
+ "LIVE": "लाइव",
+ "Seek to live, currently behind live": "छोड़कर लाइव प्रसारण पर आगे बढ़ें, अभी लाइव प्रसारण से पीछे हैं",
+ "Seek to live, currently playing live": "छोड़कर लाइव प्रसारण पर आगे बढ़ें, अभी लाइव चल रहा है",
+ "Loaded": "लोड हुआ",
+ "Progress": "प्रगति",
+ "Progress Bar": "प्रोगेस बार",
+ "progress bar timing: currentTime={1} duration={2}": "{2} में से {1}",
+ "Fullscreen": "फ़ुल स्क्रीन",
+ "Non-Fullscreen": "फ़ुल स्क्रीन से बाहर निकलें",
+ "Mute": "म्यूट करें",
+ "Unmute": "अनम्यूट करें",
+ "Playback Rate": "चलाने की दर",
+ "Subtitles": "उपशीर्षक",
+ "subtitles off": "उपशीर्षक बंद",
+ "Captions": "कैप्शन",
+ "captions off": "कैप्शन बंद",
+ "Chapters": "अध्याय",
+ "Descriptions": "विवरण",
+ "descriptions off": "विवरण बंद",
+ "Audio Track": "ऑडियो ट्रैक",
+ "Volume Level": "वॉल्यूम स्तर",
+ "You aborted the media playback": "आपने मीडिया प्लेबैक को रोक दिया",
+ "A network error caused the media download to fail part-way.": "एक नेटवर्क त्रुटि के कारण मीडिया डाउनलोड आंशिक रूप से विफल हो गया।",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "मीडिया लोड नहीं किया जा सका, या तो सर्वर या नेटवर्क विफल होने के कारण या प्रारूप समर्थित नहीं होने के कारण।",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "मीडिया प्लेबैक निरस्त कर दिया गया, कारण: दूषण की समस्या या मीडिया ने उन सुविधाओं का उपयोग किया था जिनका आपके ब्राउज़र ने समर्थन नहीं किया।",
+ "No compatible source was found for this media.": "इस मीडिया के लिए कोई अनुकूल स्रोत नहीं मिला।.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "मीडिया एन्क्रिप्टेड है और हमारे पास इसे डिक्रिप्ट करने की चाबी नहीं है।",
+ "Play Video": "वीडियो चलाएं",
+ "Close": "बंद करे",
+ "Close Modal Dialog": "मोडल डायलॉग बंद करें",
+ "Modal Window": "मोडल विंडो",
+ "This is a modal window": "यह एक मोडल विंडो है",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "इस मोडल को एस्केप कुंजी दबाकर या बंद करें बटन को सक्रिय करके बंद किया जा सकता है।",
+ ", opens captions settings dialog": ", कैप्शन सेटिंग डायलॉग खोलता है",
+ ", opens subtitles settings dialog": ", उपशीर्षक सेटिंग्स संवाद खोलता है",
+ ", opens descriptions settings dialog": ", विवरण सेटिंग संवाद खोलता है",
+ ", selected": ", चुना गया",
+ "captions settings": "कैप्शन सेटिंग",
+ "subtitles settings": "उपशीर्षक सेटिंग",
+ "descriptions settings": "विवरण सेटिंग",
+ "Text": "टेक्स्ट",
+ "White": "सफेद",
+ "Black": "काला",
+ "Red": "लाल",
+ "Green": "हरा",
+ "Blue": "नीला",
+ "Yellow": "पीला",
+ "Magenta": "मैजेंटा",
+ "Cyan": "सियान",
+ "Background": "बैकग्राउंड",
+ "Window": "विंडो",
+ "Transparent": "पारदर्शी",
+ "Semi-Transparent": "अर्द्ध पारदर्शी",
+ "Opaque": "अपारदर्शी",
+ "Font Size": "फ़ॉन्ट आकार",
+ "Text Edge Style": "टेक्स्ट एज स्टाइल",
+ "None": "कोई नहीं",
+ "Raised": "उठा हुआ",
+ "Depressed": "उदास",
+ "Uniform": "वर्दी",
+ "Dropshadow": "परछाई",
+ "Font Family": "फॉण्ट परिवार",
+ "Proportional Sans-Serif": "प्रोपोरशनल साँस-सेरिफ",
+ "Monospace Sans-Serif": "मोनोस्पास साँस-सेरिफ",
+ "Proportional Serif": "प्रोपोरशनल सेरिफ",
+ "Monospace Serif": "मोनोस्पास सेरिफ",
+ "Casual": "आकस्मिक",
+ "Script": "स्क्रिप्ट",
+ "Small Caps": "छोटे अक्षर",
+ "Reset": "रीसेट करें",
+ "restore all settings to the default values": "सभी सेटिंग्स को डिफ़ॉल्ट मानों पर पुनर्स्थापित करें",
+ "Done": "पूर्ण",
+ "Caption Settings Dialog": "कैप्शन सेटिंग्स डायलॉग",
+ "Beginning of dialog window. Escape will cancel and close the window.": "डायलॉग विंडो की शुरुआत। एस्केप विंडो को रद्द और बंद कर देगा।",
+ "End of dialog window.": "संवाद विंडो का अंत।",
+ "{1} is loading.": "{1} लोड हो रहा है।",
+ "Exit Picture-in-Picture": "पिक्चर-इन-पिक्चर से बाहर निकलें",
+ "Picture-in-Picture": "पिक्चर-इन-पिक्चर"
+});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "ऑडियो प्लेयर",
+ "Video Player": "वीडियो प्लेयर",
+ "Play": "चलाएँ",
+ "Pause": "रोके",
+ "Replay": "फिर से चलाएँ",
+ "Current Time": "वर्तमान समय",
+ "Duration": "अवधि",
+ "Remaining Time": "शेष समय",
+ "Stream Type": "स्ट्रीम प्रकार",
+ "LIVE": "लाइव",
+ "Seek to live, currently behind live": "छोड़कर लाइव प्रसारण पर आगे बढ़ें, अभी लाइव प्रसारण से पीछे हैं",
+ "Seek to live, currently playing live": "छोड़कर लाइव प्रसारण पर आगे बढ़ें, अभी लाइव चल रहा है",
+ "Loaded": "लोड हुआ",
+ "Progress": "प्रगति",
+ "Progress Bar": "प्रोगेस बार",
+ "progress bar timing: currentTime={1} duration={2}": "{2} में से {1}",
+ "Fullscreen": "फ़ुल स्क्रीन",
+ "Non-Fullscreen": "फ़ुल स्क्रीन से बाहर निकलें",
+ "Mute": "म्यूट करें",
+ "Unmute": "अनम्यूट करें",
+ "Playback Rate": "चलाने की दर",
+ "Subtitles": "उपशीर्षक",
+ "subtitles off": "उपशीर्षक बंद",
+ "Captions": "कैप्शन",
+ "captions off": "कैप्शन बंद",
+ "Chapters": "अध्याय",
+ "Descriptions": "विवरण",
+ "descriptions off": "विवरण बंद",
+ "Audio Track": "ऑडियो ट्रैक",
+ "Volume Level": "वॉल्यूम स्तर",
+ "You aborted the media playback": "आपने मीडिया प्लेबैक को रोक दिया",
+ "A network error caused the media download to fail part-way.": "एक नेटवर्क त्रुटि के कारण मीडिया डाउनलोड आंशिक रूप से विफल हो गया।",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "मीडिया लोड नहीं किया जा सका, या तो सर्वर या नेटवर्क विफल होने के कारण या प्रारूप समर्थित नहीं होने के कारण।",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "मीडिया प्लेबैक निरस्त कर दिया गया, कारण: दूषण की समस्या या मीडिया ने उन सुविधाओं का उपयोग किया था जिनका आपके ब्राउज़र ने समर्थन नहीं किया।",
+ "No compatible source was found for this media.": "इस मीडिया के लिए कोई अनुकूल स्रोत नहीं मिला।.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "मीडिया एन्क्रिप्टेड है और हमारे पास इसे डिक्रिप्ट करने की चाबी नहीं है।",
+ "Play Video": "वीडियो चलाएं",
+ "Close": "बंद करे",
+ "Close Modal Dialog": "मोडल डायलॉग बंद करें",
+ "Modal Window": "मोडल विंडो",
+ "This is a modal window": "यह एक मोडल विंडो है",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "इस मोडल को एस्केप कुंजी दबाकर या बंद करें बटन को सक्रिय करके बंद किया जा सकता है।",
+ ", opens captions settings dialog": ", कैप्शन सेटिंग डायलॉग खोलता है",
+ ", opens subtitles settings dialog": ", उपशीर्षक सेटिंग्स संवाद खोलता है",
+ ", opens descriptions settings dialog": ", विवरण सेटिंग संवाद खोलता है",
+ ", selected": ", चुना गया",
+ "captions settings": "कैप्शन सेटिंग",
+ "subtitles settings": "उपशीर्षक सेटिंग",
+ "descriptions settings": "विवरण सेटिंग",
+ "Text": "टेक्स्ट",
+ "White": "सफेद",
+ "Black": "काला",
+ "Red": "लाल",
+ "Green": "हरा",
+ "Blue": "नीला",
+ "Yellow": "पीला",
+ "Magenta": "मैजेंटा",
+ "Cyan": "सियान",
+ "Background": "बैकग्राउंड",
+ "Window": "विंडो",
+ "Transparent": "पारदर्शी",
+ "Semi-Transparent": "अर्द्ध पारदर्शी",
+ "Opaque": "अपारदर्शी",
+ "Font Size": "फ़ॉन्ट आकार",
+ "Text Edge Style": "टेक्स्ट एज स्टाइल",
+ "None": "कोई नहीं",
+ "Raised": "उठा हुआ",
+ "Depressed": "उदास",
+ "Uniform": "वर्दी",
+ "Dropshadow": "परछाई",
+ "Font Family": "फॉण्ट परिवार",
+ "Proportional Sans-Serif": "प्रोपोरशनल साँस-सेरिफ",
+ "Monospace Sans-Serif": "मोनोस्पास साँस-सेरिफ",
+ "Proportional Serif": "प्रोपोरशनल सेरिफ",
+ "Monospace Serif": "मोनोस्पास सेरिफ",
+ "Casual": "आकस्मिक",
+ "Script": "स्क्रिप्ट",
+ "Small Caps": "छोटे अक्षर",
+ "Reset": "रीसेट करें",
+ "restore all settings to the default values": "सभी सेटिंग्स को डिफ़ॉल्ट मानों पर पुनर्स्थापित करें",
+ "Done": "पूर्ण",
+ "Caption Settings Dialog": "कैप्शन सेटिंग्स डायलॉग",
+ "Beginning of dialog window. Escape will cancel and close the window.": "डायलॉग विंडो की शुरुआत। एस्केप विंडो को रद्द और बंद कर देगा।",
+ "End of dialog window.": "संवाद विंडो का अंत।",
+ "{1} is loading.": "{1} लोड हो रहा है।",
+ "Exit Picture-in-Picture": "पिक्चर-इन-पिक्चर से बाहर निकलें",
+ "Picture-in-Picture": "पिक्चर-इन-पिक्चर"
+}
-videojs.addLanguage("hr",{
- "Play": "Pusti",
- "Pause": "Pauza",
- "Current Time": "Trenutno vrijeme",
- "Duration Time": "Vrijeme trajanja",
- "Remaining Time": "Preostalo vrijeme",
- "Stream Type": "Način strimovanja",
- "LIVE": "UŽIVO",
- "Loaded": "Učitan",
- "Progress": "Progres",
- "Fullscreen": "Puni ekran",
- "Non-Fullscreen": "Mali ekran",
- "Mute": "Prigušen",
- "Unmute": "Ne-prigušen",
- "Playback Rate": "Stopa reprodukcije",
- "Subtitles": "Podnaslov",
- "subtitles off": "Podnaslov deaktiviran",
- "Captions": "Titlovi",
- "captions off": "Titlovi deaktivirani",
- "Chapters": "Poglavlja",
- "You aborted the media playback": "Isključili ste reprodukciju videa.",
- "A network error caused the media download to fail part-way.": "Video se prestao preuzimati zbog greške na mreži.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video se ne može reproducirati zbog servera, greške u mreži ili je format ne podržan.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Reprodukcija videa je zaustavljenja zbog greške u formatu ili zbog verzije vašeg pretraživača.",
- "No compatible source was found for this media.": "Nije nađen nijedan kompatibilan izvor ovog videa."
+videojs.addLanguage('hr', {
+ "Play": "Pusti",
+ "Pause": "Pauza",
+ "Current Time": "Trenutno vrijeme",
+ "Duration": "Vrijeme trajanja",
+ "Remaining Time": "Preostalo vrijeme",
+ "Stream Type": "Način strimovanja",
+ "LIVE": "UŽIVO",
+ "Loaded": "Učitan",
+ "Progress": "Progres",
+ "Fullscreen": "Puni ekran",
+ "Non-Fullscreen": "Mali ekran",
+ "Mute": "Prigušen",
+ "Unmute": "Ne-prigušen",
+ "Playback Rate": "Stopa reprodukcije",
+ "Subtitles": "Podnaslov",
+ "subtitles off": "Podnaslov deaktiviran",
+ "Captions": "Titlovi",
+ "captions off": "Titlovi deaktivirani",
+ "Chapters": "Poglavlja",
+ "You aborted the media playback": "Isključili ste reprodukciju videa.",
+ "A network error caused the media download to fail part-way.": "Video se prestao preuzimati zbog greške na mreži.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video se ne može reproducirati zbog servera, greške u mreži ili je format ne podržan.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Reprodukcija videa je zaustavljenja zbog greške u formatu ili zbog verzije vašeg pretraživača.",
+ "No compatible source was found for this media.": "Nije nađen nijedan kompatibilan izvor ovog videa."
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Pusti",
+ "Pause": "Pauza",
+ "Current Time": "Trenutno vrijeme",
+ "Duration": "Vrijeme trajanja",
+ "Remaining Time": "Preostalo vrijeme",
+ "Stream Type": "Način strimovanja",
+ "LIVE": "UŽIVO",
+ "Loaded": "Učitan",
+ "Progress": "Progres",
+ "Fullscreen": "Puni ekran",
+ "Non-Fullscreen": "Mali ekran",
+ "Mute": "Prigušen",
+ "Unmute": "Ne-prigušen",
+ "Playback Rate": "Stopa reprodukcije",
+ "Subtitles": "Podnaslov",
+ "subtitles off": "Podnaslov deaktiviran",
+ "Captions": "Titlovi",
+ "captions off": "Titlovi deaktivirani",
+ "Chapters": "Poglavlja",
+ "You aborted the media playback": "Isključili ste reprodukciju videa.",
+ "A network error caused the media download to fail part-way.": "Video se prestao preuzimati zbog greške na mreži.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video se ne može reproducirati zbog servera, greške u mreži ili je format ne podržan.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Reprodukcija videa je zaustavljenja zbog greške u formatu ili zbog verzije vašeg pretraživača.",
+ "No compatible source was found for this media.": "Nije nađen nijedan kompatibilan izvor ovog videa."
+}
-videojs.addLanguage("hu",{
- "Play": "Lejátszás",
- "Pause": "Szünet",
- "Current Time": "Aktuális időpont",
- "Duration Time": "Hossz",
- "Remaining Time": "Hátralévő idő",
- "Stream Type": "Adatfolyam típusa",
- "LIVE": "ÉLŐ",
- "Loaded": "Betöltve",
- "Progress": "Állapot",
- "Fullscreen": "Teljes képernyő",
- "Non-Fullscreen": "Normál méret",
- "Mute": "Némítás",
- "Unmute": "Némítás kikapcsolva",
- "Playback Rate": "Lejátszási sebesség",
- "Subtitles": "Feliratok",
- "subtitles off": "Feliratok kikapcsolva",
- "Captions": "Magyarázó szöveg",
- "captions off": "Magyarázó szöveg kikapcsolva",
- "Chapters": "Fejezetek",
- "You aborted the media playback": "Leállította a lejátszást",
- "A network error caused the media download to fail part-way.": "Hálózati hiba miatt a videó részlegesen töltődött le.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "A videó nem tölthető be hálózati vagy kiszolgálói hiba miatt, vagy a formátuma nem támogatott.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "A lejátszás adatsérülés miatt leállt, vagy a videó egyes tulajdonságait a böngészője nem támogatja.",
- "No compatible source was found for this media.": "Nincs kompatibilis forrás ehhez a videóhoz."
+videojs.addLanguage('hu', {
+ "Play": "Lejátszás",
+ "Pause": "Szünet",
+ "Current Time": "Aktuális időpont",
+ "Duration": "Hossz",
+ "Remaining Time": "Hátralévő idő",
+ "Stream Type": "Adatfolyam típusa",
+ "LIVE": "ÉLŐ",
+ "Loaded": "Betöltve",
+ "Progress": "Állapot",
+ "Fullscreen": "Teljes képernyő",
+ "Non-Fullscreen": "Normál méret",
+ "Mute": "Némítás",
+ "Unmute": "Némítás kikapcsolva",
+ "Playback Rate": "Lejátszási sebesség",
+ "Subtitles": "Feliratok",
+ "subtitles off": "Feliratok kikapcsolva",
+ "Captions": "Magyarázó szöveg",
+ "captions off": "Magyarázó szöveg kikapcsolva",
+ "Chapters": "Fejezetek",
+ "You aborted the media playback": "Leállította a lejátszást",
+ "A network error caused the media download to fail part-way.": "Hálózati hiba miatt a videó részlegesen töltődött le.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "A videó nem tölthető be hálózati vagy kiszolgálói hiba miatt, vagy a formátuma nem támogatott.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "A lejátszás adatsérülés miatt leállt, vagy a videó egyes tulajdonságait a böngészője nem támogatja.",
+ "No compatible source was found for this media.": "Nincs kompatibilis forrás ehhez a videóhoz.",
+ "Audio Player": "Audio lejátszó",
+ "Video Player": "Videó lejátszó",
+ "Replay": "Visszajátszás",
+ "Descriptions": "Leírások",
+ "descriptions off": "leírások kikapcsolva",
+ "Audio Track": "Hangsáv",
+ "Volume Level": "Hangerő",
+ "Play Video": "Videó lejátszása",
+ "Close": "Bezárás",
+ "Text": "Szöveg",
+ "White": "Fehér",
+ "Black": "Fekete",
+ "Red": "Piros",
+ "Green": "Zöld",
+ "Blue": "Kék",
+ "Yellow": "Sárga",
+ "Background": "Háttér",
+ "Window": "Ablak",
+ "Transparent": "Átlátszó",
+ "Semi-Transparent": "Félig átlátszó",
+ "Opaque": "Áttetsző",
+ "Font Size": "Betűméret",
+ "Font Family": "Betűtípus",
+ "Done": "Kész",
+ "Picture-in-Picture": "Kép a képben",
+ "Exit Picture-in-Picture": "Kilépés kép a képben módból",
+ "{1} is loading.": "{1} betöltése.",
+ "Reset": "Visszaállítás",
+ "restore all settings to the default values": "összes beállítás visszaállítása az alapértelmezett értékekre",
+ "The media is encrypted and we do not have the keys to decrypt it.": "A média titkosítva van és nincsenek kulcsok a visszafejtéshez.",
+ "Close Modal Dialog": "Felugró ablak bezárása",
+ "Modal Window": "Felugró ablak",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Ezt a felugró ablakot az Escape gomb megnyomásával vagy a bezáró gomb aktiválásával lehet bezárni.",
+ ", selected": ", kiválasztva",
+ "descriptions settings": "leírások beállítása",
+ "Text Edge Style": "Szövegél stílus",
+ "This is a modal window": "Ez egy felugró ablak",
+ "Cyan": "Cián",
+ "Dropshadow": "Árnyék",
+ "End of dialog window.": "Párbeszédablak vége.",
+ "Progress Bar": "Folyamatjelző sáv",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Párbeszédablak eleje. Az Escape gomb befejezi és bezárja az ablakot.",
+ "Caption Settings Dialog": "Feliratbeállítások párbeszédablak",
+ ", opens descriptions settings dialog": ", megnyitja a leírások beállításainak párbeszédablakját",
+ ", opens captions settings dialog": ", megnyitja a magyarázó szövegek beállításainak párbeszédablakját",
+ ", opens subtitles settings dialog": ", megnyitja a feliratok beállításainak párbeszédablakját",
+ "Seek to live, currently behind live": "Élő adáshoz tekerés, jelenleg az élő adás mögött van",
+ "Seek to live, currently playing live": "Élő adáshoz tekerés, jelenleg az élő adásnál van",
+ "progress bar timing: currentTime={1} duration={2}": "{1} / {2}",
+ "Magenta": "Lila",
+ "Script": "Script",
+ "Casual": "Casual",
+ "Monospace Serif": "Monospace Serif",
+ "Monospace Sans-Serif": "Monospace Sans-Serif",
+ "Proportional Sans-Serif": "Proportional Sans-Serif",
+ "Proportional Serif": "Proportional Serif",
+ "Uniform": "Uniform",
+ "Small Caps": "Kiskapitális",
+ "None": "Egyik sem",
+ "captions settings": "magyarázó szövegek beállításai",
+ "subtitles settings": "feliratok beállításai",
+ "Raised": "Emelt",
+ "Depressed": "Nyomott"
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Lejátszás",
+ "Pause": "Szünet",
+ "Current Time": "Aktuális időpont",
+ "Duration": "Hossz",
+ "Remaining Time": "Hátralévő idő",
+ "Stream Type": "Adatfolyam típusa",
+ "LIVE": "ÉLŐ",
+ "Loaded": "Betöltve",
+ "Progress": "Állapot",
+ "Fullscreen": "Teljes képernyő",
+ "Non-Fullscreen": "Normál méret",
+ "Mute": "Némítás",
+ "Unmute": "Némítás kikapcsolva",
+ "Playback Rate": "Lejátszási sebesség",
+ "Subtitles": "Feliratok",
+ "subtitles off": "Feliratok kikapcsolva",
+ "Captions": "Magyarázó szöveg",
+ "captions off": "Magyarázó szöveg kikapcsolva",
+ "Chapters": "Fejezetek",
+ "You aborted the media playback": "Leállította a lejátszást",
+ "A network error caused the media download to fail part-way.": "Hálózati hiba miatt a videó részlegesen töltődött le.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "A videó nem tölthető be hálózati vagy kiszolgálói hiba miatt, vagy a formátuma nem támogatott.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "A lejátszás adatsérülés miatt leállt, vagy a videó egyes tulajdonságait a böngészője nem támogatja.",
+ "No compatible source was found for this media.": "Nincs kompatibilis forrás ehhez a videóhoz.",
+ "Audio Player": "Audio lejátszó",
+ "Video Player": "Videó lejátszó",
+ "Replay": "Visszajátszás",
+ "Descriptions": "Leírások",
+ "descriptions off": "leírások kikapcsolva",
+ "Audio Track": "Hangsáv",
+ "Volume Level": "Hangerő",
+ "Play Video": "Videó lejátszása",
+ "Close": "Bezárás",
+ "Text": "Szöveg",
+ "White": "Fehér",
+ "Black": "Fekete",
+ "Red": "Piros",
+ "Green": "Zöld",
+ "Blue": "Kék",
+ "Yellow": "Sárga",
+ "Background": "Háttér",
+ "Window": "Ablak",
+ "Transparent": "Átlátszó",
+ "Semi-Transparent": "Félig átlátszó",
+ "Opaque": "Áttetsző",
+ "Font Size": "Betűméret",
+ "Font Family": "Betűtípus",
+ "Done": "Kész",
+ "Picture-in-Picture": "Kép a képben",
+ "Exit Picture-in-Picture": "Kilépés kép a képben módból",
+ "{1} is loading.": "{1} betöltése.",
+ "Reset": "Visszaállítás",
+ "restore all settings to the default values": "összes beállítás visszaállítása az alapértelmezett értékekre",
+ "The media is encrypted and we do not have the keys to decrypt it.": "A média titkosítva van és nincsenek kulcsok a visszafejtéshez.",
+ "Close Modal Dialog": "Felugró ablak bezárása",
+ "Modal Window": "Felugró ablak",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Ezt a felugró ablakot az Escape gomb megnyomásával vagy a bezáró gomb aktiválásával lehet bezárni.",
+ ", selected": ", kiválasztva",
+ "descriptions settings": "leírások beállítása",
+ "Text Edge Style": "Szövegél stílus",
+ "This is a modal window": "Ez egy felugró ablak",
+ "Cyan": "Cián",
+ "Dropshadow": "Árnyék",
+ "End of dialog window.": "Párbeszédablak vége.",
+ "Progress Bar": "Folyamatjelző sáv",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Párbeszédablak eleje. Az Escape gomb befejezi és bezárja az ablakot.",
+ "Caption Settings Dialog": "Feliratbeállítások párbeszédablak",
+ ", opens descriptions settings dialog": ", megnyitja a leírások beállításainak párbeszédablakját",
+ ", opens captions settings dialog": ", megnyitja a magyarázó szövegek beállításainak párbeszédablakját",
+ ", opens subtitles settings dialog": ", megnyitja a feliratok beállításainak párbeszédablakját",
+ "Seek to live, currently behind live": "Élő adáshoz tekerés, jelenleg az élő adás mögött van",
+ "Seek to live, currently playing live": "Élő adáshoz tekerés, jelenleg az élő adásnál van",
+ "progress bar timing: currentTime={1} duration={2}": "{1} / {2}",
+ "Magenta": "Lila",
+ "Script": "Script",
+ "Casual": "Casual",
+ "Monospace Serif": "Monospace Serif",
+ "Monospace Sans-Serif": "Monospace Sans-Serif",
+ "Proportional Sans-Serif": "Proportional Sans-Serif",
+ "Proportional Serif": "Proportional Serif",
+ "Uniform": "Uniform",
+ "Small Caps": "Kiskapitális",
+ "None": "Egyik sem",
+ "captions settings": "magyarázó szövegek beállításai",
+ "subtitles settings": "feliratok beállításai",
+ "Raised": "Emelt",
+ "Depressed": "Nyomott"
+}
-videojs.addLanguage("it",{
- "Play": "Play",
- "Pause": "Pausa",
- "Current Time": "Orario attuale",
- "Duration Time": "Durata",
- "Remaining Time": "Tempo rimanente",
- "Stream Type": "Tipo del Streaming",
- "LIVE": "LIVE",
- "Loaded": "Caricato",
- "Progress": "Stato",
- "Fullscreen": "Schermo intero",
- "Non-Fullscreen": "Chiudi schermo intero",
- "Mute": "Muto",
- "Unmute": "Audio",
- "Playback Rate": "Tasso di riproduzione",
- "Subtitles": "Sottotitoli",
- "subtitles off": "Senza sottotitoli",
- "Captions": "Sottotitoli non udenti",
- "captions off": "Senza sottotitoli non udenti",
- "Chapters": "Capitolo",
- "You aborted the media playback": "La riproduzione del filmato è stata interrotta.",
- "A network error caused the media download to fail part-way.": "Il download del filmato è stato interrotto a causa di un problema rete.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Il filmato non può essere caricato a causa di un errore nel server o nella rete o perché il formato non viene supportato.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La riproduzione del filmato è stata interrotta a causa di un file danneggiato o per l’utilizzo di impostazioni non supportate dal browser.",
- "No compatible source was found for this media.": "Non ci sono fonti compatibili per questo filmato."
+videojs.addLanguage('it', {
+ "Play": "Play",
+ "Pause": "Pausa",
+ "Current Time": "Orario attuale",
+ "Duration": "Durata",
+ "Remaining Time": "Tempo rimanente",
+ "Stream Type": "Tipo del Streaming",
+ "LIVE": "LIVE",
+ "Loaded": "Caricato",
+ "Progress": "Stato",
+ "Fullscreen": "Schermo intero",
+ "Non-Fullscreen": "Chiudi schermo intero",
+ "Mute": "Muto",
+ "Unmute": "Audio",
+ "Playback Rate": "Tasso di riproduzione",
+ "Subtitles": "Sottotitoli",
+ "subtitles off": "Senza sottotitoli",
+ "Captions": "Sottotitoli non udenti",
+ "captions off": "Senza sottotitoli non udenti",
+ "Chapters": "Capitolo",
+ "You aborted the media playback": "La riproduzione del filmato è stata interrotta.",
+ "A network error caused the media download to fail part-way.": "Il download del filmato è stato interrotto a causa di un problema rete.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Il filmato non può essere caricato a causa di un errore nel server o nella rete o perché il formato non viene supportato.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La riproduzione del filmato è stata interrotta a causa di un file danneggiato o per l’utilizzo di impostazioni non supportate dal browser.",
+ "No compatible source was found for this media.": "Non ci sono fonti compatibili per questo filmato."
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Play",
+ "Pause": "Pausa",
+ "Current Time": "Orario attuale",
+ "Duration": "Durata",
+ "Remaining Time": "Tempo rimanente",
+ "Stream Type": "Tipo del Streaming",
+ "LIVE": "LIVE",
+ "Loaded": "Caricato",
+ "Progress": "Stato",
+ "Fullscreen": "Schermo intero",
+ "Non-Fullscreen": "Chiudi schermo intero",
+ "Mute": "Muto",
+ "Unmute": "Audio",
+ "Playback Rate": "Tasso di riproduzione",
+ "Subtitles": "Sottotitoli",
+ "subtitles off": "Senza sottotitoli",
+ "Captions": "Sottotitoli non udenti",
+ "captions off": "Senza sottotitoli non udenti",
+ "Chapters": "Capitolo",
+ "You aborted the media playback": "La riproduzione del filmato è stata interrotta.",
+ "A network error caused the media download to fail part-way.": "Il download del filmato è stato interrotto a causa di un problema rete.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Il filmato non può essere caricato a causa di un errore nel server o nella rete o perché il formato non viene supportato.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La riproduzione del filmato è stata interrotta a causa di un file danneggiato o per l’utilizzo di impostazioni non supportate dal browser.",
+ "No compatible source was found for this media.": "Non ci sono fonti compatibili per questo filmato."
+}
-videojs.addLanguage("ja",{
- "Play": "再生",
- "Pause": "一時停止",
- "Current Time": "現在の時間",
- "Duration Time": "長さ",
- "Remaining Time": "残りの時間",
- "Stream Type": "ストリームの種類",
- "LIVE": "ライブ",
- "Loaded": "ロード済み",
- "Progress": "進行状況",
- "Fullscreen": "フルスクリーン",
- "Non-Fullscreen": "フルスクリーン以外",
- "Mute": "ミュート",
- "Unmute": "ミュート解除",
- "Playback Rate": "再生レート",
- "Subtitles": "サブタイトル",
- "subtitles off": "サブタイトル オフ",
- "Captions": "キャプション",
- "captions off": "キャプション オフ",
- "Chapters": "チャプター",
- "You aborted the media playback": "動画再生を中止しました",
- "A network error caused the media download to fail part-way.": "ネットワーク エラーにより動画のダウンロードが途中で失敗しました",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "サーバーまたはネットワークのエラー、またはフォーマットがサポートされていないため、動画をロードできませんでした",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "破損の問題、またはお使いのブラウザがサポートしていない機能が動画に使用されていたため、動画の再生が中止されました",
- "No compatible source was found for this media.": "この動画に対して互換性のあるソースが見つかりませんでした"
+videojs.addLanguage('ja', {
+ "Play": "再生",
+ "Pause": "一時停止",
+ "Current Time": "現在の時間",
+ "Duration": "長さ",
+ "Remaining Time": "残りの時間",
+ "Stream Type": "ストリームの種類",
+ "LIVE": "ライブ",
+ "Loaded": "ロード済み",
+ "Progress": "進行状況",
+ "Fullscreen": "フルスクリーン",
+ "Non-Fullscreen": "フルスクリーン以外",
+ "Mute": "ミュート",
+ "Unmute": "ミュート解除",
+ "Playback Rate": "再生レート",
+ "Subtitles": "サブタイトル",
+ "subtitles off": "サブタイトル オフ",
+ "Captions": "キャプション",
+ "captions off": "キャプション オフ",
+ "Chapters": "チャプター",
+ "You aborted the media playback": "動画再生を中止しました",
+ "A network error caused the media download to fail part-way.": "ネットワーク エラーにより動画のダウンロードが途中で失敗しました",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "サーバーまたはネットワークのエラー、またはフォーマットがサポートされていないため、動画をロードできませんでした",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "破損の問題、またはお使いのブラウザがサポートしていない機能が動画に使用されていたため、動画の再生が中止されました",
+ "No compatible source was found for this media.": "この動画に対して互換性のあるソースが見つかりませんでした"
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "再生",
+ "Pause": "一時停止",
+ "Current Time": "現在の時間",
+ "Duration": "長さ",
+ "Remaining Time": "残りの時間",
+ "Stream Type": "ストリームの種類",
+ "LIVE": "ライブ",
+ "Loaded": "ロード済み",
+ "Progress": "進行状況",
+ "Fullscreen": "フルスクリーン",
+ "Non-Fullscreen": "フルスクリーン以外",
+ "Mute": "ミュート",
+ "Unmute": "ミュート解除",
+ "Playback Rate": "再生レート",
+ "Subtitles": "サブタイトル",
+ "subtitles off": "サブタイトル オフ",
+ "Captions": "キャプション",
+ "captions off": "キャプション オフ",
+ "Chapters": "チャプター",
+ "You aborted the media playback": "動画再生を中止しました",
+ "A network error caused the media download to fail part-way.": "ネットワーク エラーにより動画のダウンロードが途中で失敗しました",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "サーバーまたはネットワークのエラー、またはフォーマットがサポートされていないため、動画をロードできませんでした",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "破損の問題、またはお使いのブラウザがサポートしていない機能が動画に使用されていたため、動画の再生が中止されました",
+ "No compatible source was found for this media.": "この動画に対して互換性のあるソースが見つかりませんでした"
+}
-videojs.addLanguage("ko",{
- "Play": "재생",
- "Pause": "일시중지",
- "Current Time": "현재 시간",
- "Duration Time": "지정 기간",
- "Remaining Time": "남은 시간",
- "Stream Type": "스트리밍 유형",
- "LIVE": "라이브",
- "Loaded": "로드됨",
- "Progress": "진행",
- "Fullscreen": "전체 화면",
- "Non-Fullscreen": "전체 화면 해제",
- "Mute": "음소거",
- "Unmute": "음소거 해제",
- "Playback Rate": "재생 비율",
- "Subtitles": "서브타이틀",
- "subtitles off": "서브타이틀 끄기",
- "Captions": "자막",
- "captions off": "자막 끄기",
- "Chapters": "챕터",
- "You aborted the media playback": "비디오 재생을 취소했습니다.",
- "A network error caused the media download to fail part-way.": "네트워크 오류로 인하여 비디오 일부를 다운로드하지 못 했습니다.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "비디오를 로드할 수 없습니다. 서버 혹은 네트워크 오류 때문이거나 지원되지 않는 형식 때문일 수 있습니다.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "비디오 재생이 취소됐습니다. 비디오가 손상되었거나 비디오가 사용하는 기능을 브라우저에서 지원하지 않는 것 같습니다.",
- "No compatible source was found for this media.": "비디오에 호환되지 않는 소스가 있습니다."
+videojs.addLanguage('ko', {
+ "Play": "재생",
+ "Pause": "일시중지",
+ "Current Time": "현재 시간",
+ "Duration": "지정 기간",
+ "Remaining Time": "남은 시간",
+ "Stream Type": "스트리밍 유형",
+ "LIVE": "라이브",
+ "Loaded": "로드됨",
+ "Progress": "진행",
+ "Fullscreen": "전체 화면",
+ "Non-Fullscreen": "전체 화면 해제",
+ "Mute": "음소거",
+ "Unmute": "음소거 해제",
+ "Playback Rate": "재생 비율",
+ "Subtitles": "서브타이틀",
+ "subtitles off": "서브타이틀 끄기",
+ "Captions": "자막",
+ "captions off": "자막 끄기",
+ "Chapters": "챕터",
+ "You aborted the media playback": "비디오 재생을 취소했습니다.",
+ "A network error caused the media download to fail part-way.": "네트워크 오류로 인하여 비디오 일부를 다운로드하지 못 했습니다.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "비디오를 로드할 수 없습니다. 서버 혹은 네트워크 오류 때문이거나 지원되지 않는 형식 때문일 수 있습니다.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "비디오 재생이 취소됐습니다. 비디오가 손상되었거나 비디오가 사용하는 기능을 브라우저에서 지원하지 않는 것 같습니다.",
+ "No compatible source was found for this media.": "비디오에 호환되지 않는 소스가 있습니다."
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "재생",
+ "Pause": "일시중지",
+ "Current Time": "현재 시간",
+ "Duration": "지정 기간",
+ "Remaining Time": "남은 시간",
+ "Stream Type": "스트리밍 유형",
+ "LIVE": "라이브",
+ "Loaded": "로드됨",
+ "Progress": "진행",
+ "Fullscreen": "전체 화면",
+ "Non-Fullscreen": "전체 화면 해제",
+ "Mute": "음소거",
+ "Unmute": "음소거 해제",
+ "Playback Rate": "재생 비율",
+ "Subtitles": "서브타이틀",
+ "subtitles off": "서브타이틀 끄기",
+ "Captions": "자막",
+ "captions off": "자막 끄기",
+ "Chapters": "챕터",
+ "You aborted the media playback": "비디오 재생을 취소했습니다.",
+ "A network error caused the media download to fail part-way.": "네트워크 오류로 인하여 비디오 일부를 다운로드하지 못 했습니다.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "비디오를 로드할 수 없습니다. 서버 혹은 네트워크 오류 때문이거나 지원되지 않는 형식 때문일 수 있습니다.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "비디오 재생이 취소됐습니다. 비디오가 손상되었거나 비디오가 사용하는 기능을 브라우저에서 지원하지 않는 것 같습니다.",
+ "No compatible source was found for this media.": "비디오에 호환되지 않는 소스가 있습니다."
+}
-videojs.addLanguage("nb",{
- "Play": "Spill",
- "Pause": "Pause",
- "Current Time": "Aktuell tid",
- "Duration Time": "Varighet",
- "Remaining Time": "Gjenstående tid",
- "Stream Type": "Type strøm",
- "LIVE": "DIREKTE",
- "Loaded": "Lastet inn",
- "Progress": "Status",
- "Fullscreen": "Fullskjerm",
- "Non-Fullscreen": "Lukk fullskjerm",
- "Mute": "Lyd av",
- "Unmute": "Lyd på",
- "Playback Rate": "Avspillingsrate",
- "Subtitles": "Undertekst på",
- "subtitles off": "Undertekst av",
- "Captions": "Undertekst for hørselshemmede på",
- "captions off": "Undertekst for hørselshemmede av",
- "Chapters": "Kapitler",
- "You aborted the media playback": "Du avbrøt avspillingen.",
- "A network error caused the media download to fail part-way.": "En nettverksfeil avbrøt nedlasting av videoen.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikke lastes ned, på grunn av nettverksfeil eller serverfeil, eller fordi formatet ikke er støttet.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoavspillingen ble avbrudt på grunn av ødelagte data eller fordi videoen ville gjøre noe som nettleseren din ikke har støtte for.",
- "No compatible source was found for this media.": "Fant ikke en kompatibel kilde for dette mediainnholdet."
+videojs.addLanguage('nb', {
+ "Audio Player": "Lydspiller",
+ "Video Player": "Videospiller",
+ "Play": "Spill",
+ "Pause": "Pause",
+ "Replay": "Spill om igjen",
+ "Current Time": "Aktuell tid",
+ "Duration": "Varighet",
+ "Remaining Time": "Gjenstående tid",
+ "Stream Type": "Type strøm",
+ "LIVE": "DIREKTE",
+ "Seek to live, currently behind live": "Hopp til live, spiller tidligere i sendingen nå",
+ "Seek to live, currently playing live": "Hopp til live, spiller live nå",
+ "Loaded": "Lastet inn",
+ "Progress": "Framdrift",
+ "Progress Bar": "Framdriftsviser",
+ "progress bar timing: currentTime={1} duration={2}": "{1} av {2}",
+ "Fullscreen": "Fullskjerm",
+ "Non-Fullscreen": "Lukk fullskjerm",
+ "Mute": "Lyd av",
+ "Unmute": "Lyd på",
+ "Playback Rate": "Avspillingshastighet",
+ "Subtitles": "Teksting på",
+ "subtitles off": "Teksting av",
+ "Captions": "Teksting for hørselshemmede på",
+ "captions off": "Teksting for hørselshemmede av",
+ "Chapters": "Kapitler",
+ "Descriptions": "Beskrivelser",
+ "descriptions off": "beskrivelser av",
+ "Audio Track": "Lydspor",
+ "Volume Level": "Volumnivå",
+ "You aborted the media playback": "Du avbrøt avspillingen.",
+ "A network error caused the media download to fail part-way.": "En nettverksfeil avbrøt nedlasting av videoen.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikke lastes ned, på grunn av nettverksfeil eller serverfeil, eller fordi formatet ikke er støttet.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoavspillingen ble avbrudt på grunn av ødelagte data eller fordi videoen ville gjøre noe som nettleseren din ikke har støtte for.",
+ "No compatible source was found for this media.": "Fant ikke en kompatibel kilde for dette mediainnholdet.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Mediefilen er kryptert og vi mangler nøkler for å dekryptere den.",
+ "Play Video": "Spill av video",
+ "Close": "Lukk",
+ "Close Modal Dialog": "Lukk dialogvinduet",
+ "Modal Window": "Dialogvindu",
+ "This is a modal window": "Dette er et dialogvindu",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Vinduet kan lukkes ved å trykke på Escape-tasten eller lukkeknappen.",
+ ", opens captions settings dialog": ", åpner innstillinger for teksting for hørselshemmede",
+ ", opens subtitles settings dialog": ", åpner innstillinger for teksting",
+ ", opens descriptions settings dialog": ", åpner innstillinger for beskrivelser",
+ ", selected": ", valgt",
+ "captions settings": "innstillinger for teksting",
+ "subtitles settings": "innstillinger for teksting",
+ "descriptions settings": "innstillinger for beskrivelser",
+ "Text": "Tekst",
+ "White": "Hvit",
+ "Black": "Svart",
+ "Red": "Rød",
+ "Green": "Grønn",
+ "Blue": "Blå",
+ "Yellow": "Gul",
+ "Magenta": "Magenta",
+ "Cyan": "Turkis",
+ "Background": "Bakgrunn",
+ "Window": "Vindu",
+ "Transparent": "Gjennomsiktig",
+ "Semi-Transparent": "Delvis gjennomsiktig",
+ "Opaque": "Ugjennomsiktig",
+ "Font Size": "Tekststørrelse",
+ "Text Edge Style": "Tekstkant",
+ "None": "Ingen",
+ "Raised": "Uthevet",
+ "Depressed": "Nedtrykt",
+ "Uniform": "Enkel",
+ "Dropshadow": "Skygge",
+ "Font Family": "Skrifttype",
+ "Proportional Sans-Serif": "Proporsjonal skrift uten seriffer",
+ "Monospace Sans-Serif": "Fastbreddeskrift uten seriffer",
+ "Proportional Serif": "Proporsjonal skrift med seriffer",
+ "Monospace Serif": "Fastbreddeskrift med seriffer",
+ "Casual": "Uformell",
+ "Script": "Skråskrift",
+ "Small Caps": "Kapitéler",
+ "Reset": "Tilbakestill",
+ "restore all settings to the default values": "tilbakestill alle innstillinger til standardverdiene",
+ "Done": "Ferdig",
+ "Caption Settings Dialog": "Innstillingsvindu for teksting for hørselshemmede",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Begynnelse på dialogvindu. Trykk Escape for å avbryte og lukke vinduet.",
+ "End of dialog window.": "Avslutning på dialogvindu.",
+ "{1} is loading.": "{1} laster."
});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Lydspiller",
+ "Video Player": "Videospiller",
+ "Play": "Spill",
+ "Pause": "Pause",
+ "Replay": "Spill om igjen",
+ "Current Time": "Aktuell tid",
+ "Duration": "Varighet",
+ "Remaining Time": "Gjenstående tid",
+ "Stream Type": "Type strøm",
+ "LIVE": "DIREKTE",
+ "Seek to live, currently behind live": "Hopp til live, spiller tidligere i sendingen nå",
+ "Seek to live, currently playing live": "Hopp til live, spiller live nå",
+ "Loaded": "Lastet inn",
+ "Progress": "Framdrift",
+ "Progress Bar": "Framdriftsviser",
+ "progress bar timing: currentTime={1} duration={2}": "{1} av {2}",
+ "Fullscreen": "Fullskjerm",
+ "Non-Fullscreen": "Lukk fullskjerm",
+ "Mute": "Lyd av",
+ "Unmute": "Lyd på",
+ "Playback Rate": "Avspillingshastighet",
+ "Subtitles": "Teksting på",
+ "subtitles off": "Teksting av",
+ "Captions": "Teksting for hørselshemmede på",
+ "captions off": "Teksting for hørselshemmede av",
+ "Chapters": "Kapitler",
+ "Descriptions": "Beskrivelser",
+ "descriptions off": "beskrivelser av",
+ "Audio Track": "Lydspor",
+ "Volume Level": "Volumnivå",
+ "You aborted the media playback": "Du avbrøt avspillingen.",
+ "A network error caused the media download to fail part-way.": "En nettverksfeil avbrøt nedlasting av videoen.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikke lastes ned, på grunn av nettverksfeil eller serverfeil, eller fordi formatet ikke er støttet.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoavspillingen ble avbrudt på grunn av ødelagte data eller fordi videoen ville gjøre noe som nettleseren din ikke har støtte for.",
+ "No compatible source was found for this media.": "Fant ikke en kompatibel kilde for dette mediainnholdet.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Mediefilen er kryptert og vi mangler nøkler for å dekryptere den.",
+ "Play Video": "Spill av video",
+ "Close": "Lukk",
+ "Close Modal Dialog": "Lukk dialogvinduet",
+ "Modal Window": "Dialogvindu",
+ "This is a modal window": "Dette er et dialogvindu",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Vinduet kan lukkes ved å trykke på Escape-tasten eller lukkeknappen.",
+ ", opens captions settings dialog": ", åpner innstillinger for teksting for hørselshemmede",
+ ", opens subtitles settings dialog": ", åpner innstillinger for teksting",
+ ", opens descriptions settings dialog": ", åpner innstillinger for beskrivelser",
+ ", selected": ", valgt",
+ "captions settings": "innstillinger for teksting",
+ "subtitles settings": "innstillinger for teksting",
+ "descriptions settings": "innstillinger for beskrivelser",
+ "Text": "Tekst",
+ "White": "Hvit",
+ "Black": "Svart",
+ "Red": "Rød",
+ "Green": "Grønn",
+ "Blue": "Blå",
+ "Yellow": "Gul",
+ "Magenta": "Magenta",
+ "Cyan": "Turkis",
+ "Background": "Bakgrunn",
+ "Window": "Vindu",
+ "Transparent": "Gjennomsiktig",
+ "Semi-Transparent": "Delvis gjennomsiktig",
+ "Opaque": "Ugjennomsiktig",
+ "Font Size": "Tekststørrelse",
+ "Text Edge Style": "Tekstkant",
+ "None": "Ingen",
+ "Raised": "Uthevet",
+ "Depressed": "Nedtrykt",
+ "Uniform": "Enkel",
+ "Dropshadow": "Skygge",
+ "Font Family": "Skrifttype",
+ "Proportional Sans-Serif": "Proporsjonal skrift uten seriffer",
+ "Monospace Sans-Serif": "Fastbreddeskrift uten seriffer",
+ "Proportional Serif": "Proporsjonal skrift med seriffer",
+ "Monospace Serif": "Fastbreddeskrift med seriffer",
+ "Casual": "Uformell",
+ "Script": "Skråskrift",
+ "Small Caps": "Kapitéler",
+ "Reset": "Tilbakestill",
+ "restore all settings to the default values": "tilbakestill alle innstillinger til standardverdiene",
+ "Done": "Ferdig",
+ "Caption Settings Dialog": "Innstillingsvindu for teksting for hørselshemmede",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Begynnelse på dialogvindu. Trykk Escape for å avbryte og lukke vinduet.",
+ "End of dialog window.": "Avslutning på dialogvindu.",
+ "{1} is loading.": "{1} laster."
+}
-videojs.addLanguage("nl",{
- "Audio Player": "Audiospeler",
- "Video Player": "Videospeler",
- "Play": "Afspelen",
- "Pause": "Pauzeren",
- "Replay": "Opnieuw afspelen",
- "Current Time": "Huidige tijd",
- "Duration Time": "Tijdsduur",
- "Remaining Time": "Resterende tijd",
- "Stream Type": "Streamtype",
- "LIVE": "LIVE",
- "Loaded": "Geladen",
- "Progress": "Voortgang",
- "Progress Bar": "Voortgangsbalk",
- "progress bar timing: currentTime={1} duration={2}": "{1} van {2}",
- "Fullscreen": "Volledig scherm",
- "Non-Fullscreen": "Geen volledig scherm",
- "Mute": "Dempen",
- "Unmute": "Niet dempen",
- "Playback Rate": "Afspeelsnelheid",
- "Subtitles": "Ondertiteling",
- "subtitles off": "ondertiteling uit",
- "Captions": "Bijschriften",
- "captions off": "bijschriften uit",
- "Chapters": "Hoofdstukken",
- "Descriptions": "Beschrijvingen",
- "descriptions off": "beschrijvingen uit",
- "Audio Track": "Audiospoor",
- "Volume Level": "Geluidsniveau",
- "You aborted the media playback": "U heeft het afspelen van de media afgebroken",
- "A network error caused the media download to fail part-way.": "Een netwerkfout heeft ervoor gezorgd dat het downloaden van de media halverwege is mislukt.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "De media kon niet worden geladen, dit komt doordat of de server of het netwerk mislukt of doordat het formaat niet wordt ondersteund.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Het afspelen van de media is afgebroken door een probleem met beschadeigde gegevens of doordat de media functies gebruikt die uw browser niet ondersteund.",
- "No compatible source was found for this media.": "Er is geen geschikte bron voor deze media gevonden.",
- "The media is encrypted and we do not have the keys to decrypt it.": "De media is versleuteld en we hebben de sleutels niet om deze te ontsleutelen.",
- "Play Video": "Video afspelen",
- "Close": "Sluiten",
- "Close Modal Dialog": "Extra venster sluiten",
- "Modal Window": "Extra venster",
- "This is a modal window": "Dit is een extra venster",
- "This modal can be closed by pressing the Escape key or activating the close button.": "Dit venster kan worden gesloten door op de Escape-toets te drukken of door de sluiten-knop te activeren.",
- ", opens captions settings dialog": ", opent instellingen-venster voor bijschriften",
- ", opens subtitles settings dialog": ", opent instellingen-venster voor ondertitelingen",
- ", opens descriptions settings dialog": ", opent instellingen-venster voor beschrijvingen",
- ", selected": ", geselecteerd",
- "captions settings": "bijschriften-instellingen",
- "subtitles settings": "ondertiteling-instellingen",
- "descriptions settings": "beschrijvingen-instellingen",
- "Text": "Tekst",
- "White": "Wit",
- "Black": "Zwart",
- "Red": "Rood",
- "Green": "Groen",
- "Blue": "Blauw",
- "Yellow": "Geel",
- "Magenta": "Magenta",
- "Cyan": "Cyaan",
- "Background": "Achtergrond",
- "Window": "Venster",
- "Transparent": "Transparant",
- "Semi-Transparent": "Semi-transparant",
- "Opaque": "Ondoorzichtig",
- "Font Size": "Lettergrootte",
- "Text Edge Style": "Stijl tekstrand",
- "None": "Geen",
- "Raised": "Verhoogd",
- "Depressed": "Ingedrukt",
- "Uniform": "Uniform",
- "Dropshadow": "Schaduw",
- "Font Family": "Lettertype",
- "Proportional Sans-Serif": "Proportioneel sans-serif",
- "Monospace Sans-Serif": "Monospace sans-serif",
- "Proportional Serif": "Proportioneel serif",
- "Monospace Serif": "Monospace serif",
- "Casual": "Luchtig",
- "Script": "Script",
- "Small Caps": "Kleine hoofdletters",
- "Reset": "Herstellen",
- "restore all settings to the default values": "alle instellingen naar de standaardwaarden herstellen",
- "Done": "Klaar",
- "Caption Settings Dialog": "Venster voor bijschriften-instellingen",
- "Beginning of dialog window. Escape will cancel and close the window.": "Begin van dialoogvenster. Escape zal annuleren en het venster sluiten.",
- "End of dialog window.": "Einde van dialoogvenster."
+videojs.addLanguage('nl', {
+ "Audio Player": "Audiospeler",
+ "Video Player": "Videospeler",
+ "Play": "Afspelen",
+ "Pause": "Pauzeren",
+ "Replay": "Opnieuw afspelen",
+ "Current Time": "Huidige tijd",
+ "Duration": "Tijdsduur",
+ "Remaining Time": "Resterende tijd",
+ "Stream Type": "Streamtype",
+ "LIVE": "LIVE",
+ "Loaded": "Geladen",
+ "Progress": "Voortgang",
+ "Progress Bar": "Voortgangsbalk",
+ "progress bar timing: currentTime={1} duration={2}": "{1} van {2}",
+ "Fullscreen": "Volledig scherm",
+ "Non-Fullscreen": "Geen volledig scherm",
+ "Mute": "Dempen",
+ "Unmute": "Niet dempen",
+ "Playback Rate": "Afspeelsnelheid",
+ "Subtitles": "Ondertiteling",
+ "subtitles off": "ondertiteling uit",
+ "Captions": "Bijschriften",
+ "captions off": "bijschriften uit",
+ "Chapters": "Hoofdstukken",
+ "Descriptions": "Beschrijvingen",
+ "descriptions off": "beschrijvingen uit",
+ "Audio Track": "Audiospoor",
+ "Volume Level": "Geluidsniveau",
+ "You aborted the media playback": "U heeft het afspelen van de media afgebroken",
+ "A network error caused the media download to fail part-way.": "Een netwerkfout heeft ervoor gezorgd dat het downloaden van de media halverwege is mislukt.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "De media kon niet worden geladen, dit komt doordat of de server of het netwerk mislukt of doordat het formaat niet wordt ondersteund.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Het afspelen van de media is afgebroken door een probleem met beschadeigde gegevens of doordat de media functies gebruikt die uw browser niet ondersteund.",
+ "No compatible source was found for this media.": "Er is geen geschikte bron voor deze media gevonden.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "De media is versleuteld en we hebben de sleutels niet om deze te ontsleutelen.",
+ "Play Video": "Video afspelen",
+ "Close": "Sluiten",
+ "Close Modal Dialog": "Extra venster sluiten",
+ "Modal Window": "Extra venster",
+ "This is a modal window": "Dit is een extra venster",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Dit venster kan worden gesloten door op de Escape-toets te drukken of door de sluiten-knop te activeren.",
+ ", opens captions settings dialog": ", opent instellingen-venster voor bijschriften",
+ ", opens subtitles settings dialog": ", opent instellingen-venster voor ondertitelingen",
+ ", opens descriptions settings dialog": ", opent instellingen-venster voor beschrijvingen",
+ ", selected": ", geselecteerd",
+ "captions settings": "bijschriften-instellingen",
+ "subtitles settings": "ondertiteling-instellingen",
+ "descriptions settings": "beschrijvingen-instellingen",
+ "Text": "Tekst",
+ "White": "Wit",
+ "Black": "Zwart",
+ "Red": "Rood",
+ "Green": "Groen",
+ "Blue": "Blauw",
+ "Yellow": "Geel",
+ "Magenta": "Magenta",
+ "Cyan": "Cyaan",
+ "Background": "Achtergrond",
+ "Window": "Venster",
+ "Transparent": "Transparant",
+ "Semi-Transparent": "Semi-transparant",
+ "Opaque": "Ondoorzichtig",
+ "Font Size": "Lettergrootte",
+ "Text Edge Style": "Stijl tekstrand",
+ "None": "Geen",
+ "Raised": "Verhoogd",
+ "Depressed": "Ingedrukt",
+ "Uniform": "Uniform",
+ "Dropshadow": "Schaduw",
+ "Font Family": "Lettertype",
+ "Proportional Sans-Serif": "Proportioneel sans-serif",
+ "Monospace Sans-Serif": "Monospace sans-serif",
+ "Proportional Serif": "Proportioneel serif",
+ "Monospace Serif": "Monospace serif",
+ "Casual": "Luchtig",
+ "Script": "Script",
+ "Small Caps": "Kleine hoofdletters",
+ "Reset": "Herstellen",
+ "restore all settings to the default values": "alle instellingen naar de standaardwaarden herstellen",
+ "Done": "Klaar",
+ "Caption Settings Dialog": "Venster voor bijschriften-instellingen",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Begin van dialoogvenster. Escape zal annuleren en het venster sluiten.",
+ "End of dialog window.": "Einde van dialoogvenster."
});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Audiospeler",
+ "Video Player": "Videospeler",
+ "Play": "Afspelen",
+ "Pause": "Pauzeren",
+ "Replay": "Opnieuw afspelen",
+ "Current Time": "Huidige tijd",
+ "Duration": "Tijdsduur",
+ "Remaining Time": "Resterende tijd",
+ "Stream Type": "Streamtype",
+ "LIVE": "LIVE",
+ "Loaded": "Geladen",
+ "Progress": "Voortgang",
+ "Progress Bar": "Voortgangsbalk",
+ "progress bar timing: currentTime={1} duration={2}": "{1} van {2}",
+ "Fullscreen": "Volledig scherm",
+ "Non-Fullscreen": "Geen volledig scherm",
+ "Mute": "Dempen",
+ "Unmute": "Niet dempen",
+ "Playback Rate": "Afspeelsnelheid",
+ "Subtitles": "Ondertiteling",
+ "subtitles off": "ondertiteling uit",
+ "Captions": "Bijschriften",
+ "captions off": "bijschriften uit",
+ "Chapters": "Hoofdstukken",
+ "Descriptions": "Beschrijvingen",
+ "descriptions off": "beschrijvingen uit",
+ "Audio Track": "Audiospoor",
+ "Volume Level": "Geluidsniveau",
+ "You aborted the media playback": "U heeft het afspelen van de media afgebroken",
+ "A network error caused the media download to fail part-way.": "Een netwerkfout heeft ervoor gezorgd dat het downloaden van de media halverwege is mislukt.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "De media kon niet worden geladen, dit komt doordat of de server of het netwerk mislukt of doordat het formaat niet wordt ondersteund.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Het afspelen van de media is afgebroken door een probleem met beschadeigde gegevens of doordat de media functies gebruikt die uw browser niet ondersteund.",
+ "No compatible source was found for this media.": "Er is geen geschikte bron voor deze media gevonden.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "De media is versleuteld en we hebben de sleutels niet om deze te ontsleutelen.",
+ "Play Video": "Video afspelen",
+ "Close": "Sluiten",
+ "Close Modal Dialog": "Extra venster sluiten",
+ "Modal Window": "Extra venster",
+ "This is a modal window": "Dit is een extra venster",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Dit venster kan worden gesloten door op de Escape-toets te drukken of door de sluiten-knop te activeren.",
+ ", opens captions settings dialog": ", opent instellingen-venster voor bijschriften",
+ ", opens subtitles settings dialog": ", opent instellingen-venster voor ondertitelingen",
+ ", opens descriptions settings dialog": ", opent instellingen-venster voor beschrijvingen",
+ ", selected": ", geselecteerd",
+ "captions settings": "bijschriften-instellingen",
+ "subtitles settings": "ondertiteling-instellingen",
+ "descriptions settings": "beschrijvingen-instellingen",
+ "Text": "Tekst",
+ "White": "Wit",
+ "Black": "Zwart",
+ "Red": "Rood",
+ "Green": "Groen",
+ "Blue": "Blauw",
+ "Yellow": "Geel",
+ "Magenta": "Magenta",
+ "Cyan": "Cyaan",
+ "Background": "Achtergrond",
+ "Window": "Venster",
+ "Transparent": "Transparant",
+ "Semi-Transparent": "Semi-transparant",
+ "Opaque": "Ondoorzichtig",
+ "Font Size": "Lettergrootte",
+ "Text Edge Style": "Stijl tekstrand",
+ "None": "Geen",
+ "Raised": "Verhoogd",
+ "Depressed": "Ingedrukt",
+ "Uniform": "Uniform",
+ "Dropshadow": "Schaduw",
+ "Font Family": "Lettertype",
+ "Proportional Sans-Serif": "Proportioneel sans-serif",
+ "Monospace Sans-Serif": "Monospace sans-serif",
+ "Proportional Serif": "Proportioneel serif",
+ "Monospace Serif": "Monospace serif",
+ "Casual": "Luchtig",
+ "Script": "Script",
+ "Small Caps": "Kleine hoofdletters",
+ "Reset": "Herstellen",
+ "restore all settings to the default values": "alle instellingen naar de standaardwaarden herstellen",
+ "Done": "Klaar",
+ "Caption Settings Dialog": "Venster voor bijschriften-instellingen",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Begin van dialoogvenster. Escape zal annuleren en het venster sluiten.",
+ "End of dialog window.": "Einde van dialoogvenster."
+}
\ No newline at end of file
-videojs.addLanguage("nn",{
- "Play": "Spel",
- "Pause": "Pause",
- "Current Time": "Aktuell tid",
- "Duration Time": "Varigheit",
- "Remaining Time": "Tid attende",
- "Stream Type": "Type straum",
- "LIVE": "DIREKTE",
- "Loaded": "Lasta inn",
- "Progress": "Status",
- "Fullscreen": "Fullskjerm",
- "Non-Fullscreen": "Stenga fullskjerm",
- "Mute": "Ljod av",
- "Unmute": "Ljod på",
- "Playback Rate": "Avspelingsrate",
- "Subtitles": "Teksting på",
- "subtitles off": "Teksting av",
- "Captions": "Teksting for høyrselshemma på",
- "captions off": "Teksting for høyrselshemma av",
- "Chapters": "Kapitel",
- "You aborted the media playback": "Du avbraut avspelinga.",
- "A network error caused the media download to fail part-way.": "Ein nettverksfeil avbraut nedlasting av videoen.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikkje lastas ned, på grunn av ein nettverksfeil eller serverfeil, eller av di formatet ikkje er stoda.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoavspelinga blei broten på grunn av øydelagde data eller av di videoen ville gjera noe som nettlesaren din ikkje stodar.",
- "No compatible source was found for this media.": "Fant ikke en kompatibel kilde for dette mediainnholdet."
+videojs.addLanguage('nn', {
+ "Audio Player": "Lydspelar",
+ "Video Player": "Videospelar",
+ "Play": "Spel",
+ "Pause": "Pause",
+ "Replay": "Spel om att",
+ "Current Time": "Aktuell tid",
+ "Duration": "Varigheit",
+ "Remaining Time": "Tid attende",
+ "Stream Type": "Type straum",
+ "LIVE": "DIREKTE",
+ "Seek to live, currently behind live": "Hopp til live, spelar tidlegare i sendinga no",
+ "Seek to live, currently playing live": "Hopp til live, speler live no",
+ "Loaded": "Lasta inn",
+ "Progress": "Framdrift",
+ "Progress Bar": "Framdriftsvisar",
+ "progress bar timing: currentTime={1} duration={2}": "{1} av {2}",
+ "Fullscreen": "Fullskjerm",
+ "Non-Fullscreen": "Stenga fullskjerm",
+ "Mute": "Lyd av",
+ "Unmute": "Lyd på",
+ "Playback Rate": "Avspelingshastigheit",
+ "Subtitles": "Teksting på",
+ "subtitles off": "Teksting av",
+ "Captions": "Teksting for høyrselshemma på",
+ "captions off": "Teksting for høyrselshemma av",
+ "Chapters": "Kapitel",
+ "Descriptions": "Beskrivingar",
+ "descriptions off": "beskrivingar av",
+ "Audio Track": "Lydspor",
+ "Volume Level": "Volumnivå",
+ "You aborted the media playback": "Du avbraut avspelinga.",
+ "A network error caused the media download to fail part-way.": "Ein nettverksfeil avbraut nedlasting av videoen.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikkje lastas ned, på grunn av ein nettverksfeil eller serverfeil, eller av di formatet ikkje er stoda.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoavspelinga blei broten på grunn av øydelagde data eller av di videoen ville gjera noe som nettlesaren din ikkje stodar.",
+ "No compatible source was found for this media.": "Fant ikke en kompatibel kilde for dette mediainnholdet.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Mediefila er kryptert og vi manglar nyklar for å dekryptere ho.",
+ "Play Video": "Spel av video",
+ "Close": "Lukk",
+ "Close Modal Dialog": "Lukk dialogvindauge",
+ "Modal Window": "Dialogvindauge",
+ "This is a modal window": "Dette er eit dialogvindauge",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Vindauget kan lukkast ved å trykke på Escape-tasten eller lukkeknappen.",
+ ", opens captions settings dialog": ", opnar innstillingar for teksting for høyrselshemma",
+ ", opens subtitles settings dialog": ", opnar innstillingar for teksting",
+ ", opens descriptions settings dialog": ", opnar innstillingar for beskrivingar",
+ ", selected": ", vald",
+ "captions settings": "innstillingar for teksting",
+ "subtitles settings": "innstillingar for teksting",
+ "descriptions settings": "innstillingar for skildringar",
+ "Text": "Tekst",
+ "White": "Kvit",
+ "Black": "Svart",
+ "Red": "Raud",
+ "Green": "Grøn",
+ "Blue": "Blå",
+ "Yellow": "Gul",
+ "Magenta": "Magenta",
+ "Cyan": "Turkis",
+ "Background": "Bakgrunn",
+ "Window": "Vindauge",
+ "Transparent": "Gjennomsiktig",
+ "Semi-Transparent": "Delvis gjennomsiktig",
+ "Opaque": "Ugjennomsiktig",
+ "Font Size": "Tekststorleik",
+ "Text Edge Style": "Tekstkant",
+ "None": "Ingen",
+ "Raised": "Utheva",
+ "Depressed": "Nedtrykt",
+ "Uniform": "Enkel",
+ "Dropshadow": "Skugge",
+ "Font Family": "Skrifttype",
+ "Proportional Sans-Serif": "Proporsjonal skrift utan seriffar",
+ "Monospace Sans-Serif": "Fastbreddeskrift utan seriffar",
+ "Proportional Serif": "Proporsjonal skrift med seriffar",
+ "Monospace Serif": "Fastbreddeskrift med seriffar",
+ "Casual": "Uformell",
+ "Script": "Skråskrift",
+ "Small Caps": "Kapitéler",
+ "Reset": "Tilbakestell",
+ "restore all settings to the default values": "tilbakestell alle innstillingar til standardverdiane",
+ "Done": "Ferdig",
+ "Caption Settings Dialog": "Innstillingsvindauge for teksting for høyrselshemma",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Byrjing på dialogvindauge. Trykk Escape for å avbryte og lukke vindauget.",
+ "End of dialog window.": "Avslutning på dialogvindauge.",
+ "{1} is loading.": "{1} lastar."
});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Lydspelar",
+ "Video Player": "Videospelar",
+ "Play": "Spel",
+ "Pause": "Pause",
+ "Replay": "Spel om att",
+ "Current Time": "Aktuell tid",
+ "Duration": "Varigheit",
+ "Remaining Time": "Tid attende",
+ "Stream Type": "Type straum",
+ "LIVE": "DIREKTE",
+ "Seek to live, currently behind live": "Hopp til live, spelar tidlegare i sendinga no",
+ "Seek to live, currently playing live": "Hopp til live, speler live no",
+ "Loaded": "Lasta inn",
+ "Progress": "Framdrift",
+ "Progress Bar": "Framdriftsvisar",
+ "progress bar timing: currentTime={1} duration={2}": "{1} av {2}",
+ "Fullscreen": "Fullskjerm",
+ "Non-Fullscreen": "Stenga fullskjerm",
+ "Mute": "Lyd av",
+ "Unmute": "Lyd på",
+ "Playback Rate": "Avspelingshastigheit",
+ "Subtitles": "Teksting på",
+ "subtitles off": "Teksting av",
+ "Captions": "Teksting for høyrselshemma på",
+ "captions off": "Teksting for høyrselshemma av",
+ "Chapters": "Kapitel",
+ "Descriptions": "Beskrivingar",
+ "descriptions off": "beskrivingar av",
+ "Audio Track": "Lydspor",
+ "Volume Level": "Volumnivå",
+ "You aborted the media playback": "Du avbraut avspelinga.",
+ "A network error caused the media download to fail part-way.": "Ein nettverksfeil avbraut nedlasting av videoen.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikkje lastas ned, på grunn av ein nettverksfeil eller serverfeil, eller av di formatet ikkje er stoda.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoavspelinga blei broten på grunn av øydelagde data eller av di videoen ville gjera noe som nettlesaren din ikkje stodar.",
+ "No compatible source was found for this media.": "Fant ikke en kompatibel kilde for dette mediainnholdet.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Mediefila er kryptert og vi manglar nyklar for å dekryptere ho.",
+ "Play Video": "Spel av video",
+ "Close": "Lukk",
+ "Close Modal Dialog": "Lukk dialogvindauge",
+ "Modal Window": "Dialogvindauge",
+ "This is a modal window": "Dette er eit dialogvindauge",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Vindauget kan lukkast ved å trykke på Escape-tasten eller lukkeknappen.",
+ ", opens captions settings dialog": ", opnar innstillingar for teksting for høyrselshemma",
+ ", opens subtitles settings dialog": ", opnar innstillingar for teksting",
+ ", opens descriptions settings dialog": ", opnar innstillingar for beskrivingar",
+ ", selected": ", vald",
+ "captions settings": "innstillingar for teksting",
+ "subtitles settings": "innstillingar for teksting",
+ "descriptions settings": "innstillingar for skildringar",
+ "Text": "Tekst",
+ "White": "Kvit",
+ "Black": "Svart",
+ "Red": "Raud",
+ "Green": "Grøn",
+ "Blue": "Blå",
+ "Yellow": "Gul",
+ "Magenta": "Magenta",
+ "Cyan": "Turkis",
+ "Background": "Bakgrunn",
+ "Window": "Vindauge",
+ "Transparent": "Gjennomsiktig",
+ "Semi-Transparent": "Delvis gjennomsiktig",
+ "Opaque": "Ugjennomsiktig",
+ "Font Size": "Tekststorleik",
+ "Text Edge Style": "Tekstkant",
+ "None": "Ingen",
+ "Raised": "Utheva",
+ "Depressed": "Nedtrykt",
+ "Uniform": "Enkel",
+ "Dropshadow": "Skugge",
+ "Font Family": "Skrifttype",
+ "Proportional Sans-Serif": "Proporsjonal skrift utan seriffar",
+ "Monospace Sans-Serif": "Fastbreddeskrift utan seriffar",
+ "Proportional Serif": "Proporsjonal skrift med seriffar",
+ "Monospace Serif": "Fastbreddeskrift med seriffar",
+ "Casual": "Uformell",
+ "Script": "Skråskrift",
+ "Small Caps": "Kapitéler",
+ "Reset": "Tilbakestell",
+ "restore all settings to the default values": "tilbakestell alle innstillingar til standardverdiane",
+ "Done": "Ferdig",
+ "Caption Settings Dialog": "Innstillingsvindauge for teksting for høyrselshemma",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Byrjing på dialogvindauge. Trykk Escape for å avbryte og lukke vindauget.",
+ "End of dialog window.": "Avslutning på dialogvindauge.",
+ "{1} is loading.": "{1} lastar."
+}
--- /dev/null
+videojs.addLanguage('oc', {
+ "Audio Player": "Lector àudio",
+ "Video Player": "Lector vidèo",
+ "Play": "Lectura",
+ "Pause": "Pausa",
+ "Replay": "Tornar legir",
+ "Current Time": "Durada passada",
+ "Duration": "Durada",
+ "Remaining Time": "Temps restant",
+ "Stream Type": "Tipe de difusion",
+ "LIVE": "DIRÈCTE",
+ "Seek to live, currently behind live": "Trapar lo dirècte, actualament darrièr lo dirècte",
+ "Seek to live, currently playing live": "Trapar lo dirècte, actualament lo dirècte es en lectura",
+ "Loaded": "Cargat",
+ "Progress": "Progression",
+ "Progress Bar": "Barra de progression",
+ "progress bar timing: currentTime={1} duration={2}": "{1} sus {2}",
+ "Fullscreen": "Ecran complèt",
+ "Non-Fullscreen": "Pas en ecran complèt",
+ "Mute": "Copar lo son",
+ "Unmute": "Restablir lo son",
+ "Playback Rate": "Velocitat de lectura",
+ "Subtitles": "Sostítols",
+ "subtitles off": "Sostítols desactivats",
+ "Captions": "Legendas",
+ "captions off": "Legendas desactivadas",
+ "Chapters": "Capítols",
+ "Descriptions": "Descripcions",
+ "descriptions off": "descripcions desactivadas",
+ "Audio Track": "Pista àudio",
+ "Volume Level": "Nivèl del volum",
+ "You aborted the media playback": "Avètz copat la lectura del mèdia.",
+ "A network error caused the media download to fail part-way.": "Una error de ret a provocat un fracàs del telecargament.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Lo mèdia a pas pogut èsser cargat, siá perque lo servidor o lo ret a fracassat siá perque lo format es pas compatible.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La lectura del mèdia es copada a causa d’un problèma de corrupcion o perque lo mèdia utiliza de foncionalitats pas suportadas pel navigador.",
+ "No compatible source was found for this media.": "Cap de font compatiblas pas trobada per aqueste mèdia.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Lo mèdia es chifrat e avèm pas las claus per lo deschifrar.",
+ "Play Video": "Legir la vidèo",
+ "Close": "Tampar",
+ "Close Modal Dialog": "Tampar la fenèstra",
+ "Modal Window": "Fenèstra",
+ "This is a modal window": "Aquò es una fenèstra",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Aquesta fenèstra pòt èsser tampada en quichar Escapar sul clavièr o en activar lo boton de tampadura.",
+ ", opens captions settings dialog": ", dobrís la fenèstra de paramètres de legendas",
+ ", opens subtitles settings dialog": ", dobrís la fenèstra de paramètres de sostítols",
+ ", opens descriptions settings dialog": ", dobrís la fenèstra de paramètres de descripcions",
+ ", selected": ", seleccionat",
+ "captions settings": "paramètres de legendas",
+ "subtitles settings": "paramètres de sostítols",
+ "descriptions settings": "paramètres de descripcions",
+ "Text": "Tèxte",
+ "White": "Blanc",
+ "Black": "Negre",
+ "Red": "Roge",
+ "Green": "Verd",
+ "Blue": "Blau",
+ "Yellow": "Jaune",
+ "Magenta": "Magenta",
+ "Cyan": "Cian",
+ "Background": "Rèireplan",
+ "Window": "Fenèstra",
+ "Transparent": "Transparent",
+ "Semi-Transparent": "Semitransparent",
+ "Opaque": "Opac",
+ "Font Size": "Talha de la polissa",
+ "Text Edge Style": "Estil dels contorns del tèxte",
+ "None": "Cap",
+ "Raised": "Naut",
+ "Depressed": "Enfonsat",
+ "Uniform": "Unifòrme",
+ "Dropshadow": "Ombrat",
+ "Font Family": "Familha de polissa",
+ "Proportional Sans-Serif": "Sans-Serif proporcionala",
+ "Monospace Sans-Serif": "Monospace Sans-Serif",
+ "Proportional Serif": "Serif proporcionala",
+ "Monospace Serif": "Serif proporcionala",
+ "Casual": "Manuscrita",
+ "Script": "Script",
+ "Small Caps": "Pichonas majusculas",
+ "Reset": "Reïnicializar",
+ "restore all settings to the default values": "O restablir tot a las valors per defaut",
+ "Done": "Acabat",
+ "Caption Settings Dialog": "Fenèstra de paramètres de legenda",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Debuta de la fenèstra. Escapar anullarà e tamparà la fenèstra",
+ "End of dialog window.": "Fin de la fenèstra.",
+ "{1} is loading.": "{1} es a cargar."
+});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Lector àudio",
+ "Video Player": "Lector vidèo",
+ "Play": "Lectura",
+ "Pause": "Pausa",
+ "Replay": "Tornar legir",
+ "Current Time": "Durada passada",
+ "Duration": "Durada",
+ "Remaining Time": "Temps restant",
+ "Stream Type": "Tipe de difusion",
+ "LIVE": "DIRÈCTE",
+ "Seek to live, currently behind live": "Trapar lo dirècte, actualament darrièr lo dirècte",
+ "Seek to live, currently playing live": "Trapar lo dirècte, actualament lo dirècte es en lectura",
+ "Loaded": "Cargat",
+ "Progress": "Progression",
+ "Progress Bar": "Barra de progression",
+ "progress bar timing: currentTime={1} duration={2}": "{1} sus {2}",
+ "Fullscreen": "Ecran complèt",
+ "Non-Fullscreen": "Pas en ecran complèt",
+ "Mute": "Copar lo son",
+ "Unmute": "Restablir lo son",
+ "Playback Rate": "Velocitat de lectura",
+ "Subtitles": "Sostítols",
+ "subtitles off": "Sostítols desactivats",
+ "Captions": "Legendas",
+ "captions off": "Legendas desactivadas",
+ "Chapters": "Capítols",
+ "Descriptions": "Descripcions",
+ "descriptions off": "descripcions desactivadas",
+ "Audio Track": "Pista àudio",
+ "Volume Level": "Nivèl del volum",
+ "You aborted the media playback": "Avètz copat la lectura del mèdia.",
+ "A network error caused the media download to fail part-way.": "Una error de ret a provocat un fracàs del telecargament.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Lo mèdia a pas pogut èsser cargat, siá perque lo servidor o lo ret a fracassat siá perque lo format es pas compatible.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La lectura del mèdia es copada a causa d’un problèma de corrupcion o perque lo mèdia utiliza de foncionalitats pas suportadas pel navigador.",
+ "No compatible source was found for this media.": "Cap de font compatiblas pas trobada per aqueste mèdia.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Lo mèdia es chifrat e avèm pas las claus per lo deschifrar.",
+ "Play Video": "Legir la vidèo",
+ "Close": "Tampar",
+ "Close Modal Dialog": "Tampar la fenèstra",
+ "Modal Window": "Fenèstra",
+ "This is a modal window": "Aquò es una fenèstra",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Aquesta fenèstra pòt èsser tampada en quichar Escapar sul clavièr o en activar lo boton de tampadura.",
+ ", opens captions settings dialog": ", dobrís la fenèstra de paramètres de legendas",
+ ", opens subtitles settings dialog": ", dobrís la fenèstra de paramètres de sostítols",
+ ", opens descriptions settings dialog": ", dobrís la fenèstra de paramètres de descripcions",
+ ", selected": ", seleccionat",
+ "captions settings": "paramètres de legendas",
+ "subtitles settings": "paramètres de sostítols",
+ "descriptions settings": "paramètres de descripcions",
+ "Text": "Tèxte",
+ "White": "Blanc",
+ "Black": "Negre",
+ "Red": "Roge",
+ "Green": "Verd",
+ "Blue": "Blau",
+ "Yellow": "Jaune",
+ "Magenta": "Magenta",
+ "Cyan": "Cian",
+ "Background": "Rèireplan",
+ "Window": "Fenèstra",
+ "Transparent": "Transparent",
+ "Semi-Transparent": "Semitransparent",
+ "Opaque": "Opac",
+ "Font Size": "Talha de la polissa",
+ "Text Edge Style": "Estil dels contorns del tèxte",
+ "None": "Cap",
+ "Raised": "Naut",
+ "Depressed": "Enfonsat",
+ "Uniform": "Unifòrme",
+ "Dropshadow": "Ombrat",
+ "Font Family": "Familha de polissa",
+ "Proportional Sans-Serif": "Sans-Serif proporcionala",
+ "Monospace Sans-Serif": "Monospace Sans-Serif",
+ "Proportional Serif": "Serif proporcionala",
+ "Monospace Serif": "Serif proporcionala",
+ "Casual": "Manuscrita",
+ "Script": "Script",
+ "Small Caps": "Pichonas majusculas",
+ "Reset": "Reïnicializar",
+ "restore all settings to the default values": "O restablir tot a las valors per defaut",
+ "Done": "Acabat",
+ "Caption Settings Dialog": "Fenèstra de paramètres de legenda",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Debuta de la fenèstra. Escapar anullarà e tamparà la fenèstra",
+ "End of dialog window.": "Fin de la fenèstra.",
+ "{1} is loading.": "{1} es a cargar."
+}
-videojs.addLanguage("pl",{
- "Play": "Odtwarzaj",
- "Pause": "Pauza",
- "Current Time": "Aktualny czas",
- "Duration Time": "Czas trwania",
- "Remaining Time": "Pozostały czas",
- "Stream Type": "Typ strumienia",
- "LIVE": "NA ŻYWO",
- "Loaded": "Załadowany",
- "Progress": "Status",
- "Fullscreen": "Pełny ekran",
- "Non-Fullscreen": "Pełny ekran niedostępny",
- "Mute": "Wyłącz dźwięk",
- "Unmute": "Włącz dźwięk",
- "Playback Rate": "Szybkość odtwarzania",
- "Subtitles": "Napisy",
- "subtitles off": "Napisy wyłączone",
- "Captions": "Transkrypcja",
- "captions off": "Transkrypcja wyłączona",
- "Chapters": "Rozdziały",
- "You aborted the media playback": "Odtwarzanie zostało przerwane",
- "A network error caused the media download to fail part-way.": "Problemy z siecią spowodowały błąd przy pobieraniu materiału wideo.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Materiał wideo nie może być załadowany, ponieważ wystąpił problem z siecią lub format nie jest obsługiwany",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Odtwarzanie materiału wideo zostało przerwane z powodu uszkodzonego pliku wideo lub z powodu błędu funkcji, które nie są wspierane przez przeglądarkę.",
- "No compatible source was found for this media.": "Dla tego materiału wideo nie znaleziono kompatybilnego źródła.",
- "Play Video": "Odtwarzaj wideo",
- "Close": "Zamknij",
- "Modal Window": "Okno Modala",
- "This is a modal window": "To jest okno modala",
- "This modal can be closed by pressing the Escape key or activating the close button.": "Ten modal możesz zamknąć naciskając przycisk Escape albo wybierając przycisk Zamknij.",
- ", opens captions settings dialog": ", otwiera okno dialogowe ustawień transkrypcji",
- ", opens subtitles settings dialog": ", otwiera okno dialogowe napisów",
- ", selected": ", zaznaczone"
+videojs.addLanguage('pl', {
+ "Play": "Odtwarzaj",
+ "Pause": "Pauza",
+ "Current Time": "Aktualny czas",
+ "Duration": "Czas trwania",
+ "Remaining Time": "Pozostały czas",
+ "Stream Type": "Typ strumienia",
+ "LIVE": "NA ŻYWO",
+ "Loaded": "Załadowany",
+ "Progress": "Status",
+ "Fullscreen": "Pełny ekran",
+ "Non-Fullscreen": "Pełny ekran niedostępny",
+ "Mute": "Wyłącz dźwięk",
+ "Unmute": "Włącz dźwięk",
+ "Playback Rate": "Szybkość odtwarzania",
+ "Subtitles": "Napisy",
+ "subtitles off": "Napisy wyłączone",
+ "Captions": "Transkrypcja",
+ "captions off": "Transkrypcja wyłączona",
+ "Chapters": "Rozdziały",
+ "You aborted the media playback": "Odtwarzanie zostało przerwane",
+ "A network error caused the media download to fail part-way.": "Problemy z siecią spowodowały błąd przy pobieraniu materiału wideo.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Materiał wideo nie może być załadowany, ponieważ wystąpił problem z siecią lub format nie jest obsługiwany",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Odtwarzanie materiału wideo zostało przerwane z powodu uszkodzonego pliku wideo lub z powodu błędu funkcji, które nie są wspierane przez przeglądarkę.",
+ "No compatible source was found for this media.": "Dla tego materiału wideo nie znaleziono kompatybilnego źródła.",
+ "Play Video": "Odtwarzaj wideo",
+ "Close": "Zamknij",
+ "Modal Window": "Okno Modala",
+ "This is a modal window": "To jest okno modala",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Ten modal możesz zamknąć naciskając przycisk Escape albo wybierając przycisk Zamknij.",
+ ", opens captions settings dialog": ", otwiera okno dialogowe ustawień transkrypcji",
+ ", opens subtitles settings dialog": ", otwiera okno dialogowe napisów",
+ ", selected": ", zaznaczone"
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Odtwarzaj",
+ "Pause": "Pauza",
+ "Current Time": "Aktualny czas",
+ "Duration": "Czas trwania",
+ "Remaining Time": "Pozostały czas",
+ "Stream Type": "Typ strumienia",
+ "LIVE": "NA ŻYWO",
+ "Loaded": "Załadowany",
+ "Progress": "Status",
+ "Fullscreen": "Pełny ekran",
+ "Non-Fullscreen": "Pełny ekran niedostępny",
+ "Mute": "Wyłącz dźwięk",
+ "Unmute": "Włącz dźwięk",
+ "Playback Rate": "Szybkość odtwarzania",
+ "Subtitles": "Napisy",
+ "subtitles off": "Napisy wyłączone",
+ "Captions": "Transkrypcja",
+ "captions off": "Transkrypcja wyłączona",
+ "Chapters": "Rozdziały",
+ "You aborted the media playback": "Odtwarzanie zostało przerwane",
+ "A network error caused the media download to fail part-way.": "Problemy z siecią spowodowały błąd przy pobieraniu materiału wideo.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Materiał wideo nie może być załadowany, ponieważ wystąpił problem z siecią lub format nie jest obsługiwany",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Odtwarzanie materiału wideo zostało przerwane z powodu uszkodzonego pliku wideo lub z powodu błędu funkcji, które nie są wspierane przez przeglądarkę.",
+ "No compatible source was found for this media.": "Dla tego materiału wideo nie znaleziono kompatybilnego źródła.",
+ "Play Video": "Odtwarzaj wideo",
+ "Close": "Zamknij",
+ "Modal Window": "Okno Modala",
+ "This is a modal window": "To jest okno modala",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Ten modal możesz zamknąć naciskając przycisk Escape albo wybierając przycisk Zamknij.",
+ ", opens captions settings dialog": ", otwiera okno dialogowe ustawień transkrypcji",
+ ", opens subtitles settings dialog": ", otwiera okno dialogowe napisów",
+ ", selected": ", zaznaczone"
+}
-videojs.addLanguage("pt-BR",{
- "Play": "Tocar",
- "Pause": "Pausar",
- "Current Time": "Tempo",
- "Duration Time": "Duração",
- "Remaining Time": "Tempo Restante",
- "Stream Type": "Tipo de Stream",
- "LIVE": "AO VIVO",
- "Loaded": "Carregado",
- "Progress": "Progresso",
- "Fullscreen": "Tela Cheia",
- "Non-Fullscreen": "Tela Normal",
- "Mute": "Mudo",
- "Unmute": "Habilitar Som",
- "Playback Rate": "Velocidade",
- "Subtitles": "Legendas",
- "subtitles off": "Sem Legendas",
- "Captions": "Anotações",
- "captions off": "Sem Anotações",
- "Chapters": "Capítulos",
- "You aborted the media playback": "Você parou a execução do vídeo.",
- "A network error caused the media download to fail part-way.": "Um erro na rede fez o vídeo parar parcialmente.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "O vídeo não pode ser carregado, ou porque houve um problema com sua rede ou pelo formato do vídeo não ser suportado.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "A execução foi interrompida por um problema com o vídeo ou por seu navegador não dar suporte ao seu formato.",
- "No compatible source was found for this media.": "Não foi encontrada fonte de vídeo compatível."
+videojs.addLanguage('pt-BR', {
+ "Audio Player": "Reprodutor de áudio",
+ "Video Player": "Reprodutor de vídeo",
+ "Play": "Tocar",
+ "Pause": "Pausar",
+ "Replay": "Tocar novamente",
+ "Current Time": "Tempo",
+ "Duration": "Duração",
+ "Remaining Time": "Tempo Restante",
+ "Stream Type": "Tipo de Stream",
+ "LIVE": "AO VIVO",
+ "Loaded": "Carregado",
+ "Progress": "Progresso",
+ "Progress Bar": "Barra de progresso",
+ "progress bar timing: currentTime={1} duration={2}": "{1} de {2}",
+ "Fullscreen": "Tela Cheia",
+ "Non-Fullscreen": "Tela Normal",
+ "Mute": "Mudo",
+ "Unmute": "Habilitar Som",
+ "Playback Rate": "Velocidade",
+ "Subtitles": "Legendas",
+ "subtitles off": "Sem Legendas",
+ "Captions": "Anotações",
+ "captions off": "Sem Anotações",
+ "Chapters": "Capítulos",
+ "Descriptions": "Descrições",
+ "descriptions off": "sem descrições",
+ "Audio Track": "Faixa de áudio",
+ "Volume Level": "Nível de volume",
+ "You aborted the media playback": "Você parou a execução do vídeo.",
+ "A network error caused the media download to fail part-way.": "Um erro na rede causou falha durante o download da mídia.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "A mídia não pode ser carregada, por uma falha de rede ou servidor ou o formato não é suportado.",
+ "No compatible source was found for this media.": "Nenhuma fonte foi encontrada para esta mídia.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "A reprodução foi interrompida devido à um problema de mídia corrompida ou porque a mídia utiliza funções que seu navegador não suporta.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "A mídia está criptografada e não temos as chaves para descriptografar.",
+ "Play Video": "Tocar Vídeo",
+ "Close": "Fechar",
+ "Close Modal Dialog": "Fechar Diálogo Modal",
+ "Modal Window": "Janela Modal",
+ "This is a modal window": "Isso é uma janela-modal",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Esta janela pode ser fechada pressionando a tecla de Escape.",
+ ", opens captions settings dialog": ", abre as configurações de legendas de comentários",
+ ", opens subtitles settings dialog": ", abre as configurações de legendas",
+ ", opens descriptions settings dialog": ", abre as configurações",
+ ", selected": ", selecionada",
+ "captions settings": "configurações de legendas de comentários",
+ "subtitles settings": "configurações de legendas",
+ "descriptions settings": "configurações das descrições",
+ "Text": "Texto",
+ "White": "Branco",
+ "Black": "Preto",
+ "Red": "Vermelho",
+ "Green": "Verde",
+ "Blue": "Azul",
+ "Yellow": "Amarelo",
+ "Magenta": "Magenta",
+ "Cyan": "Ciano",
+ "Background": "Plano-de-Fundo",
+ "Window": "Janela",
+ "Transparent": "Transparente",
+ "Semi-Transparent": "Semi-Transparente",
+ "Opaque": "Opaco",
+ "Font Size": "Tamanho da Fonte",
+ "Text Edge Style": "Estilo da Borda",
+ "None": "Nenhum",
+ "Raised": "Elevado",
+ "Depressed": "Acachapado",
+ "Uniform": "Uniforme",
+ "Dropshadow": "Sombra de projeção",
+ "Font Family": "Família da Fonte",
+ "Proportional Sans-Serif": "Sans-Serif(Sem serifa) Proporcional",
+ "Monospace Sans-Serif": "Sans-Serif(Sem serifa) Monoespaçada",
+ "Proportional Serif": "Serifa Proporcional",
+ "Monospace Serif": "Serifa Monoespaçada",
+ "Casual": "Casual",
+ "Script": "Script",
+ "Small Caps": "Maiúsculas Pequenas",
+ "Reset": "Redefinir",
+ "restore all settings to the default values": "restaurar todas as configurações aos valores padrão",
+ "Done": "Salvar",
+ "Caption Settings Dialog": "Caíxa-de-Diálogo das configurações de Legendas",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Iniciando a Janela-de-Diálogo. Pressionar Escape irá cancelar e fechar a janela.",
+ "End of dialog window.": "Fim da Janela-de-Diálogo",
+ "{1} is loading.": "{1} está carregando.",
+ "Exit Picture-in-Picture": "Sair de Picture-in-Picture",
+ "Picture-in-Picture": "Picture-in-Picture"
});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Reprodutor de áudio",
+ "Video Player": "Reprodutor de vídeo",
+ "Play": "Tocar",
+ "Pause": "Pausar",
+ "Replay": "Tocar novamente",
+ "Current Time": "Tempo",
+ "Duration": "Duração",
+ "Remaining Time": "Tempo Restante",
+ "Stream Type": "Tipo de Stream",
+ "LIVE": "AO VIVO",
+ "Loaded": "Carregado",
+ "Progress": "Progresso",
+ "Progress Bar": "Barra de progresso",
+ "progress bar timing: currentTime={1} duration={2}": "{1} de {2}",
+ "Fullscreen": "Tela Cheia",
+ "Non-Fullscreen": "Tela Normal",
+ "Mute": "Mudo",
+ "Unmute": "Habilitar Som",
+ "Playback Rate": "Velocidade",
+ "Subtitles": "Legendas",
+ "subtitles off": "Sem Legendas",
+ "Captions": "Anotações",
+ "captions off": "Sem Anotações",
+ "Chapters": "Capítulos",
+ "Descriptions": "Descrições",
+ "descriptions off": "sem descrições",
+ "Audio Track": "Faixa de áudio",
+ "Volume Level": "Nível de volume",
+ "You aborted the media playback": "Você parou a execução do vídeo.",
+ "A network error caused the media download to fail part-way.": "Um erro na rede causou falha durante o download da mídia.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "A mídia não pode ser carregada, por uma falha de rede ou servidor ou o formato não é suportado.",
+ "No compatible source was found for this media.": "Não foi encontrada fonte de mídia compatível.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "A reprodução foi interrompida devido à um problema de mídia corrompida ou porque a mídia utiliza funções que seu navegador não suporta.",
+ "No compatible source was found for this media.": "Nenhuma fonte foi encontrada para esta mídia.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "A mídia está criptografada e não temos as chaves para descriptografar.",
+ "Play Video": "Tocar Vídeo",
+ "Close": "Fechar",
+ "Close Modal Dialog": "Fechar Diálogo Modal",
+ "Modal Window": "Janela Modal",
+ "This is a modal window": "Isso é uma janela-modal",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Esta janela pode ser fechada pressionando a tecla de Escape.",
+ ", opens captions settings dialog": ", abre as configurações de legendas de comentários",
+ ", opens subtitles settings dialog": ", abre as configurações de legendas",
+ ", opens descriptions settings dialog": ", abre as configurações",
+ ", selected": ", selecionada",
+ "captions settings": "configurações de legendas de comentários",
+ "subtitles settings": "configurações de legendas",
+ "descriptions settings": "configurações das descrições",
+ "Text": "Texto",
+ "White": "Branco",
+ "Black": "Preto",
+ "Red": "Vermelho",
+ "Green": "Verde",
+ "Blue": "Azul",
+ "Yellow": "Amarelo",
+ "Magenta": "Magenta",
+ "Cyan": "Ciano",
+ "Background": "Plano-de-Fundo",
+ "Window": "Janela",
+ "Transparent": "Transparente",
+ "Semi-Transparent": "Semi-Transparente",
+ "Opaque": "Opaco",
+ "Font Size": "Tamanho da Fonte",
+ "Text Edge Style": "Estilo da Borda",
+ "None": "Nenhum",
+ "Raised": "Elevado",
+ "Depressed": "Acachapado",
+ "Uniform": "Uniforme",
+ "Dropshadow": "Sombra de projeção",
+ "Font Family": "Família da Fonte",
+ "Proportional Sans-Serif": "Sans-Serif(Sem serifa) Proporcional",
+ "Monospace Sans-Serif": "Sans-Serif(Sem serifa) Monoespaçada",
+ "Proportional Serif": "Serifa Proporcional",
+ "Monospace Serif": "Serifa Monoespaçada",
+ "Casual": "Casual",
+ "Script": "Script",
+ "Small Caps": "Maiúsculas Pequenas",
+ "Reset": "Redefinir",
+ "restore all settings to the default values": "restaurar todas as configurações aos valores padrão",
+ "Done": "Salvar",
+ "Caption Settings Dialog": "Caíxa-de-Diálogo das configurações de Legendas",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Iniciando a Janela-de-Diálogo. Pressionar Escape irá cancelar e fechar a janela.",
+ "End of dialog window.": "Fim da Janela-de-Diálogo",
+ "{1} is loading.": "{1} está carregando.",
+ "Exit Picture-in-Picture": "Sair de Picture-in-Picture",
+ "Picture-in-Picture": "Picture-in-Picture"
+}
-videojs.addLanguage("pt-PT",{
- "Play": "Reproduzir",
- "Pause": "Parar",
- "Replay": "Reiniciar",
- "Current Time": "Tempo Atual",
- "Duration Time": "Duração",
- "Remaining Time": "Tempo Restante",
- "Stream Type": "Tipo de Stream",
- "LIVE": "EM DIRETO",
- "Loaded": "Carregado",
- "Progress": "Progresso",
- "Fullscreen": "Ecrã inteiro",
- "Non-Fullscreen": "Ecrã normal",
- "Mute": "Desativar som",
- "Unmute": "Ativar som",
- "Playback Rate": "Velocidade de reprodução",
- "Subtitles": "Legendas",
- "subtitles off": "desativar legendas",
- "Captions": "Anotações",
- "captions off": "desativar anotações",
- "Chapters": "Capítulos",
- "Close Modal Dialog": "Fechar Janela Modal",
- "Descriptions": "Descrições",
- "descriptions off": "desativar descrições",
- "Audio Track": "Faixa Áudio",
- "You aborted the media playback": "Parou a reprodução do vídeo.",
- "A network error caused the media download to fail part-way.": "Um erro na rede fez o vídeo falhar parcialmente.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "O vídeo não pode ser carregado, ou porque houve um problema na rede ou no servidor, ou porque formato do vídeo não é compatível.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "A reprodução foi interrompida por um problema com o vídeo ou porque o formato não é compatível com o seu navegador.",
- "No compatible source was found for this media.": "Não foi encontrada uma fonte de vídeo compatível.",
- "The media is encrypted and we do not have the keys to decrypt it.": "O vídeo está encriptado e não há uma chave para o desencriptar.",
- "Play Video": "Reproduzir Vídeo",
- "Close": "Fechar",
- "Modal Window": "Janela Modal",
- "This is a modal window": "Isto é uma janela modal",
- "This modal can be closed by pressing the Escape key or activating the close button.": "Esta modal pode ser fechada pressionando a tecla ESC ou ativando o botão de fechar.",
- ", opens captions settings dialog": ", abre janela com definições de legendas",
- ", opens subtitles settings dialog": ", abre janela com definições de legendas",
- ", opens descriptions settings dialog": ", abre janela com definições de descrições",
- ", selected": ", seleccionado"
+videojs.addLanguage('pt-PT', {
+ "Play": "Reproduzir",
+ "Pause": "Parar",
+ "Replay": "Reiniciar",
+ "Current Time": "Tempo Atual",
+ "Duration": "Duração",
+ "Remaining Time": "Tempo Restante",
+ "Stream Type": "Tipo de Stream",
+ "LIVE": "EM DIRETO",
+ "Loaded": "Carregado",
+ "Progress": "Progresso",
+ "Fullscreen": "Ecrã inteiro",
+ "Non-Fullscreen": "Ecrã normal",
+ "Mute": "Desativar som",
+ "Unmute": "Ativar som",
+ "Playback Rate": "Velocidade de reprodução",
+ "Subtitles": "Legendas",
+ "subtitles off": "desativar legendas",
+ "Captions": "Anotações",
+ "captions off": "desativar anotações",
+ "Chapters": "Capítulos",
+ "Close Modal Dialog": "Fechar Janela Modal",
+ "Descriptions": "Descrições",
+ "descriptions off": "desativar descrições",
+ "Audio Track": "Faixa Áudio",
+ "You aborted the media playback": "Parou a reprodução do vídeo.",
+ "A network error caused the media download to fail part-way.": "Um erro na rede fez o vídeo falhar parcialmente.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "O vídeo não pode ser carregado, ou porque houve um problema na rede ou no servidor, ou porque formato do vídeo não é compatível.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "A reprodução foi interrompida por um problema com o vídeo ou porque o formato não é compatível com o seu navegador.",
+ "No compatible source was found for this media.": "Não foi encontrada uma fonte de vídeo compatível.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "O vídeo está encriptado e não há uma chave para o desencriptar.",
+ "Play Video": "Reproduzir Vídeo",
+ "Close": "Fechar",
+ "Modal Window": "Janela Modal",
+ "This is a modal window": "Isto é uma janela modal",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Esta modal pode ser fechada pressionando a tecla ESC ou ativando o botão de fechar.",
+ ", opens captions settings dialog": ", abre janela com definições de legendas",
+ ", opens subtitles settings dialog": ", abre janela com definições de legendas",
+ ", opens descriptions settings dialog": ", abre janela com definições de descrições",
+ ", selected": ", seleccionado"
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Reproduzir",
+ "Pause": "Parar",
+ "Replay": "Reiniciar",
+ "Current Time": "Tempo Atual",
+ "Duration": "Duração",
+ "Remaining Time": "Tempo Restante",
+ "Stream Type": "Tipo de Stream",
+ "LIVE": "EM DIRETO",
+ "Loaded": "Carregado",
+ "Progress": "Progresso",
+ "Fullscreen": "Ecrã inteiro",
+ "Non-Fullscreen": "Ecrã normal",
+ "Mute": "Desativar som",
+ "Unmute": "Ativar som",
+ "Playback Rate": "Velocidade de reprodução",
+ "Subtitles": "Legendas",
+ "subtitles off": "desativar legendas",
+ "Captions": "Anotações",
+ "captions off": "desativar anotações",
+ "Chapters": "Capítulos",
+ "Close Modal Dialog": "Fechar Janela Modal",
+ "Descriptions": "Descrições",
+ "descriptions off": "desativar descrições",
+ "Audio Track": "Faixa Áudio",
+ "You aborted the media playback": "Parou a reprodução do vídeo.",
+ "A network error caused the media download to fail part-way.": "Um erro na rede fez o vídeo falhar parcialmente.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "O vídeo não pode ser carregado, ou porque houve um problema na rede ou no servidor, ou porque formato do vídeo não é compatível.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "A reprodução foi interrompida por um problema com o vídeo ou porque o formato não é compatível com o seu navegador.",
+ "No compatible source was found for this media.": "Não foi encontrada uma fonte de vídeo compatível.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "O vídeo está encriptado e não há uma chave para o desencriptar.",
+ "Play Video": "Reproduzir Vídeo",
+ "Close": "Fechar",
+ "Modal Window": "Janela Modal",
+ "This is a modal window": "Isto é uma janela modal",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Esta modal pode ser fechada pressionando a tecla ESC ou ativando o botão de fechar.",
+ ", opens captions settings dialog": ", abre janela com definições de legendas",
+ ", opens subtitles settings dialog": ", abre janela com definições de legendas",
+ ", opens descriptions settings dialog": ", abre janela com definições de descrições",
+ ", selected": ", seleccionado"
+}
\ No newline at end of file
--- /dev/null
+videojs.addLanguage('ro', {
+ "Audio Player": "Player audio",
+ "Video Player": "Player video",
+ "Play": "Piesă",
+ "Pause": "Pauză",
+ "Replay": "Reluare",
+ "Current Time": "Ora curentă",
+ "Duration": "Durată",
+ "Remaining Time": "Timp rămas",
+ "Stream Type": "Tip flux",
+ "LIVE": "ÎN DIRECT",
+ "Seek to live, currently behind live": "Căutare în direct; în prezent, sunteți în urmă",
+ "Seek to live, currently playing live": "Căutare în direct; în prezent, se redă în direct",
+ "Loaded": "Încărcat",
+ "Progress": "Progres",
+ "Progress Bar": "Bară de progres",
+ "progress bar timing: currentTime={1} duration={2}": "{1} din {2}",
+ "Fullscreen": "Ecran complet",
+ "Non-Fullscreen": "Ecran parțial",
+ "Mute": "Suprimare sunet",
+ "Unmute": "Activare sunet",
+ "Playback Rate": "Rată de redare",
+ "Subtitles": "Subtitrări",
+ "subtitles off": "subtitrări dezactivate",
+ "Captions": "Indicații scrise",
+ "captions off": "indicații scrise dezactivate",
+ "Chapters": "Capitole",
+ "Descriptions": "Descrieri",
+ "descriptions off": "descrieri dezactivate",
+ "Audio Track": "Pistă audio",
+ "Volume Level": "Nivel volum",
+ "You aborted the media playback": "Ați abandonat redarea media",
+ "A network error caused the media download to fail part-way.": "O eroare de rețea a provocat eșecul descărcării conținutului media în timpul procesului.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Conținutul media nu a putut fi încărcat, fie pentru că serverul sau rețeaua a eșuat, fie pentru că formatul nu este acceptat.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Redarea media a fost întreruptă din cauza conținutului corupt sau din cauza faptului că acest conținut media folosește funcții pe care browserul dvs. nu le acceptă.",
+ "No compatible source was found for this media.": "Nu au fost găsite surse compatibile pentru acest conținut media.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Conținutul media este criptată și nu avem cheile pentru decriptare.",
+ "Play Video": "Redare video",
+ "Close": "Închidere",
+ "Close Modal Dialog": "Închidere dialog modal",
+ "Modal Window": "Fereastră modală",
+ "This is a modal window": "Aceasta este o fereastră modală",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Această fereastră modală poate fi închisă cu tasta Escape sau butonul de închidere.",
+ ", opens captions settings dialog": ", deschide dialogul de setări pentru indicații scrise",
+ ", opens subtitles settings dialog": ", deschide dialogul de setări pentru subtitrări",
+ ", opens descriptions settings dialog": ", deschide dialogul de setări pentru descrieri",
+ ", selected": ", selectat",
+ "captions settings": "setări indicații scrise",
+ "subtitles settings": "setări subtitrări",
+ "descriptions settings": "setări descrieri",
+ "Text": "Text",
+ "White": "Alb",
+ "Black": "Negru",
+ "Red": "Roșu",
+ "Green": "Verde",
+ "Blue": "Albastru",
+ "Yellow": "Galben",
+ "Magenta": "Magenta",
+ "Cyan": "Cyan",
+ "Background": "Fundal",
+ "Window": "Fereastră",
+ "Transparent": "Transparent",
+ "Semi-Transparent": "Semitransparent",
+ "Opaque": "Opac",
+ "Font Size": "Mărime font",
+ "Text Edge Style": "Stil margine text",
+ "None": "Fără",
+ "Raised": "Ridicat",
+ "Depressed": "Apăsat",
+ "Uniform": "Uniformă",
+ "Dropshadow": "Umbră",
+ "Font Family": "Familie fonturi",
+ "Proportional Sans-Serif": "Sans-serif proporțional",
+ "Monospace Sans-Serif": "Sans-serif monospațiu",
+ "Proportional Serif": "Serif proporțional",
+ "Monospace Serif": "Serif monospațiu",
+ "Casual": "Informal",
+ "Script": "Script",
+ "Small Caps": "Majuscule mici",
+ "Reset": "Resetare",
+ "restore all settings to the default values": "readuceți toate setările la valorile implicite",
+ "Done": "Terminat",
+ "Caption Settings Dialog": "Dialog setări indicații scrise",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Începutul ferestrei de dialog. Tasta Escape va anula și va închide fereastra.",
+ "End of dialog window.": "Sfârșitul ferestrei de dialog.",
+ "{1} is loading.": "{1} se încarcă.",
+ "Exit Picture-in-Picture": "Închidere imagine în imagine",
+ "Picture-in-Picture": "Imagine în imagine"
+});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Player audio",
+ "Video Player": "Player video",
+ "Play": "Piesă",
+ "Pause": "Pauză",
+ "Replay": "Reluare",
+ "Current Time": "Ora curentă",
+ "Duration": "Durată",
+ "Remaining Time": "Timp rămas",
+ "Stream Type": "Tip flux",
+ "LIVE": "ÎN DIRECT",
+ "Seek to live, currently behind live": "Căutare în direct; în prezent, sunteți în urmă",
+ "Seek to live, currently playing live": "Căutare în direct; în prezent, se redă în direct",
+ "Loaded": "Încărcat",
+ "Progress": "Progres",
+ "Progress Bar": "Bară de progres",
+ "progress bar timing: currentTime={1} duration={2}": "{1} din {2}",
+ "Fullscreen": "Ecran complet",
+ "Non-Fullscreen": "Ecran parțial",
+ "Mute": "Suprimare sunet",
+ "Unmute": "Activare sunet",
+ "Playback Rate": "Rată de redare",
+ "Subtitles": "Subtitrări",
+ "subtitles off": "subtitrări dezactivate",
+ "Captions": "Indicații scrise",
+ "captions off": "indicații scrise dezactivate",
+ "Chapters": "Capitole",
+ "Descriptions": "Descrieri",
+ "descriptions off": "descrieri dezactivate",
+ "Audio Track": "Pistă audio",
+ "Volume Level": "Nivel volum",
+ "You aborted the media playback": "Ați abandonat redarea media",
+ "A network error caused the media download to fail part-way.": "O eroare de rețea a provocat eșecul descărcării conținutului media în timpul procesului.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Conținutul media nu a putut fi încărcat, fie pentru că serverul sau rețeaua a eșuat, fie pentru că formatul nu este acceptat.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Redarea media a fost întreruptă din cauza conținutului corupt sau din cauza faptului că acest conținut media folosește funcții pe care browserul dvs. nu le acceptă.",
+ "No compatible source was found for this media.": "Nu au fost găsite surse compatibile pentru acest conținut media.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Conținutul media este criptată și nu avem cheile pentru decriptare.",
+ "Play Video": "Redare video",
+ "Close": "Închidere",
+ "Close Modal Dialog": "Închidere dialog modal",
+ "Modal Window": "Fereastră modală",
+ "This is a modal window": "Aceasta este o fereastră modală",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Această fereastră modală poate fi închisă cu tasta Escape sau butonul de închidere.",
+ ", opens captions settings dialog": ", deschide dialogul de setări pentru indicații scrise",
+ ", opens subtitles settings dialog": ", deschide dialogul de setări pentru subtitrări",
+ ", opens descriptions settings dialog": ", deschide dialogul de setări pentru descrieri",
+ ", selected": ", selectat",
+ "captions settings": "setări indicații scrise",
+ "subtitles settings": "setări subtitrări",
+ "descriptions settings": "setări descrieri",
+ "Text": "Text",
+ "White": "Alb",
+ "Black": "Negru",
+ "Red": "Roșu",
+ "Green": "Verde",
+ "Blue": "Albastru",
+ "Yellow": "Galben",
+ "Magenta": "Magenta",
+ "Cyan": "Cyan",
+ "Background": "Fundal",
+ "Window": "Fereastră",
+ "Transparent": "Transparent",
+ "Semi-Transparent": "Semitransparent",
+ "Opaque": "Opac",
+ "Font Size": "Mărime font",
+ "Text Edge Style": "Stil margine text",
+ "None": "Fără",
+ "Raised": "Ridicat",
+ "Depressed": "Apăsat",
+ "Uniform": "Uniformă",
+ "Dropshadow": "Umbră",
+ "Font Family": "Familie fonturi",
+ "Proportional Sans-Serif": "Sans-serif proporțional",
+ "Monospace Sans-Serif": "Sans-serif monospațiu",
+ "Proportional Serif": "Serif proporțional",
+ "Monospace Serif": "Serif monospațiu",
+ "Casual": "Informal",
+ "Script": "Script",
+ "Small Caps": "Majuscule mici",
+ "Reset": "Resetare",
+ "restore all settings to the default values": "readuceți toate setările la valorile implicite",
+ "Done": "Terminat",
+ "Caption Settings Dialog": "Dialog setări indicații scrise",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Începutul ferestrei de dialog. Tasta Escape va anula și va închide fereastra.",
+ "End of dialog window.": "Sfârșitul ferestrei de dialog.",
+ "{1} is loading.": "{1} se încarcă.",
+ "Exit Picture-in-Picture": "Închidere imagine în imagine",
+ "Picture-in-Picture": "Imagine în imagine"
+}
-videojs.addLanguage("ru",{
- "Audio Player": "Аудио проигрыватель",
- "Video Player": "Видео проигрыватель",
- "Play": "Воспроизвести",
- "Pause": "Приостановить",
- "Replay": "Воспроизвести снова",
- "Current Time": "Текущее время",
- "Duration Time": "Продолжительность",
- "Remaining Time": "Оставшееся время",
- "Stream Type": "Тип потока",
- "LIVE": "ОНЛАЙН",
- "Loaded": "Загрузка",
- "Progress": "Прогресс",
- "Progress Bar": "Индикатор загрузки",
- "progress bar timing: currentTime={1} duration={2}": "{1} из {2}",
- "Fullscreen": "Полноэкранный режим",
- "Non-Fullscreen": "Неполноэкранный режим",
- "Mute": "Без звука",
- "Unmute": "Со звуком",
- "Playback Rate": "Скорость воспроизведения",
- "Subtitles": "Субтитры",
- "subtitles off": "Субтитры выкл.",
- "Captions": "Подписи",
- "captions off": "Подписи выкл.",
- "Chapters": "Главы",
- "Descriptions": "Описания",
- "descriptions off": "Отключить описания",
- "Audio Track": "Звуковая дорожка",
- "Volume Level": "Уровень громкости",
- "You aborted the media playback": "Вы прервали воспроизведение видео",
- "A network error caused the media download to fail part-way.": "Ошибка сети вызвала сбой во время загрузки видео.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Невозможно загрузить видео из-за сетевого или серверного сбоя либо формат не поддерживается.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Воспроизведение видео было приостановлено из-за повреждения либо в связи с тем, что видео использует функции, неподдерживаемые вашим браузером.",
- "No compatible source was found for this media.": "Совместимые источники для этого видео отсутствуют.",
- "The media is encrypted and we do not have the keys to decrypt it.": "Видео в зашифрованном виде, и у нас нет ключей для расшифровки.",
- "Play Video": "Воспроизвести видео",
- "Close": "Закрыть",
- "Close Modal Dialog": "Закрыть модальное окно",
- "Modal Window": "Модальное окно",
- "This is a modal window": "Это модальное окно",
- "This modal can be closed by pressing the Escape key or activating the close button.": "Модальное окно можно закрыть нажав Esc или кнопку закрытия окна.",
- ", opens captions settings dialog": ", откроется диалог настройки подписей",
- ", opens subtitles settings dialog": ", откроется диалог настройки субтитров",
- ", opens descriptions settings dialog": ", откроется диалог настройки описаний",
- ", selected": ", выбрано",
- "captions settings": "настройки подписей",
- "subtitles settings": "настройки субтитров",
- "descriptions settings": "настройки описаний",
- "Text": "Текст",
- "White": "Белый",
- "Black": "Черный",
- "Red": "Красный",
- "Green": "Зеленый",
- "Blue": "Синий",
- "Yellow": "Желтый",
- "Magenta": "Пурпурный",
- "Cyan": "Голубой",
- "Background": "Фон",
- "Window": "Окно",
- "Transparent": "Прозрачный",
- "Semi-Transparent": "Полупрозрачный",
- "Opaque": "Прозрачность",
- "Font Size": "Размер шрифта",
- "Text Edge Style": "Стиль края текста",
- "None": "Ничего",
- "Raised": "Поднятый",
- "Depressed": "Пониженный",
- "Uniform": "Одинаковый",
- "Dropshadow": "Тень",
- "Font Family": "Шрифт",
- "Proportional Sans-Serif": "Пропорциональный без засечек",
- "Monospace Sans-Serif": "Моноширинный без засечек",
- "Proportional Serif": "Пропорциональный с засечками",
- "Monospace Serif": "Моноширинный с засечками",
- "Casual": "Случайный",
- "Script": "Письменный",
- "Small Caps": "Малые прописные",
- "Reset": "Сбросить",
- "restore all settings to the default values": "сбросить все найстройки по умолчанию",
- "Done": "Готово",
- "Caption Settings Dialog": "Диалог настроек подписи",
- "Beginning of dialog window. Escape will cancel and close the window.": "Начало диалоговго окна. Кнопка Escape закроет или отменит окно",
- "End of dialog window.": "Конец диалогового окна."
+videojs.addLanguage('ru', {
+ "Audio Player": "Аудио проигрыватель",
+ "Video Player": "Видео проигрыватель",
+ "Play": "Воспроизвести",
+ "Pause": "Приостановить",
+ "Replay": "Воспроизвести снова",
+ "Current Time": "Текущее время",
+ "Duration": "Продолжительность",
+ "Remaining Time": "Оставшееся время",
+ "Stream Type": "Тип потока",
+ "LIVE": "ОНЛАЙН",
+ "Loaded": "Загрузка",
+ "Progress": "Прогресс",
+ "Progress Bar": "Индикатор загрузки",
+ "progress bar timing: currentTime={1} duration={2}": "{1} из {2}",
+ "Fullscreen": "Полноэкранный режим",
+ "Non-Fullscreen": "Неполноэкранный режим",
+ "Mute": "Без звука",
+ "Unmute": "Со звуком",
+ "Playback Rate": "Скорость воспроизведения",
+ "Subtitles": "Субтитры",
+ "subtitles off": "Субтитры выкл.",
+ "Captions": "Подписи",
+ "captions off": "Подписи выкл.",
+ "Chapters": "Главы",
+ "Descriptions": "Описания",
+ "descriptions off": "Отключить описания",
+ "Audio Track": "Звуковая дорожка",
+ "Volume Level": "Уровень громкости",
+ "You aborted the media playback": "Вы прервали воспроизведение видео",
+ "A network error caused the media download to fail part-way.": "Ошибка сети вызвала сбой во время загрузки видео.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Невозможно загрузить видео из-за сетевого или серверного сбоя либо формат не поддерживается.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Воспроизведение видео было приостановлено из-за повреждения либо в связи с тем, что видео использует функции, неподдерживаемые вашим браузером.",
+ "No compatible source was found for this media.": "Совместимые источники для этого видео отсутствуют.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Видео в зашифрованном виде, и у нас нет ключей для расшифровки.",
+ "Play Video": "Воспроизвести видео",
+ "Close": "Закрыть",
+ "Close Modal Dialog": "Закрыть модальное окно",
+ "Modal Window": "Модальное окно",
+ "This is a modal window": "Это модальное окно",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Модальное окно можно закрыть нажав Esc или кнопку закрытия окна.",
+ ", opens captions settings dialog": ", откроется диалог настройки подписей",
+ ", opens subtitles settings dialog": ", откроется диалог настройки субтитров",
+ ", opens descriptions settings dialog": ", откроется диалог настройки описаний",
+ ", selected": ", выбрано",
+ "captions settings": "настройки подписей",
+ "subtitles settings": "настройки субтитров",
+ "descriptions settings": "настройки описаний",
+ "Text": "Текст",
+ "White": "Белый",
+ "Black": "Черный",
+ "Red": "Красный",
+ "Green": "Зеленый",
+ "Blue": "Синий",
+ "Yellow": "Желтый",
+ "Magenta": "Пурпурный",
+ "Cyan": "Голубой",
+ "Background": "Фон",
+ "Window": "Окно",
+ "Transparent": "Прозрачный",
+ "Semi-Transparent": "Полупрозрачный",
+ "Opaque": "Прозрачность",
+ "Font Size": "Размер шрифта",
+ "Text Edge Style": "Стиль края текста",
+ "None": "Ничего",
+ "Raised": "Поднятый",
+ "Depressed": "Пониженный",
+ "Uniform": "Одинаковый",
+ "Dropshadow": "Тень",
+ "Font Family": "Шрифт",
+ "Proportional Sans-Serif": "Пропорциональный без засечек",
+ "Monospace Sans-Serif": "Моноширинный без засечек",
+ "Proportional Serif": "Пропорциональный с засечками",
+ "Monospace Serif": "Моноширинный с засечками",
+ "Casual": "Случайный",
+ "Script": "Письменный",
+ "Small Caps": "Малые прописные",
+ "Reset": "Сбросить",
+ "restore all settings to the default values": "сбросить все найстройки по умолчанию",
+ "Done": "Готово",
+ "Caption Settings Dialog": "Диалог настроек подписи",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Начало диалоговго окна. Кнопка Escape закроет или отменит окно",
+ "End of dialog window.": "Конец диалогового окна.",
+ "{1} is loading.": "{1} загружается."
});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Аудио проигрыватель",
+ "Video Player": "Видео проигрыватель",
+ "Play": "Воспроизвести",
+ "Pause": "Приостановить",
+ "Replay": "Воспроизвести снова",
+ "Current Time": "Текущее время",
+ "Duration": "Продолжительность",
+ "Remaining Time": "Оставшееся время",
+ "Stream Type": "Тип потока",
+ "LIVE": "ОНЛАЙН",
+ "Loaded": "Загрузка",
+ "Progress": "Прогресс",
+ "Progress Bar": "Индикатор загрузки",
+ "progress bar timing: currentTime={1} duration={2}": "{1} из {2}",
+ "Fullscreen": "Полноэкранный режим",
+ "Non-Fullscreen": "Неполноэкранный режим",
+ "Mute": "Без звука",
+ "Unmute": "Со звуком",
+ "Playback Rate": "Скорость воспроизведения",
+ "Subtitles": "Субтитры",
+ "subtitles off": "Субтитры выкл.",
+ "Captions": "Подписи",
+ "captions off": "Подписи выкл.",
+ "Chapters": "Главы",
+ "Descriptions": "Описания",
+ "descriptions off": "Отключить описания",
+ "Audio Track": "Звуковая дорожка",
+ "Volume Level": "Уровень громкости",
+ "You aborted the media playback": "Вы прервали воспроизведение видео",
+ "A network error caused the media download to fail part-way.": "Ошибка сети вызвала сбой во время загрузки видео.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Невозможно загрузить видео из-за сетевого или серверного сбоя либо формат не поддерживается.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Воспроизведение видео было приостановлено из-за повреждения либо в связи с тем, что видео использует функции, неподдерживаемые вашим браузером.",
+ "No compatible source was found for this media.": "Совместимые источники для этого видео отсутствуют.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Видео в зашифрованном виде, и у нас нет ключей для расшифровки.",
+ "Play Video": "Воспроизвести видео",
+ "Close": "Закрыть",
+ "Close Modal Dialog": "Закрыть модальное окно",
+ "Modal Window": "Модальное окно",
+ "This is a modal window": "Это модальное окно",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Модальное окно можно закрыть нажав Esc или кнопку закрытия окна.",
+ ", opens captions settings dialog": ", откроется диалог настройки подписей",
+ ", opens subtitles settings dialog": ", откроется диалог настройки субтитров",
+ ", opens descriptions settings dialog": ", откроется диалог настройки описаний",
+ ", selected": ", выбрано",
+ "captions settings": "настройки подписей",
+ "subtitles settings": "настройки субтитров",
+ "descriptions settings": "настройки описаний",
+ "Text": "Текст",
+ "White": "Белый",
+ "Black": "Черный",
+ "Red": "Красный",
+ "Green": "Зеленый",
+ "Blue": "Синий",
+ "Yellow": "Желтый",
+ "Magenta": "Пурпурный",
+ "Cyan": "Голубой",
+ "Background": "Фон",
+ "Window": "Окно",
+ "Transparent": "Прозрачный",
+ "Semi-Transparent": "Полупрозрачный",
+ "Opaque": "Прозрачность",
+ "Font Size": "Размер шрифта",
+ "Text Edge Style": "Стиль края текста",
+ "None": "Ничего",
+ "Raised": "Поднятый",
+ "Depressed": "Пониженный",
+ "Uniform": "Одинаковый",
+ "Dropshadow": "Тень",
+ "Font Family": "Шрифт",
+ "Proportional Sans-Serif": "Пропорциональный без засечек",
+ "Monospace Sans-Serif": "Моноширинный без засечек",
+ "Proportional Serif": "Пропорциональный с засечками",
+ "Monospace Serif": "Моноширинный с засечками",
+ "Casual": "Случайный",
+ "Script": "Письменный",
+ "Small Caps": "Малые прописные",
+ "Reset": "Сбросить",
+ "restore all settings to the default values": "сбросить все найстройки по умолчанию",
+ "Done": "Готово",
+ "Caption Settings Dialog": "Диалог настроек подписи",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Начало диалоговго окна. Кнопка Escape закроет или отменит окно",
+ "End of dialog window.": "Конец диалогового окна.",
+ "{1} is loading.": "{1} загружается."
+}
-videojs.addLanguage("sk",{
- "Audio Player": "Zvukový prehrávač",
- "Video Player": "Video prehrávač",
- "Play": "Prehrať",
- "Pause": "Pozastaviť",
- "Replay": "Prehrať znova",
- "Current Time": "Aktuálny čas",
- "Duration Time": "Čas trvania",
- "Remaining Time": "Zostávajúci čas",
- "Stream Type": "Typ stopy",
- "LIVE": "NAŽIVO",
- "Loaded": "Načítané",
- "Progress": "Priebeh",
- "Progress Bar": "Ukazovateľ priebehu",
- "progress bar timing: currentTime={1} duration={2}": "časovanie ukazovateľa priebehu: currentTime={1} duration={2}",
- "Fullscreen": "Režim celej obrazovky",
- "Non-Fullscreen": "Režim normálnej obrazovky",
- "Mute": "Stlmiť",
- "Unmute": "Zrušiť stlmenie",
- "Playback Rate": "Rýchlosť prehrávania",
- "Subtitles": "Titulky",
- "subtitles off": "titulky vypnuté",
- "Captions": "Popisky",
- "captions off": "popisky vypnuté",
- "Chapters": "Kapitoly",
- "Descriptions": "Opisy",
- "descriptions off": "opisy vypnuté",
- "Audio Track": "Zvuková stopa",
- "Volume Level": "Úroveň hlasitosti",
- "You aborted the media playback": "Prerušili ste prehrávanie",
- "A network error caused the media download to fail part-way.": "Sťahovanie súboru bolo zrušené pre chybu na sieti.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Súbor sa nepodarilo načítať pre chybu servera, sieťového pripojenia, alebo je formát súboru nepodporovaný.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Prehrávanie súboru bolo prerušené pre poškodené dáta, alebo súbor používa vlastnosti, ktoré váš prehliadač nepodporuje.",
- "No compatible source was found for this media.": "Nebol nájdený žiaden kompatibilný zdroj pre tento súbor.",
- "The media is encrypted and we do not have the keys to decrypt it.": "Súbor je zašifrovaný a nie je k dispozícii kľúč na rozšifrovanie.",
- "Play Video": "Prehrať video",
- "Close": "Zatvoriť",
- "Close Modal Dialog": "Zatvoriť modálne okno",
- "Modal Window": "Modálne okno",
- "This is a modal window": "Toto je modálne okno",
- "This modal can be closed by pressing the Escape key or activating the close button.": "Toto modálne okno je možné zatvoriť stlačením klávesy Escape, alebo aktivovaním tlačidla na zatvorenie.",
- ", opens captions settings dialog": ", otvorí okno nastavení popiskov",
- ", opens subtitles settings dialog": ", otvorí okno nastavení titulkov",
- ", opens descriptions settings dialog": ", otvorí okno nastavení opisov",
- ", selected": ", označené",
- "captions settings": "nastavenia popiskov",
- "subtitles settings": "nastavenia titulkov",
- "descriptions settings": "nastavenia opisov",
- "Text": "Text",
- "White": "Biela",
- "Black": "Čierna",
- "Red": "Červená",
- "Green": "Zelená",
- "Blue": "Modrá",
- "Yellow": "Žltá",
- "Magenta": "Ružová",
- "Cyan": "Tyrkysová",
- "Background": "Pozadie",
- "Window": "Okno",
- "Transparent": "Priesvitné",
- "Semi-Transparent": "Polopriesvitné",
- "Opaque": "Plné",
- "Font Size": "Veľkosť písma",
- "Text Edge Style": "Typ okrajov písma",
- "None": "Žiadne",
- "Raised": "Zvýšené",
- "Depressed": "Znížené",
- "Uniform": "Pravidelné",
- "Dropshadow": "S tieňom",
- "Font Family": "Typ písma",
- "Proportional Sans-Serif": "Proporčné bezpätkové",
- "Monospace Sans-Serif": "Pravidelné, bezpätkové",
- "Proportional Serif": "Proporčné pätkové",
- "Monospace Serif": "Pravidelné pätkové",
- "Casual": "Bežné",
- "Script": "Písané",
- "Small Caps": "Malé kapitálky",
- "Reset": "Resetovať",
- "restore all settings to the default values": "všetky nastavenia na základné hodnoty",
- "Done": "Hotovo",
- "Caption Settings Dialog": "Okno nastavení popiskov",
- "Beginning of dialog window. Escape will cancel and close the window.": "Začiatok okna. Klávesa Escape zruší a zavrie okno.",
- "End of dialog window.": "Koniec okna."
+videojs.addLanguage('sk', {
+ "Audio Player": "Zvukový prehrávač",
+ "Video Player": "Video prehrávač",
+ "Play": "Prehrať",
+ "Pause": "Pozastaviť",
+ "Replay": "Prehrať znova",
+ "Current Time": "Aktuálny čas",
+ "Duration": "Čas trvania",
+ "Remaining Time": "Zostávajúci čas",
+ "Stream Type": "Typ stopy",
+ "LIVE": "NAŽIVO",
+ "Loaded": "Načítané",
+ "Progress": "Priebeh",
+ "Progress Bar": "Ukazovateľ priebehu",
+ "progress bar timing: currentTime={1} duration={2}": "časovanie ukazovateľa priebehu: currentTime={1} duration={2}",
+ "Fullscreen": "Režim celej obrazovky",
+ "Non-Fullscreen": "Režim normálnej obrazovky",
+ "Mute": "Stlmiť",
+ "Unmute": "Zrušiť stlmenie",
+ "Playback Rate": "Rýchlosť prehrávania",
+ "Subtitles": "Titulky",
+ "subtitles off": "titulky vypnuté",
+ "Captions": "Popisky",
+ "captions off": "popisky vypnuté",
+ "Chapters": "Kapitoly",
+ "Descriptions": "Opisy",
+ "descriptions off": "opisy vypnuté",
+ "Audio Track": "Zvuková stopa",
+ "Volume Level": "Úroveň hlasitosti",
+ "You aborted the media playback": "Prerušili ste prehrávanie",
+ "A network error caused the media download to fail part-way.": "Sťahovanie súboru bolo zrušené pre chybu na sieti.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Súbor sa nepodarilo načítať pre chybu servera, sieťového pripojenia, alebo je formát súboru nepodporovaný.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Prehrávanie súboru bolo prerušené pre poškodené dáta, alebo súbor používa vlastnosti, ktoré váš prehliadač nepodporuje.",
+ "No compatible source was found for this media.": "Nebol nájdený žiaden kompatibilný zdroj pre tento súbor.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Súbor je zašifrovaný a nie je k dispozícii kľúč na rozšifrovanie.",
+ "Play Video": "Prehrať video",
+ "Close": "Zatvoriť",
+ "Close Modal Dialog": "Zatvoriť modálne okno",
+ "Modal Window": "Modálne okno",
+ "This is a modal window": "Toto je modálne okno",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Toto modálne okno je možné zatvoriť stlačením klávesy Escape, alebo aktivovaním tlačidla na zatvorenie.",
+ ", opens captions settings dialog": ", otvorí okno nastavení popiskov",
+ ", opens subtitles settings dialog": ", otvorí okno nastavení titulkov",
+ ", opens descriptions settings dialog": ", otvorí okno nastavení opisov",
+ ", selected": ", označené",
+ "captions settings": "nastavenia popiskov",
+ "subtitles settings": "nastavenia titulkov",
+ "descriptions settings": "nastavenia opisov",
+ "Text": "Text",
+ "White": "Biela",
+ "Black": "Čierna",
+ "Red": "Červená",
+ "Green": "Zelená",
+ "Blue": "Modrá",
+ "Yellow": "Žltá",
+ "Magenta": "Ružová",
+ "Cyan": "Tyrkysová",
+ "Background": "Pozadie",
+ "Window": "Okno",
+ "Transparent": "Priesvitné",
+ "Semi-Transparent": "Polopriesvitné",
+ "Opaque": "Plné",
+ "Font Size": "Veľkosť písma",
+ "Text Edge Style": "Typ okrajov písma",
+ "None": "Žiadne",
+ "Raised": "Zvýšené",
+ "Depressed": "Znížené",
+ "Uniform": "Pravidelné",
+ "Dropshadow": "S tieňom",
+ "Font Family": "Typ písma",
+ "Proportional Sans-Serif": "Proporčné bezpätkové",
+ "Monospace Sans-Serif": "Pravidelné, bezpätkové",
+ "Proportional Serif": "Proporčné pätkové",
+ "Monospace Serif": "Pravidelné pätkové",
+ "Casual": "Bežné",
+ "Script": "Písané",
+ "Small Caps": "Malé kapitálky",
+ "Reset": "Resetovať",
+ "restore all settings to the default values": "všetky nastavenia na základné hodnoty",
+ "Done": "Hotovo",
+ "Caption Settings Dialog": "Okno nastavení popiskov",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Začiatok okna. Klávesa Escape zruší a zavrie okno.",
+ "End of dialog window.": "Koniec okna.",
+ "{1} is loading.": "{1} sa načíta."
});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Zvukový prehrávač",
+ "Video Player": "Video prehrávač",
+ "Play": "Prehrať",
+ "Pause": "Pozastaviť",
+ "Replay": "Prehrať znova",
+ "Current Time": "Aktuálny čas",
+ "Duration": "Čas trvania",
+ "Remaining Time": "Zostávajúci čas",
+ "Stream Type": "Typ stopy",
+ "LIVE": "NAŽIVO",
+ "Loaded": "Načítané",
+ "Progress": "Priebeh",
+ "Progress Bar": "Ukazovateľ priebehu",
+ "progress bar timing: currentTime={1} duration={2}": "časovanie ukazovateľa priebehu: currentTime={1} duration={2}",
+ "Fullscreen": "Režim celej obrazovky",
+ "Non-Fullscreen": "Režim normálnej obrazovky",
+ "Mute": "Stlmiť",
+ "Unmute": "Zrušiť stlmenie",
+ "Playback Rate": "Rýchlosť prehrávania",
+ "Subtitles": "Titulky",
+ "subtitles off": "titulky vypnuté",
+ "Captions": "Popisky",
+ "captions off": "popisky vypnuté",
+ "Chapters": "Kapitoly",
+ "Descriptions": "Opisy",
+ "descriptions off": "opisy vypnuté",
+ "Audio Track": "Zvuková stopa",
+ "Volume Level": "Úroveň hlasitosti",
+ "You aborted the media playback": "Prerušili ste prehrávanie",
+ "A network error caused the media download to fail part-way.": "Sťahovanie súboru bolo zrušené pre chybu na sieti.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Súbor sa nepodarilo načítať pre chybu servera, sieťového pripojenia, alebo je formát súboru nepodporovaný.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Prehrávanie súboru bolo prerušené pre poškodené dáta, alebo súbor používa vlastnosti, ktoré váš prehliadač nepodporuje.",
+ "No compatible source was found for this media.": "Nebol nájdený žiaden kompatibilný zdroj pre tento súbor.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Súbor je zašifrovaný a nie je k dispozícii kľúč na rozšifrovanie.",
+ "Play Video": "Prehrať video",
+ "Close": "Zatvoriť",
+ "Close Modal Dialog": "Zatvoriť modálne okno",
+ "Modal Window": "Modálne okno",
+ "This is a modal window": "Toto je modálne okno",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Toto modálne okno je možné zatvoriť stlačením klávesy Escape, alebo aktivovaním tlačidla na zatvorenie.",
+ ", opens captions settings dialog": ", otvorí okno nastavení popiskov",
+ ", opens subtitles settings dialog": ", otvorí okno nastavení titulkov",
+ ", opens descriptions settings dialog": ", otvorí okno nastavení opisov",
+ ", selected": ", označené",
+ "captions settings": "nastavenia popiskov",
+ "subtitles settings": "nastavenia titulkov",
+ "descriptions settings": "nastavenia opisov",
+ "Text": "Text",
+ "White": "Biela",
+ "Black": "Čierna",
+ "Red": "Červená",
+ "Green": "Zelená",
+ "Blue": "Modrá",
+ "Yellow": "Žltá",
+ "Magenta": "Ružová",
+ "Cyan": "Tyrkysová",
+ "Background": "Pozadie",
+ "Window": "Okno",
+ "Transparent": "Priesvitné",
+ "Semi-Transparent": "Polopriesvitné",
+ "Opaque": "Plné",
+ "Font Size": "Veľkosť písma",
+ "Text Edge Style": "Typ okrajov písma",
+ "None": "Žiadne",
+ "Raised": "Zvýšené",
+ "Depressed": "Znížené",
+ "Uniform": "Pravidelné",
+ "Dropshadow": "S tieňom",
+ "Font Family": "Typ písma",
+ "Proportional Sans-Serif": "Proporčné bezpätkové",
+ "Monospace Sans-Serif": "Pravidelné, bezpätkové",
+ "Proportional Serif": "Proporčné pätkové",
+ "Monospace Serif": "Pravidelné pätkové",
+ "Casual": "Bežné",
+ "Script": "Písané",
+ "Small Caps": "Malé kapitálky",
+ "Reset": "Resetovať",
+ "restore all settings to the default values": "všetky nastavenia na základné hodnoty",
+ "Done": "Hotovo",
+ "Caption Settings Dialog": "Okno nastavení popiskov",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Začiatok okna. Klávesa Escape zruší a zavrie okno.",
+ "End of dialog window.": "Koniec okna.",
+ "{1} is loading.": "{1} sa načíta."
+}
--- /dev/null
+videojs.addLanguage('sl', {
+ "Audio Player": "Avdio predvajalnik",
+ "Video Player": "Video predvajalnik",
+ "Play": "Predvajaj",
+ "Pause": "Začasno ustavi",
+ "Replay": "Predvajaj ponovno",
+ "Current Time": "Trenutni čas",
+ "Duration": "Trajanje",
+ "Remaining Time": "Preostali čas",
+ "Stream Type": "Vrsta podatkovnega toka",
+ "LIVE": "V ŽIVO",
+ "Seek to live, currently behind live": "Spremljaj v živo (trenutno v zaostanku)",
+ "Seek to live, currently playing live": "Spremljaj v živo (trenutno v živo)",
+ "Loaded": "Naloženo",
+ "Progress": "Napredek",
+ "Progress Bar": "Vrstica napredka",
+ "progress bar timing: currentTime={1} duration={2}": "{1} od {2}",
+ "Fullscreen": "Celozaslonski prikaz",
+ "Non-Fullscreen": "Prikaz na delu zaslona",
+ "Mute": "Izključi zvok",
+ "Unmute": "Vključi zvok",
+ "Playback Rate": "Hitrost predvajanja",
+ "Subtitles": "Podnapisi",
+ "subtitles off": "podnapisi izklopljeni",
+ "Captions": "Zvočni zapis",
+ "captions off": "zvočni zapis izklopljen",
+ "Chapters": "Poglavja",
+ "Descriptions": "Opisi",
+ "descriptions off": "opisi izklopljeni",
+ "Audio Track": "Zvočni posnetek",
+ "Volume Level": "Raven glasnosti",
+ "You aborted the media playback": "Prekinili ste predvajanje.",
+ "A network error caused the media download to fail part-way.": "Prenos multimedijske datoteke ni uspel zaradi napake v omrežju.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Multimedijske datoteke ni bilo mogoče naložiti zaradi napake na strežniku oziroma omrežju ali ker ta oblika ni podprta.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Predvajanje datoteke je bilo prekinjeno zaradi napak v datoteki ali ker uporablja funkcije, ki jih brskalnik ne podpira.",
+ "No compatible source was found for this media.": "Za to datoteko ni bil najden noben združljiv vir.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Datoteka je šifrirana in predvajalnik nima ključev za njeno dešifriranje.",
+ "Play Video": "Predvajaj",
+ "Close": "Zapri",
+ "Close Modal Dialog": "Zapri modalno okno",
+ "Modal Window": "Modalno okno",
+ "This is a modal window": "To je modalno okno",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "To okno lahko zaprete s pritiskom na tipko Escape ali z aktiviranjem gumba za zapiranje.",
+ ", opens captions settings dialog": ", odpre nastavitve za zvočni zapis",
+ ", opens subtitles settings dialog": ", odpre nastavitve za podnapise",
+ ", opens descriptions settings dialog": ", odpre nastavitve za opis",
+ ", selected": ", izbrano",
+ "captions settings": "nastavitve zvočnega zapisa",
+ "subtitles settings": "nastavitve podnapisov",
+ "descriptions settings": "nastavitve opisa",
+ "Text": "Tekst",
+ "White": "Bela",
+ "Black": "Črna",
+ "Red": "Rdeča",
+ "Green": "Zelena",
+ "Blue": "Modra",
+ "Yellow": "Rumena",
+ "Magenta": "Magenta",
+ "Cyan": "Cian",
+ "Background": "Ozadje",
+ "Window": "Okno",
+ "Transparent": "Prozorno",
+ "Semi-Transparent": "Delno prozorno",
+ "Opaque": "Neprozorno",
+ "Font Size": "Velikost pisave",
+ "Text Edge Style": "Slog roba besedila",
+ "None": "Brez",
+ "Raised": "Dvignjeno",
+ "Depressed": "Vtisnjeno",
+ "Uniform": "Enakomerno",
+ "Dropshadow": "S senco",
+ "Font Family": "Družina pisave",
+ "Small Caps": "Male črke",
+ "Reset": "Ponastavi",
+ "restore all settings to the default values": "obnovi vse nastavitve na privzete vrednosti",
+ "Done": "Končano",
+ "Caption Settings Dialog": "Pogovorno okno za nastavitve zvočnega zapisa",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Začetek pogovornega okna. Escape bo preklical in zaprl okno.",
+ "End of dialog window.": "Konec pogovornega okna.",
+ "{1} is loading.": "{1} se nalaga.",
+ "Exit Picture-in-Picture": "Izhod iz slike v sliki",
+ "Picture-in-Picture": "Slika v sliki"
+});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Avdio predvajalnik",
+ "Video Player": "Video predvajalnik",
+ "Play": "Predvajaj",
+ "Pause": "Začasno ustavi",
+ "Replay": "Predvajaj ponovno",
+ "Current Time": "Trenutni čas",
+ "Duration": "Trajanje",
+ "Remaining Time": "Preostali čas",
+ "Stream Type": "Vrsta podatkovnega toka",
+ "LIVE": "V ŽIVO",
+ "Seek to live, currently behind live": "Spremljaj v živo (trenutno v zaostanku)",
+ "Seek to live, currently playing live": "Spremljaj v živo (trenutno v živo)",
+ "Loaded": "Naloženo",
+ "Progress": "Napredek",
+ "Progress Bar": "Vrstica napredka",
+ "progress bar timing: currentTime={1} duration={2}": "{1} od {2}",
+ "Fullscreen": "Celozaslonski prikaz",
+ "Non-Fullscreen": "Prikaz na delu zaslona",
+ "Mute": "Izključi zvok",
+ "Unmute": "Vključi zvok",
+ "Playback Rate": "Hitrost predvajanja",
+ "Subtitles": "Podnapisi",
+ "subtitles off": "podnapisi izklopljeni",
+ "Captions": "Zvočni zapis",
+ "captions off": "zvočni zapis izklopljen",
+ "Chapters": "Poglavja",
+ "Descriptions": "Opisi",
+ "descriptions off": "opisi izklopljeni",
+ "Audio Track": "Zvočni posnetek",
+ "Volume Level": "Raven glasnosti",
+ "You aborted the media playback": "Prekinili ste predvajanje.",
+ "A network error caused the media download to fail part-way.": "Prenos multimedijske datoteke ni uspel zaradi napake v omrežju.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Multimedijske datoteke ni bilo mogoče naložiti zaradi napake na strežniku oziroma omrežju ali ker ta oblika ni podprta.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Predvajanje datoteke je bilo prekinjeno zaradi napak v datoteki ali ker uporablja funkcije, ki jih brskalnik ne podpira.",
+ "No compatible source was found for this media.": "Za to datoteko ni bil najden noben združljiv vir.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Datoteka je šifrirana in predvajalnik nima ključev za njeno dešifriranje.",
+ "Play Video": "Predvajaj",
+ "Close": "Zapri",
+ "Close Modal Dialog": "Zapri modalno okno",
+ "Modal Window": "Modalno okno",
+ "This is a modal window": "To je modalno okno",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "To okno lahko zaprete s pritiskom na tipko Escape ali z aktiviranjem gumba za zapiranje.",
+ ", opens captions settings dialog": ", odpre nastavitve za zvočni zapis",
+ ", opens subtitles settings dialog": ", odpre nastavitve za podnapise",
+ ", opens descriptions settings dialog": ", odpre nastavitve za opis",
+ ", selected": ", izbrano",
+ "captions settings": "nastavitve zvočnega zapisa",
+ "subtitles settings": "nastavitve podnapisov",
+ "descriptions settings": "nastavitve opisa",
+ "Text": "Tekst",
+ "White": "Bela",
+ "Black": "Črna",
+ "Red": "Rdeča",
+ "Green": "Zelena",
+ "Blue": "Modra",
+ "Yellow": "Rumena",
+ "Magenta": "Magenta",
+ "Cyan": "Cian",
+ "Background": "Ozadje",
+ "Window": "Okno",
+ "Transparent": "Prozorno",
+ "Semi-Transparent": "Delno prozorno",
+ "Opaque": "Neprozorno",
+ "Font Size": "Velikost pisave",
+ "Text Edge Style": "Slog roba besedila",
+ "None": "Brez",
+ "Raised": "Dvignjeno",
+ "Depressed": "Vtisnjeno",
+ "Uniform": "Enakomerno",
+ "Dropshadow": "S senco",
+ "Font Family": "Družina pisave",
+ "Small Caps": "Male črke",
+ "Reset": "Ponastavi",
+ "restore all settings to the default values": "obnovi vse nastavitve na privzete vrednosti",
+ "Done": "Končano",
+ "Caption Settings Dialog": "Pogovorno okno za nastavitve zvočnega zapisa",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Začetek pogovornega okna. Escape bo preklical in zaprl okno.",
+ "End of dialog window.": "Konec pogovornega okna.",
+ "{1} is loading.": "{1} se nalaga.",
+ "Exit Picture-in-Picture": "Izhod iz slike v sliki",
+ "Picture-in-Picture": "Slika v sliki"
+}
-videojs.addLanguage("sr",{
- "Play": "Pusti",
- "Pause": "Pauza",
- "Current Time": "Trenutno vrijeme",
- "Duration Time": "Vrijeme trajanja",
- "Remaining Time": "Preostalo vrijeme",
- "Stream Type": "Način strimovanja",
- "LIVE": "UŽIVO",
- "Loaded": "Učitan",
- "Progress": "Progres",
- "Fullscreen": "Puni ekran",
- "Non-Fullscreen": "Mali ekran",
- "Mute": "Prigušen",
- "Unmute": "Ne-prigušen",
- "Playback Rate": "Stopa reprodukcije",
- "Subtitles": "Podnaslov",
- "subtitles off": "Podnaslov deaktiviran",
- "Captions": "Titlovi",
- "captions off": "Titlovi deaktivirani",
- "Chapters": "Poglavlja",
- "You aborted the media playback": "Isključili ste reprodukciju videa.",
- "A network error caused the media download to fail part-way.": "Video se prestao preuzimati zbog greške na mreži.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video se ne može reproducirati zbog servera, greške u mreži ili je format ne podržan.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Reprodukcija videa je zaustavljenja zbog greške u formatu ili zbog verzije vašeg pretraživača.",
- "No compatible source was found for this media.": "Nije nađen nijedan kompatibilan izvor ovog videa."
+videojs.addLanguage('sr', {
+ "Play": "Pusti",
+ "Pause": "Pauza",
+ "Current Time": "Trenutno vreme",
+ "Duration": "Vreme trajanja",
+ "Remaining Time": "Preostalo vreme",
+ "Stream Type": "Način strimovanja",
+ "LIVE": "UŽIVO",
+ "Loaded": "Učitan",
+ "Progress": "Progres",
+ "Fullscreen": "Pun ekran",
+ "Non-Fullscreen": "Mali ekran",
+ "Mute": "Prigušen",
+ "Unmute": "Ne-prigušen",
+ "Playback Rate": "Stopa reprodukcije",
+ "Subtitles": "Podnaslov",
+ "subtitles off": "Podnaslov deaktiviran",
+ "Captions": "Titlovi",
+ "captions off": "Titlovi deaktivirani",
+ "Chapters": "Poglavlja",
+ "You aborted the media playback": "Isključili ste reprodukciju videa.",
+ "A network error caused the media download to fail part-way.": "Video se prestao preuzimati zbog greške na mreži.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video se ne može reproducirati zbog servera, greške u mreži ili format nije podržan.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Reprodukcija videa je zaustavljenja zbog greške u formatu ili zbog verzije vašeg pretraživača.",
+ "No compatible source was found for this media.": "Nije nađen nijedan kompatibilan izvor ovog videa."
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Pusti",
+ "Pause": "Pauza",
+ "Current Time": "Trenutno vreme",
+ "Duration": "Vreme trajanja",
+ "Remaining Time": "Preostalo vreme",
+ "Stream Type": "Način strimovanja",
+ "LIVE": "UŽIVO",
+ "Loaded": "Učitan",
+ "Progress": "Progres",
+ "Fullscreen": "Pun ekran",
+ "Non-Fullscreen": "Mali ekran",
+ "Mute": "Prigušen",
+ "Unmute": "Ne-prigušen",
+ "Playback Rate": "Stopa reprodukcije",
+ "Subtitles": "Podnaslov",
+ "subtitles off": "Podnaslov deaktiviran",
+ "Captions": "Titlovi",
+ "captions off": "Titlovi deaktivirani",
+ "Chapters": "Poglavlja",
+ "You aborted the media playback": "Isključili ste reprodukciju videa.",
+ "A network error caused the media download to fail part-way.": "Video se prestao preuzimati zbog greške na mreži.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video se ne može reproducirati zbog servera, greške u mreži ili format nije podržan.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Reprodukcija videa je zaustavljenja zbog greške u formatu ili zbog verzije vašeg pretraživača.",
+ "No compatible source was found for this media.": "Nije nađen nijedan kompatibilan izvor ovog videa."
+}
-videojs.addLanguage("sv",{
- "Play": "Spela",
- "Pause": "Pausa",
- "Current Time": "Aktuell tid",
- "Duration Time": "Total tid",
- "Remaining Time": "Återstående tid",
- "Stream Type": "Strömningstyp",
- "LIVE": "LIVE",
- "Loaded": "Laddad",
- "Progress": "Förlopp",
- "Fullscreen": "Fullskärm",
- "Non-Fullscreen": "Ej fullskärm",
- "Mute": "Ljud av",
- "Unmute": "Ljud på",
- "Playback Rate": "Uppspelningshastighet",
- "Subtitles": "Text på",
- "subtitles off": "Text av",
- "Captions": "Text på",
- "captions off": "Text av",
- "Chapters": "Kapitel",
- "You aborted the media playback": "Du har avbrutit videouppspelningen.",
- "A network error caused the media download to fail part-way.": "Ett nätverksfel gjorde att nedladdningen av videon avbröts.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Det gick inte att ladda videon, antingen på grund av ett server- eller nätverksfel, eller för att formatet inte stöds.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Uppspelningen avbröts på grund av att videon är skadad, eller också för att videon använder funktioner som din webbläsare inte stöder.",
- "No compatible source was found for this media.": "Det gick inte att hitta någon kompatibel källa för den här videon."
+videojs.addLanguage('sv', {
+ ", opens captions settings dialog": ", öppnar dialogruta för textning",
+ ", opens descriptions settings dialog": ", öppnar dialogruta för inställningar",
+ ", opens subtitles settings dialog": ", öppnar dialogruta för undertexter",
+ ", selected": ", vald",
+ "A network error caused the media download to fail part-way.": "Ett nätverksfel gjorde att nedladdningen av videon avbröts.",
+ "Audio Player": "Ljudspelare",
+ "Audio Track": "Ljudspår",
+ "Background": "Bakgrund",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Början av dialogfönster. Escape avbryter och stänger fönstret.",
+ "Black": "Svart",
+ "Blue": "Blå",
+ "Caption Settings Dialog": "Dialogruta för textningsinställningar",
+ "Captions": "Text på",
+ "Casual": "Casual",
+ "Chapters": "Kapitel",
+ "Close": "Stäng",
+ "Close Modal Dialog": "Stäng dialogruta",
+ "Current Time": "Aktuell tid",
+ "Cyan": "Cyan",
+ "Depressed": "Deprimerad",
+ "Descriptions": "Beskrivningar",
+ "Done": "Klar",
+ "Dropshadow": "DropSkugga",
+ "Duration": "Total tid",
+ "End of dialog window.": "Slutet av dialogfönster.",
+ "Font Family": "Typsnittsfamilj",
+ "Font Size": "Textstorlek",
+ "Fullscreen": "Fullskärm",
+ "Green": "Grön",
+ "LIVE": "LIVE",
+ "Loaded": "Laddad",
+ "Magenta": "Magenta",
+ "Modal Window": "dialogruta",
+ "Monospace Sans-Serif": "Monospace Sans-Serif",
+ "Monospace Serif": "Monospace Serif",
+ "Mute": "Ljud av",
+ "No compatible source was found for this media.": "Det gick inte att hitta någon kompatibel källa för den här videon.",
+ "Non-Fullscreen": "Ej fullskärm",
+ "None": "Ingen",
+ "Opaque": "Opak",
+ "Pause": "Pausa",
+ "Play": "Spela",
+ "Play Video": "Spela upp video",
+ "Playback Rate": "Uppspelningshastighet",
+ "Progress": "Förlopp",
+ "Progress Bar": "förloppsmätare",
+ "Proportional Sans-Serif": "Proportionell Sans-Serif",
+ "Proportional Serif": "Proportionell Serif",
+ "Raised": "Raised",
+ "Red": "Röd",
+ "Remaining Time": "Återstående tid",
+ "Replay": "Spela upp igen",
+ "Reset": "Återställ",
+ "Script": "Manus",
+ "Seek to live, currently behind live": "Återgå till live, uppspelningen är inte live",
+ "Seek to live, currently playing live": "Återgå till live, uppspelningen är live",
+ "Semi-Transparent": "Semi-transparent",
+ "Small Caps": "Small-Caps",
+ "Stream Type": "Strömningstyp",
+ "Subtitles": "Text på",
+ "Text": "Text",
+ "Text Edge Style": "Textkantstil",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Det gick inte att ladda videon, antingen på grund av ett server- eller nätverksfel, eller för att formatet inte stöds.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Mediat är krypterat och vi har inte nycklarna för att dekryptera det.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Uppspelningen avbröts på grund av att videon är skadad, eller också för att videon använder funktioner som din webbläsare inte stöder.",
+ "This is a modal window": "Det här är ett dialogruta",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Den här dialogrutan kan stängas genom att trycka på Escape-tangenten eller stäng knappen.",
+ "Transparent": "Transparent",
+ "Uniform": "Uniform",
+ "Unmute": "Ljud på",
+ "Video Player": "Videospelare",
+ "Volume Level": "Volymnivå",
+ "White": "Vit",
+ "Window": "Fönster",
+ "Yellow": "Gul",
+ "You aborted the media playback": "Du har avbrutit videouppspelningen.",
+ "captions off": "Text av",
+ "captions settings": "textningsinställningar",
+ "descriptions off": "beskrivningar av",
+ "descriptions settings": "beskrivningsinställningar",
+ "progress bar timing: currentTime={1} duration={2}": "{1} av {2}",
+ "restore all settings to the default values": "återställ alla inställningar till standardvärden",
+ "subtitles off": "Text av",
+ "subtitles settings": "undertextsinställningar",
+ "{1} is loading.": "{1} laddar."
});
\ No newline at end of file
--- /dev/null
+{
+ ", opens captions settings dialog": ", öppnar dialogruta för textning",
+ ", opens descriptions settings dialog": ", öppnar dialogruta för inställningar",
+ ", opens subtitles settings dialog": ", öppnar dialogruta för undertexter",
+ ", selected": ", vald",
+ "A network error caused the media download to fail part-way.": "Ett nätverksfel gjorde att nedladdningen av videon avbröts.",
+ "Audio Player": "Ljudspelare",
+ "Audio Track": "Ljudspår",
+ "Background": "Bakgrund",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Början av dialogfönster. Escape avbryter och stänger fönstret.",
+ "Black": "Svart",
+ "Blue": "Blå",
+ "Caption Settings Dialog": "Dialogruta för textningsinställningar",
+ "Captions": "Text på",
+ "Casual": "Casual",
+ "Chapters": "Kapitel",
+ "Close": "Stäng",
+ "Close Modal Dialog": "Stäng dialogruta",
+ "Current Time": "Aktuell tid",
+ "Cyan": "Cyan",
+ "Depressed": "Deprimerad",
+ "Descriptions": "Beskrivningar",
+ "Done": "Klar",
+ "Dropshadow": "DropSkugga",
+ "Duration": "Total tid",
+ "End of dialog window.": "Slutet av dialogfönster.",
+ "Font Family": "Typsnittsfamilj",
+ "Font Size": "Textstorlek",
+ "Fullscreen": "Fullskärm",
+ "Green": "Grön",
+ "LIVE": "LIVE",
+ "Loaded": "Laddad",
+ "Magenta": "Magenta",
+ "Modal Window": "dialogruta",
+ "Monospace Sans-Serif": "Monospace Sans-Serif",
+ "Monospace Serif": "Monospace Serif",
+ "Mute": "Ljud av",
+ "No compatible source was found for this media.": "Det gick inte att hitta någon kompatibel källa för den här videon.",
+ "Non-Fullscreen": "Ej fullskärm",
+ "None": "Ingen",
+ "Opaque": "Opak",
+ "Pause": "Pausa",
+ "Play": "Spela",
+ "Play Video": "Spela upp video",
+ "Playback Rate": "Uppspelningshastighet",
+ "Progress": "Förlopp",
+ "Progress Bar": "förloppsmätare",
+ "Proportional Sans-Serif": "Proportionell Sans-Serif",
+ "Proportional Serif": "Proportionell Serif",
+ "Raised": "Raised",
+ "Red": "Röd",
+ "Remaining Time": "Återstående tid",
+ "Replay": "Spela upp igen",
+ "Reset": "Återställ",
+ "Script": "Manus",
+ "Seek to live, currently behind live": "Återgå till live, uppspelningen är inte live",
+ "Seek to live, currently playing live": "Återgå till live, uppspelningen är live",
+ "Semi-Transparent": "Semi-transparent",
+ "Small Caps": "Small-Caps",
+ "Stream Type": "Strömningstyp",
+ "Subtitles": "Text på",
+ "Text": "Text",
+ "Text Edge Style": "Textkantstil",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Det gick inte att ladda videon, antingen på grund av ett server- eller nätverksfel, eller för att formatet inte stöds.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Mediat är krypterat och vi har inte nycklarna för att dekryptera det.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Uppspelningen avbröts på grund av att videon är skadad, eller också för att videon använder funktioner som din webbläsare inte stöder.",
+ "This is a modal window": "Det här är ett dialogruta",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Den här dialogrutan kan stängas genom att trycka på Escape-tangenten eller stäng knappen.",
+ "Transparent": "Transparent",
+ "Uniform": "Uniform",
+ "Unmute": "Ljud på",
+ "Video Player": "Videospelare",
+ "Volume Level": "Volymnivå",
+ "White": "Vit",
+ "Window": "Fönster",
+ "Yellow": "Gul",
+ "You aborted the media playback": "Du har avbrutit videouppspelningen.",
+ "captions off": "Text av",
+ "captions settings": "textningsinställningar",
+ "descriptions off": "beskrivningar av",
+ "descriptions settings": "beskrivningsinställningar",
+ "progress bar timing: currentTime={1} duration={2}": "{1} av {2}",
+ "restore all settings to the default values": "återställ alla inställningar till standardvärden",
+ "subtitles off": "Text av",
+ "subtitles settings": "undertextsinställningar",
+ "{1} is loading.": "{1} laddar."
+}
--- /dev/null
+videojs.addLanguage('th', {
+ "Audio Player": "โปรแกรมเล่นเสียง",
+ "Video Player": "โปรแกรมเล่นวิดีโอ",
+ "Play": "เล่น",
+ "Pause": "หยุดชั่วคราว",
+ "Replay": "เล่นซ้ำ",
+ "Current Time": "เวลาปัจจุบัน",
+ "Duration": "ระยะเวลา",
+ "Remaining Time": "เวลาที่เหลือ",
+ "Stream Type": "ประเภทของสตรีม",
+ "LIVE": "ถ่ายทอดสด",
+ "Seek to live, currently behind live": "หาโอกาสที่จะถ่ายทอดสด กำลังอยู่เบื้องหลังการถ่ายทอดสดในขณะนี้",
+ "Seek to live, currently playing live": "หาโอกาสที่จะถ่ายทอดสด กำลังเล่นแบบสดในขณะนี้",
+ "Loaded": "โหลดแล้ว",
+ "Progress": "ความคืบหน้า",
+ "Progress Bar": "แถบแสดงความคืบหน้า",
+ "progress bar timing: currentTime={1} duration={2}": "{1} ของ {2}",
+ "Fullscreen": "แบบเต็มหน้าจอ",
+ "Non-Fullscreen": "ไม่ใช่แบบเต็มหน้าจอ",
+ "Mute": "ปิดเสียง",
+ "Unmute": "ยกเลิกการปิดเสียง",
+ "Playback Rate": "อัตราการเล่น",
+ "Subtitles": "คำบรรยาย",
+ "subtitles off": "ปิดคำบรรยาย",
+ "Captions": "คำอธิบายภาพ",
+ "captions off": "ปิดคำอธิบายภาพ",
+ "Chapters": "บท",
+ "Descriptions": "คำอธิบาย",
+ "descriptions off": "ปิดคำอธิบาย",
+ "Audio Track": "แทร็กเสียง",
+ "Volume Level": "ระดับเสียง",
+ "You aborted the media playback": "คุณยกเลิกการเล่นสื่อแล้ว",
+ "A network error caused the media download to fail part-way.": "ข้อผิดพลาดของเครือข่ายทำให้การดาวน์โหลดสื่อไม่สำเร็จเป็นบางส่วน",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "ไม่สามารถโหลดสื่อได้ โดยอาจเป็นเพราะเซิร์ฟเวอร์หรือเครือข่ายล้มเหลว หรือเพราะรูปแบบไม่ได้รับการรองรับ",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "การเล่นสื่อถูกยกเลิกเนื่องจากปัญหาเกี่ยวกับความเสียหาย หรือเนื่องจากสื่อใช้ฟีเจอร์ที่เบราว์เซอร์ของคุณไม่รองรับ",
+ "No compatible source was found for this media.": "ไม่พบแหล่งที่เข้ากันได้สำหรับสื่อนี้",
+ "The media is encrypted and we do not have the keys to decrypt it.": "สื่อถูกเข้ารหัสลับแล้ว และเราไม่มีคีย์ที่จะถอดรหัสลับดังกล่าว",
+ "Play Video": "เล่นวิดีโอ",
+ "Close": "ปิด",
+ "Close Modal Dialog": "ปิดกล่องโต้ตอบโมดอล",
+ "Modal Window": "หน้าต่างโมดอล",
+ "This is a modal window": "รายการนี้เป็นหน้าต่างโมดอล",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "คุณสามารถปิดโมดอลนี้โดยกดปุ่ม Escape หรือเปิดใช้งานปุ่มปิด",
+ ", opens captions settings dialog": ", เปิดกล่องโต้ตอบการตั้งค่าคำอธิบายภาพ",
+ ", opens subtitles settings dialog": ", เปิดกล่องโต้ตอบการตั้งค่าคำบรรยาย",
+ ", opens descriptions settings dialog": ", เปิดกล่องโต้ตอบการตั้งค่าคำอธิบาย",
+ ", selected": ", เลือกแล้ว",
+ "captions settings": "การตั้งค่าคำอธิบายภาพ",
+ "subtitles settings": "การตั้งค่าคำบรรยาย",
+ "descriptions settings": "การตั้งค่าคำอธิบาย",
+ "Text": "ข้อความ",
+ "White": "สีขาว",
+ "Black": "สีดำ",
+ "Red": "สีแดง",
+ "Green": "สีเขียว",
+ "Blue": "สีน้ำเงิน",
+ "Yellow": "สีเหลือง",
+ "Magenta": "สีม่วงแดง",
+ "Cyan": "สีน้ำเงินอมเขียว",
+ "Background": "พื้นหลัง",
+ "Window": "หน้าต่าง",
+ "Transparent": "โปร่งใส",
+ "Semi-Transparent": "กึ่งโปร่งใส",
+ "Opaque": "ทึบ",
+ "Font Size": "ขนาดแบบอักษร",
+ "Text Edge Style": "ลักษณะขอบข้อความ",
+ "None": "ไม่มี",
+ "Raised": "ยกขึ้น",
+ "Depressed": "ปล่อยออก",
+ "Uniform": "รูปแบบ",
+ "Dropshadow": "เพิ่มเงา",
+ "Font Family": "ตระกูลแบบอักษร",
+ "Proportional Sans-Serif": "Sans-Serif ตามสัดส่วน",
+ "Monospace Sans-Serif": "Sans-Serif ช่องว่างเดี่ยว",
+ "Proportional Serif": "Serif ตามสัดส่วน",
+ "Monospace Serif": "Serif ช่องว่างเดี่ยว",
+ "Casual": "ไม่เป็นทางการ",
+ "Script": "สคริปต์",
+ "Small Caps": "ตัวพิมพ์ใหญ่ขนาดเล็ก",
+ "Reset": "รีเซ็ต",
+ "restore all settings to the default values": "คืนค่าการตั้งค่าท้้งหมดให้เป็นค่าเริ่มต้น",
+ "Done": "เสร็จสิ้น",
+ "Caption Settings Dialog": "กล่องโต้ตอบการตั้งค่าคำอธิบายภาพ",
+ "Beginning of dialog window. Escape will cancel and close the window.": "การเริ่มต้นหน้าต่างกล่องโต้ตอบ Escape จะยกเลิกและปิดหน้าต่าง",
+ "End of dialog window.": "สิ้นสุดหน้าต่างกล่องโต้ตอบ",
+ "{1} is loading.": "กำลังโหลด {1}",
+ "Exit Picture-in-Picture": "ออกจากการเล่นภาพควบคู่",
+ "Picture-in-Picture": "การเล่นภาพควบคู่"
+});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "โปรแกรมเล่นเสียง",
+ "Video Player": "โปรแกรมเล่นวิดีโอ",
+ "Play": "เล่น",
+ "Pause": "หยุดชั่วคราว",
+ "Replay": "เล่นซ้ำ",
+ "Current Time": "เวลาปัจจุบัน",
+ "Duration": "ระยะเวลา",
+ "Remaining Time": "เวลาที่เหลือ",
+ "Stream Type": "ประเภทของสตรีม",
+ "LIVE": "ถ่ายทอดสด",
+ "Seek to live, currently behind live": "หาโอกาสที่จะถ่ายทอดสด กำลังอยู่เบื้องหลังการถ่ายทอดสดในขณะนี้",
+ "Seek to live, currently playing live": "หาโอกาสที่จะถ่ายทอดสด กำลังเล่นแบบสดในขณะนี้",
+ "Loaded": "โหลดแล้ว",
+ "Progress": "ความคืบหน้า",
+ "Progress Bar": "แถบแสดงความคืบหน้า",
+ "progress bar timing: currentTime={1} duration={2}": "{1} ของ {2}",
+ "Fullscreen": "แบบเต็มหน้าจอ",
+ "Non-Fullscreen": "ไม่ใช่แบบเต็มหน้าจอ",
+ "Mute": "ปิดเสียง",
+ "Unmute": "ยกเลิกการปิดเสียง",
+ "Playback Rate": "อัตราการเล่น",
+ "Subtitles": "คำบรรยาย",
+ "subtitles off": "ปิดคำบรรยาย",
+ "Captions": "คำอธิบายภาพ",
+ "captions off": "ปิดคำอธิบายภาพ",
+ "Chapters": "บท",
+ "Descriptions": "คำอธิบาย",
+ "descriptions off": "ปิดคำอธิบาย",
+ "Audio Track": "แทร็กเสียง",
+ "Volume Level": "ระดับเสียง",
+ "You aborted the media playback": "คุณยกเลิกการเล่นสื่อแล้ว",
+ "A network error caused the media download to fail part-way.": "ข้อผิดพลาดของเครือข่ายทำให้การดาวน์โหลดสื่อไม่สำเร็จเป็นบางส่วน",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "ไม่สามารถโหลดสื่อได้ โดยอาจเป็นเพราะเซิร์ฟเวอร์หรือเครือข่ายล้มเหลว หรือเพราะรูปแบบไม่ได้รับการรองรับ",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "การเล่นสื่อถูกยกเลิกเนื่องจากปัญหาเกี่ยวกับความเสียหาย หรือเนื่องจากสื่อใช้ฟีเจอร์ที่เบราว์เซอร์ของคุณไม่รองรับ",
+ "No compatible source was found for this media.": "ไม่พบแหล่งที่เข้ากันได้สำหรับสื่อนี้",
+ "The media is encrypted and we do not have the keys to decrypt it.": "สื่อถูกเข้ารหัสลับแล้ว และเราไม่มีคีย์ที่จะถอดรหัสลับดังกล่าว",
+ "Play Video": "เล่นวิดีโอ",
+ "Close": "ปิด",
+ "Close Modal Dialog": "ปิดกล่องโต้ตอบโมดอล",
+ "Modal Window": "หน้าต่างโมดอล",
+ "This is a modal window": "รายการนี้เป็นหน้าต่างโมดอล",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "คุณสามารถปิดโมดอลนี้โดยกดปุ่ม Escape หรือเปิดใช้งานปุ่มปิด",
+ ", opens captions settings dialog": ", เปิดกล่องโต้ตอบการตั้งค่าคำอธิบายภาพ",
+ ", opens subtitles settings dialog": ", เปิดกล่องโต้ตอบการตั้งค่าคำบรรยาย",
+ ", opens descriptions settings dialog": ", เปิดกล่องโต้ตอบการตั้งค่าคำอธิบาย",
+ ", selected": ", เลือกแล้ว",
+ "captions settings": "การตั้งค่าคำอธิบายภาพ",
+ "subtitles settings": "การตั้งค่าคำบรรยาย",
+ "descriptions settings": "การตั้งค่าคำอธิบาย",
+ "Text": "ข้อความ",
+ "White": "สีขาว",
+ "Black": "สีดำ",
+ "Red": "สีแดง",
+ "Green": "สีเขียว",
+ "Blue": "สีน้ำเงิน",
+ "Yellow": "สีเหลือง",
+ "Magenta": "สีม่วงแดง",
+ "Cyan": "สีน้ำเงินอมเขียว",
+ "Background": "พื้นหลัง",
+ "Window": "หน้าต่าง",
+ "Transparent": "โปร่งใส",
+ "Semi-Transparent": "กึ่งโปร่งใส",
+ "Opaque": "ทึบ",
+ "Font Size": "ขนาดแบบอักษร",
+ "Text Edge Style": "ลักษณะขอบข้อความ",
+ "None": "ไม่มี",
+ "Raised": "ยกขึ้น",
+ "Depressed": "ปล่อยออก",
+ "Uniform": "รูปแบบ",
+ "Dropshadow": "เพิ่มเงา",
+ "Font Family": "ตระกูลแบบอักษร",
+ "Proportional Sans-Serif": "Sans-Serif ตามสัดส่วน",
+ "Monospace Sans-Serif": "Sans-Serif ช่องว่างเดี่ยว",
+ "Proportional Serif": "Serif ตามสัดส่วน",
+ "Monospace Serif": "Serif ช่องว่างเดี่ยว",
+ "Casual": "ไม่เป็นทางการ",
+ "Script": "สคริปต์",
+ "Small Caps": "ตัวพิมพ์ใหญ่ขนาดเล็ก",
+ "Reset": "รีเซ็ต",
+ "restore all settings to the default values": "คืนค่าการตั้งค่าท้้งหมดให้เป็นค่าเริ่มต้น",
+ "Done": "เสร็จสิ้น",
+ "Caption Settings Dialog": "กล่องโต้ตอบการตั้งค่าคำอธิบายภาพ",
+ "Beginning of dialog window. Escape will cancel and close the window.": "การเริ่มต้นหน้าต่างกล่องโต้ตอบ Escape จะยกเลิกและปิดหน้าต่าง",
+ "End of dialog window.": "สิ้นสุดหน้าต่างกล่องโต้ตอบ",
+ "{1} is loading.": "กำลังโหลด {1}",
+ "Exit Picture-in-Picture": "ออกจากการเล่นภาพควบคู่",
+ "Picture-in-Picture": "การเล่นภาพควบคู่"
+}
\ No newline at end of file
-videojs.addLanguage("tr",{
- "Play": "Oynat",
- "Pause": "Duraklat",
- "Replay": "Yeniden Oynat",
- "Current Time": "Süre",
- "Duration Time": "Toplam Süre",
- "Remaining Time": "Kalan Süre",
- "Stream Type": "Yayın Tipi",
- "LIVE": "CANLI",
- "Loaded": "Yüklendi",
- "Progress": "Yükleniyor",
- "Fullscreen": "Tam Ekran",
- "Non-Fullscreen": "Küçük Ekran",
- "Mute": "Ses Kapa",
- "Unmute": "Ses Aç",
- "Playback Rate": "Oynatma Hızı",
- "Subtitles": "Altyazı",
- "subtitles off": "Altyazı Kapalı",
- "Captions": "Altyazı",
- "captions off": "Altyazı Kapalı",
- "Chapters": "Bölümler",
- "Close Modal Dialog": "Dialogu Kapat",
- "Descriptions": "Açıklamalar",
- "descriptions off": "Açıklamalar kapalı",
- "Audio Track": "Ses Dosyası",
- "You aborted the media playback": "Video oynatmayı iptal ettiniz",
- "A network error caused the media download to fail part-way.": "Video indirilirken bağlantı sorunu oluştu.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video oynatılamadı, ağ ya da sunucu hatası veya belirtilen format desteklenmiyor.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Tarayıcınız desteklemediği için videoda hata oluştu.",
- "No compatible source was found for this media.": "Video için kaynak bulunamadı.",
- "The media is encrypted and we do not have the keys to decrypt it.": "Video, şifrelenmiş bir kaynaktan geliyor ve oynatmak için gerekli anahtar bulunamadı.",
- "Play Video": "Videoyu Oynat",
- "Close": "Kapat",
- "Modal Window": "Modal Penceresi",
- "This is a modal window": "Bu bir modal penceresidir",
- "This modal can be closed by pressing the Escape key or activating the close button.": "Bu modal ESC tuşuna basarak ya da kapata tıklanarak kapatılabilir.",
- ", opens captions settings dialog": ", altyazı ayarları menüsünü açar",
- ", opens subtitles settings dialog": ", altyazı ayarları menüsünü açar",
- ", opens descriptions settings dialog": ", açıklama ayarları menüsünü açar",
- ", selected": ", seçildi",
- "captions settings": "altyazı ayarları",
- "subtitles settings": "altyazı ayarları",
- "descriptions settings": "açıklama ayarları",
- "Text": "Yazı",
- "White": "Beyaz",
- "Black": "Siyah",
- "Red": "Kırmızı",
- "Green": "Yeşil",
- "Blue": "Mavi",
- "Yellow": "Sarı",
- "Magenta": "Macenta",
- "Cyan": "Açık Mavi (Camgöbeği)",
- "Background": "Arka plan",
- "Window": "Pencere",
- "Transparent": "Saydam",
- "Semi-Transparent": "Yarı-Saydam",
- "Opaque": "Mat",
- "Font Size": "Yazı Boyutu",
- "Text Edge Style": "Yazı Kenarlıkları",
- "None": "Hiçbiri",
- "Raised": "Kabartılmış",
- "Depressed": "Yassı",
- "Uniform": "Düz",
- "Dropshadow": "Gölgeli",
- "Font Family": "Yazı Tipi",
- "Proportional Sans-Serif": "Orantılı Sans-Serif",
- "Monospace Sans-Serif": "Eşaralıklı Sans-Serif",
- "Proportional Serif": "Orantılı Serif",
- "Monospace Serif": "Eşaralıklı Serif",
- "Casual": "Gündelik",
- "Script": "El Yazısı",
- "Small Caps": "Küçük Boyutlu Büyük Harfli",
- "Done": "Tamam",
- "Caption Settings Dialog": "Altyazı Ayarları Menüsü",
- "Beginning of dialog window. Escape will cancel and close the window.": "Diyalog penceresinin başlangıcı. ESC tuşu işlemi iptal edip pencereyi kapatacaktır."
+videojs.addLanguage('tr', {
+ "Play": "Oynat",
+ "Pause": "Duraklat",
+ "Replay": "Yeniden Oynat",
+ "Current Time": "Süre",
+ "Duration": "Toplam Süre",
+ "Remaining Time": "Kalan Süre",
+ "Stream Type": "Yayın Tipi",
+ "LIVE": "CANLI",
+ "Loaded": "Yüklendi",
+ "Progress": "Yükleniyor",
+ "Fullscreen": "Tam Ekran",
+ "Non-Fullscreen": "Küçük Ekran",
+ "Mute": "Ses Kapa",
+ "Unmute": "Ses Aç",
+ "Playback Rate": "Oynatma Hızı",
+ "Subtitles": "Altyazı",
+ "subtitles off": "Altyazı Kapalı",
+ "Captions": "Altyazı",
+ "captions off": "Altyazı Kapalı",
+ "Chapters": "Bölümler",
+ "Close Modal Dialog": "Dialogu Kapat",
+ "Descriptions": "Açıklamalar",
+ "descriptions off": "Açıklamalar kapalı",
+ "Audio Track": "Ses Dosyası",
+ "You aborted the media playback": "Video oynatmayı iptal ettiniz",
+ "A network error caused the media download to fail part-way.": "Video indirilirken bağlantı sorunu oluştu.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video oynatılamadı, ağ ya da sunucu hatası veya belirtilen format desteklenmiyor.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Tarayıcınız desteklemediği için videoda hata oluştu.",
+ "No compatible source was found for this media.": "Video için kaynak bulunamadı.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Video, şifrelenmiş bir kaynaktan geliyor ve oynatmak için gerekli anahtar bulunamadı.",
+ "Play Video": "Videoyu Oynat",
+ "Close": "Kapat",
+ "Modal Window": "Modal Penceresi",
+ "This is a modal window": "Bu bir modal penceresidir",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Bu modal ESC tuşuna basarak ya da kapata tıklanarak kapatılabilir.",
+ ", opens captions settings dialog": ", altyazı ayarları menüsünü açar",
+ ", opens subtitles settings dialog": ", altyazı ayarları menüsünü açar",
+ ", opens descriptions settings dialog": ", açıklama ayarları menüsünü açar",
+ ", selected": ", seçildi",
+ "captions settings": "altyazı ayarları",
+ "subtitles settings": "altyazı ayarları",
+ "descriptions settings": "açıklama ayarları",
+ "Text": "Yazı",
+ "White": "Beyaz",
+ "Black": "Siyah",
+ "Red": "Kırmızı",
+ "Green": "Yeşil",
+ "Blue": "Mavi",
+ "Yellow": "Sarı",
+ "Magenta": "Macenta",
+ "Cyan": "Açık Mavi (Camgöbeği)",
+ "Background": "Arka plan",
+ "Window": "Pencere",
+ "Transparent": "Saydam",
+ "Semi-Transparent": "Yarı-Saydam",
+ "Opaque": "Mat",
+ "Font Size": "Yazı Boyutu",
+ "Text Edge Style": "Yazı Kenarlıkları",
+ "None": "Hiçbiri",
+ "Raised": "Kabartılmış",
+ "Depressed": "Yassı",
+ "Uniform": "Düz",
+ "Dropshadow": "Gölgeli",
+ "Font Family": "Yazı Tipi",
+ "Proportional Sans-Serif": "Orantılı Sans-Serif",
+ "Monospace Sans-Serif": "Eşaralıklı Sans-Serif",
+ "Proportional Serif": "Orantılı Serif",
+ "Monospace Serif": "Eşaralıklı Serif",
+ "Casual": "Gündelik",
+ "Script": "El Yazısı",
+ "Small Caps": "Küçük Boyutlu Büyük Harfli",
+ "Done": "Tamam",
+ "Caption Settings Dialog": "Altyazı Ayarları Menüsü",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Diyalog penceresinin başlangıcı. ESC tuşu işlemi iptal edip pencereyi kapatacaktır."
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "Oynat",
+ "Pause": "Duraklat",
+ "Replay": "Yeniden Oynat",
+ "Current Time": "Süre",
+ "Duration": "Toplam Süre",
+ "Remaining Time": "Kalan Süre",
+ "Stream Type": "Yayın Tipi",
+ "LIVE": "CANLI",
+ "Loaded": "Yüklendi",
+ "Progress": "Yükleniyor",
+ "Fullscreen": "Tam Ekran",
+ "Non-Fullscreen": "Küçük Ekran",
+ "Mute": "Ses Kapa",
+ "Unmute": "Ses Aç",
+ "Playback Rate": "Oynatma Hızı",
+ "Subtitles": "Altyazı",
+ "subtitles off": "Altyazı Kapalı",
+ "Captions": "Altyazı",
+ "captions off": "Altyazı Kapalı",
+ "Chapters": "Bölümler",
+ "Close Modal Dialog": "Dialogu Kapat",
+ "Descriptions": "Açıklamalar",
+ "descriptions off": "Açıklamalar kapalı",
+ "Audio Track": "Ses Dosyası",
+ "You aborted the media playback": "Video oynatmayı iptal ettiniz",
+ "A network error caused the media download to fail part-way.": "Video indirilirken bağlantı sorunu oluştu.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video oynatılamadı, ağ ya da sunucu hatası veya belirtilen format desteklenmiyor.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Tarayıcınız desteklemediği için videoda hata oluştu.",
+ "No compatible source was found for this media.": "Video için kaynak bulunamadı.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Video, şifrelenmiş bir kaynaktan geliyor ve oynatmak için gerekli anahtar bulunamadı.",
+ "Play Video": "Videoyu Oynat",
+ "Close": "Kapat",
+ "Modal Window": "Modal Penceresi",
+ "This is a modal window": "Bu bir modal penceresidir",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Bu modal ESC tuşuna basarak ya da kapata tıklanarak kapatılabilir.",
+ ", opens captions settings dialog": ", altyazı ayarları menüsünü açar",
+ ", opens subtitles settings dialog": ", altyazı ayarları menüsünü açar",
+ ", opens descriptions settings dialog": ", açıklama ayarları menüsünü açar",
+ ", selected": ", seçildi",
+ "captions settings": "altyazı ayarları",
+ "subtitles settings": "altyazı ayarları",
+ "descriptions settings": "açıklama ayarları",
+ "Text": "Yazı",
+ "White": "Beyaz",
+ "Black": "Siyah",
+ "Red": "Kırmızı",
+ "Green": "Yeşil",
+ "Blue": "Mavi",
+ "Yellow": "Sarı",
+ "Magenta": "Macenta",
+ "Cyan": "Açık Mavi (Camgöbeği)",
+ "Background": "Arka plan",
+ "Window": "Pencere",
+ "Transparent": "Saydam",
+ "Semi-Transparent": "Yarı-Saydam",
+ "Opaque": "Mat",
+ "Font Size": "Yazı Boyutu",
+ "Text Edge Style": "Yazı Kenarlıkları",
+ "None": "Hiçbiri",
+ "Raised": "Kabartılmış",
+ "Depressed": "Yassı",
+ "Uniform": "Düz",
+ "Dropshadow": "Gölgeli",
+ "Font Family": "Yazı Tipi",
+ "Proportional Sans-Serif": "Orantılı Sans-Serif",
+ "Monospace Sans-Serif": "Eşaralıklı Sans-Serif",
+ "Proportional Serif": "Orantılı Serif",
+ "Monospace Serif": "Eşaralıklı Serif",
+ "Casual": "Gündelik",
+ "Script": "El Yazısı",
+ "Small Caps": "Küçük Boyutlu Büyük Harfli",
+ "Done": "Tamam",
+ "Caption Settings Dialog": "Altyazı Ayarları Menüsü",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Diyalog penceresinin başlangıcı. ESC tuşu işlemi iptal edip pencereyi kapatacaktır."
+}
-videojs.addLanguage("uk",{
- "Play": "Відтворити",
- "Pause": "Призупинити",
- "Current Time": "Поточний час",
- "Duration Time": "Тривалість",
- "Remaining Time": "Час, що залишився",
- "Stream Type": "Тип потоку",
- "LIVE": "НАЖИВО",
- "Loaded": "Завантаження",
- "Progress": "Прогрес",
- "Fullscreen": "Повноекранний режим",
- "Non-Fullscreen": "Неповноекранний режим",
- "Mute": "Без звуку",
- "Unmute": "Зі звуком",
- "Playback Rate": "Швидкість відтворення",
- "Subtitles": "Субтитри",
- "subtitles off": "Без субтитрів",
- "Captions": "Підписи",
- "captions off": "Без підписів",
- "Chapters": "Розділи",
- "Close Modal Dialog": "Закрити модальний діалог",
- "Descriptions": "Описи",
- "descriptions off": "Без описів",
- "Audio Track": "Аудіодоріжка",
- "You aborted the media playback": "Ви припинили відтворення відео",
- "A network error caused the media download to fail part-way.": "Помилка мережі викликала збій під час завантаження відео.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Неможливо завантажити відео через мережевий чи серверний збій або формат не підтримується.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Відтворення відео було припинено через пошкодження або у зв'язку з тим, що відео використовує функції, які не підтримуються вашим браузером.",
- "No compatible source was found for this media.": "Сумісні джерела для цього відео відсутні.",
- "The media is encrypted and we do not have the keys to decrypt it.": "Відео в зашифрованому вигляді, і ми не маємо ключі для розшифровки.",
- "Play Video": "Відтворити відео",
- "Close": "Закрити",
- "Modal Window": "Модальне вікно",
- "This is a modal window": "Це модальне вікно.",
- "This modal can be closed by pressing the Escape key or activating the close button.": "Модальне вікно можна закрити, натиснувши клавішу Esc або кнопку закриття вікна.",
- ", opens captions settings dialog": ", відкриється діалогове вікно налаштування підписів",
- ", opens subtitles settings dialog": ", відкриється діалогове вікно налаштування субтитрів",
- ", opens descriptions settings dialog": ", відкриється діалогове вікно налаштування описів",
- ", selected": ", обраний"
+videojs.addLanguage('uk', {
+ "Audio Player": "Аудіопрогравач",
+ "Video Player": "Відеопрогравач",
+ "Play": "Відтворити",
+ "Pause": "Призупинити",
+ "Replay": "Відтворити знову",
+ "Current Time": "Поточний час",
+ "Duration": "Тривалість",
+ "Remaining Time": "Час, що залишився",
+ "Stream Type": "Тип потоку",
+ "LIVE": "НАЖИВО",
+ "Loaded": "Завантаження",
+ "Progress": "Прогрес",
+ "Progress Bar": "Індикатор завантаження",
+ "progress bar timing: currentTime={1} duration={2}": "{1} з {2}",
+ "Fullscreen": "Повноекранний режим",
+ "Non-Fullscreen": "Неповноекранний режим",
+ "Mute": "Без звуку",
+ "Unmute": "Зі звуком",
+ "Playback Rate": "Швидкість відтворення",
+ "Subtitles": "Субтитри",
+ "subtitles off": "Без субтитрів",
+ "Captions": "Підписи",
+ "captions off": "Без підписів",
+ "Chapters": "Розділи",
+ "Close Modal Dialog": "Закрити модальний діалог",
+ "Descriptions": "Описи",
+ "descriptions off": "Без описів",
+ "Audio Track": "Аудіодоріжка",
+ "Volume Level": "Рівень гучності",
+ "You aborted the media playback": "Ви припинили відтворення відео",
+ "A network error caused the media download to fail part-way.": "Помилка мережі викликала збій під час завантаження відео.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Неможливо завантажити відео через мережевий чи серверний збій або формат не підтримується.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Відтворення відео було припинено через пошкодження або у зв'язку з тим, що відео використовує функції, які не підтримуються вашим браузером.",
+ "No compatible source was found for this media.": "Сумісні джерела для цього відео відсутні.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Відео в зашифрованому вигляді, і ми не маємо ключі для розшифровки.",
+ "Play Video": "Відтворити відео",
+ "Close": "Закрити",
+ "Modal Window": "Модальне вікно",
+ "This is a modal window": "Це модальне вікно.",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Модальне вікно можна закрити, натиснувши клавішу Esc або кнопку закриття вікна.",
+ ", opens captions settings dialog": ", відкриється діалогове вікно налаштування підписів",
+ ", opens subtitles settings dialog": ", відкриється діалогове вікно налаштування субтитрів",
+ ", opens descriptions settings dialog": ", відкриється діалогове вікно налаштування описів",
+ ", selected": ", обраний",
+ "captions settings": "налаштування підписів",
+ "subtitles settings": "налаштування субтитрів",
+ "descriptions settings": "налаштування описів",
+ "Text": "Текст",
+ "White": "Білий",
+ "Black": "Чорний",
+ "Red": "Червоний",
+ "Green": "Зелений",
+ "Blue": "Синій",
+ "Yellow": "Жовтий",
+ "Magenta": "Пурпурний",
+ "Cyan": "Блакитний",
+ "Background": "Фон",
+ "Window": "Вікно",
+ "Transparent": "Прозорий",
+ "Semi-Transparent": "Напівпрозорий",
+ "Opaque": "Прозорість",
+ "Font Size": "Розмір шрифту",
+ "Text Edge Style": "Стиль краю тексту",
+ "None": "Нічого",
+ "Raised": "Піднятий",
+ "Depressed": "Знижений",
+ "Uniform": "Однаковий",
+ "Dropshadow": "Тінь",
+ "Font Family": "Шрифт",
+ "Proportional Sans-Serif": "Пропорційний без засічок",
+ "Monospace Sans-Serif": "Моноширинний без засічок",
+ "Proportional Serif": "Пропорційний із засічками",
+ "Monospace Serif": "Моноширинний із засічками",
+ "Casual": "Випадковий",
+ "Script": "Писемний",
+ "Small Caps": "Малі прописні",
+ "Reset": "Скинути",
+ "restore all settings to the default values": "скинути всі налаштування за замовчуванням",
+ "Done": "Готово",
+ "Caption Settings Dialog": "Діалог налаштувань підпису",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Початок діалоговго вікна. Кнопка Escape закриє або скасує вікно",
+ "End of dialog window.": "Кінець діалогового вікна.",
+ "{1} is loading.": "{1} завантажується."
});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Аудіопрогравач",
+ "Video Player": "Відеопрогравач",
+ "Play": "Відтворити",
+ "Pause": "Призупинити",
+ "Replay": "Відтворити знову",
+ "Current Time": "Поточний час",
+ "Duration": "Тривалість",
+ "Remaining Time": "Час, що залишився",
+ "Stream Type": "Тип потоку",
+ "LIVE": "НАЖИВО",
+ "Loaded": "Завантаження",
+ "Progress": "Прогрес",
+ "Progress Bar": "Індикатор завантаження",
+ "progress bar timing: currentTime={1} duration={2}": "{1} з {2}",
+ "Fullscreen": "Повноекранний режим",
+ "Non-Fullscreen": "Неповноекранний режим",
+ "Mute": "Без звуку",
+ "Unmute": "Зі звуком",
+ "Playback Rate": "Швидкість відтворення",
+ "Subtitles": "Субтитри",
+ "subtitles off": "Без субтитрів",
+ "Captions": "Підписи",
+ "captions off": "Без підписів",
+ "Chapters": "Розділи",
+ "Close Modal Dialog": "Закрити модальний діалог",
+ "Descriptions": "Описи",
+ "descriptions off": "Без описів",
+ "Audio Track": "Аудіодоріжка",
+ "Volume Level": "Рівень гучності",
+ "You aborted the media playback": "Ви припинили відтворення відео",
+ "A network error caused the media download to fail part-way.": "Помилка мережі викликала збій під час завантаження відео.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Неможливо завантажити відео через мережевий чи серверний збій або формат не підтримується.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Відтворення відео було припинено через пошкодження або у зв'язку з тим, що відео використовує функції, які не підтримуються вашим браузером.",
+ "No compatible source was found for this media.": "Сумісні джерела для цього відео відсутні.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Відео в зашифрованому вигляді, і ми не маємо ключі для розшифровки.",
+ "Play Video": "Відтворити відео",
+ "Close": "Закрити",
+ "Modal Window": "Модальне вікно",
+ "This is a modal window": "Це модальне вікно.",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Модальне вікно можна закрити, натиснувши клавішу Esc або кнопку закриття вікна.",
+ ", opens captions settings dialog": ", відкриється діалогове вікно налаштування підписів",
+ ", opens subtitles settings dialog": ", відкриється діалогове вікно налаштування субтитрів",
+ ", opens descriptions settings dialog": ", відкриється діалогове вікно налаштування описів",
+ ", selected": ", обраний",
+ "captions settings": "налаштування підписів",
+ "subtitles settings": "налаштування субтитрів",
+ "descriptions settings": "налаштування описів",
+ "Text": "Текст",
+ "White": "Білий",
+ "Black": "Чорний",
+ "Red": "Червоний",
+ "Green": "Зелений",
+ "Blue": "Синій",
+ "Yellow": "Жовтий",
+ "Magenta": "Пурпурний",
+ "Cyan": "Блакитний",
+ "Background": "Фон",
+ "Window": "Вікно",
+ "Transparent": "Прозорий",
+ "Semi-Transparent": "Напівпрозорий",
+ "Opaque": "Прозорість",
+ "Font Size": "Розмір шрифту",
+ "Text Edge Style": "Стиль краю тексту",
+ "None": "Нічого",
+ "Raised": "Піднятий",
+ "Depressed": "Знижений",
+ "Uniform": "Однаковий",
+ "Dropshadow": "Тінь",
+ "Font Family": "Шрифт",
+ "Proportional Sans-Serif": "Пропорційний без засічок",
+ "Monospace Sans-Serif": "Моноширинний без засічок",
+ "Proportional Serif": "Пропорційний із засічками",
+ "Monospace Serif": "Моноширинний із засічками",
+ "Casual": "Випадковий",
+ "Script": "Писемний",
+ "Small Caps": "Малі прописні",
+ "Reset": "Скинути",
+ "restore all settings to the default values": "скинути всі налаштування за замовчуванням",
+ "Done": "Готово",
+ "Caption Settings Dialog": "Діалог налаштувань підпису",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Початок діалоговго вікна. Кнопка Escape закриє або скасує вікно",
+ "End of dialog window.": "Кінець діалогового вікна.",
+ "{1} is loading.": "{1} завантажується."
+}
-videojs.addLanguage("vi",{
- "Audio Player": "Trình phát Audio",
- "Video Player": "Trình phát Video",
- "Play": "Phát",
- "Pause": "Tạm dừng",
- "Replay": "Phát lại",
- "Current Time": "Thời gian hiện tại",
- "Duration Time": "Độ dài",
- "Remaining Time": "Thời gian còn lại",
- "Stream Type": "Kiểu Stream",
- "LIVE": "TRỰC TIẾP",
- "Loaded": "Đã tải",
- "Progress": "Tiến trình",
- "Progress Bar": "Thanh tiến trình",
- "progress bar timing: currentTime={1} duration={2}": "{1} của {2}",
- "Fullscreen": "Toàn màn hình",
- "Non-Fullscreen": "Thoát toàn màn hình",
- "Mute": "Tắt tiếng",
- "Unmute": "Bật âm thanh",
- "Playback Rate": "Tỉ lệ phát lại",
- "Subtitles": "Phụ đề",
- "subtitles off": "tắt phụ đề",
- "Captions": "Chú thích",
- "captions off": "tắt chú thích",
- "Chapters": "Chương",
- "Descriptions": "Mô tả",
- "descriptions off": "tắt mô tả",
- "Audio Track": "Track âm thanh",
- "Volume Level": "Mức âm lượng",
- "You aborted the media playback": "Bạn đã hủy việc phát lại media.",
- "A network error caused the media download to fail part-way.": "Một lỗi mạng dẫn đến việc tải media bị lỗi.",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video không tải được, mạng hay server có lỗi hoặc định dạng không được hỗ trợ.",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Phát media đã bị hủy do một sai lỗi hoặc media sử dụng những tính năng trình duyệt không hỗ trợ.",
- "No compatible source was found for this media.": "Không có nguồn tương thích cho media này.",
- "The media is encrypted and we do not have the keys to decrypt it.": "Media đã được mã hóa và chúng tôi không có để giải mã nó.",
- "Play Video": "Phát Video",
- "Close": "Đóng",
- "Close Modal Dialog": "Đóng cửa sổ",
- "Modal Window": "Cửa sổ",
- "This is a modal window": "Đây là một cửa sổ",
- "This modal can be closed by pressing the Escape key or activating the close button.": "Cửa sổ này có thể thoát bằng việc nhấn phím Esc hoặc kích hoạt nút đóng.",
- ", opens captions settings dialog": ", mở hộp thoại cài đặt chú thích",
- ", opens subtitles settings dialog": ", mở hộp thoại cài đặt phụ đề",
- ", opens descriptions settings dialog": ", mở hộp thoại cài đặt mô tả",
- ", selected": ", đã chọn",
- "captions settings": "cài đặt chú thích",
- "subtitles settings": "cài đặt phụ đề",
- "descriptions settings": "cài đặt mô tả",
- "Text": "Văn bản",
- "White": "Trắng",
- "Black": "Đen",
- "Red": "Đỏ",
- "Green": "Xanh lá cây",
- "Blue": "Xanh da trời",
- "Yellow": "Vàng",
- "Magenta": "Đỏ tươi",
- "Cyan": "Lam",
- "Background": "Nền",
- "Window": "Cửa sổ",
- "Transparent": "Trong suốt",
- "Semi-Transparent": "Bán trong suốt",
- "Opaque": "Mờ",
- "Font Size": "Kích cỡ phông chữ",
- "Text Edge Style": "Dạng viền văn bản",
- "None": "None",
- "Raised": "Raised",
- "Depressed": "Depressed",
- "Uniform": "Uniform",
- "Dropshadow": "Dropshadow",
- "Font Family": "Phông chữ",
- "Proportional Sans-Serif": "Proportional Sans-Serif",
- "Monospace Sans-Serif": "Monospace Sans-Serif",
- "Proportional Serif": "Proportional Serif",
- "Monospace Serif": "Monospace Serif",
- "Casual": "Casual",
- "Script": "Script",
- "Small Caps": "Small Caps",
- "Reset": "Đặt lại",
- "restore all settings to the default values": "khôi phục lại tất cả các cài đặt về giá trị mặc định",
- "Done": "Xong",
- "Caption Settings Dialog": "Hộp thoại cài đặt chú thích",
- "Beginning of dialog window. Escape will cancel and close the window.": "Bắt đầu cửa sổ hộp thoại. Esc sẽ thoát và đóng cửa sổ.",
- "End of dialog window.": "Kết thúc cửa sổ hộp thoại."
+videojs.addLanguage('vi', {
+ "Audio Player": "Trình phát Audio",
+ "Video Player": "Trình phát Video",
+ "Play": "Phát",
+ "Pause": "Tạm dừng",
+ "Replay": "Phát lại",
+ "Current Time": "Thời gian hiện tại",
+ "Duration": "Độ dài",
+ "Remaining Time": "Thời gian còn lại",
+ "Stream Type": "Kiểu Stream",
+ "LIVE": "TRỰC TIẾP",
+ "Loaded": "Đã tải",
+ "Progress": "Tiến trình",
+ "Progress Bar": "Thanh tiến trình",
+ "progress bar timing: currentTime={1} duration={2}": "{1} của {2}",
+ "Fullscreen": "Toàn màn hình",
+ "Non-Fullscreen": "Thoát toàn màn hình",
+ "Mute": "Tắt tiếng",
+ "Unmute": "Bật âm thanh",
+ "Playback Rate": "Tỉ lệ phát lại",
+ "Subtitles": "Phụ đề",
+ "subtitles off": "tắt phụ đề",
+ "Captions": "Chú thích",
+ "captions off": "tắt chú thích",
+ "Chapters": "Chương",
+ "Descriptions": "Mô tả",
+ "descriptions off": "tắt mô tả",
+ "Audio Track": "Track âm thanh",
+ "Volume Level": "Mức âm lượng",
+ "You aborted the media playback": "Bạn đã hủy việc phát lại media.",
+ "A network error caused the media download to fail part-way.": "Một lỗi mạng dẫn đến việc tải media bị lỗi.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video không tải được, mạng hay server có lỗi hoặc định dạng không được hỗ trợ.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Phát media đã bị hủy do một sai lỗi hoặc media sử dụng những tính năng trình duyệt không hỗ trợ.",
+ "No compatible source was found for this media.": "Không có nguồn tương thích cho media này.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Media đã được mã hóa và chúng tôi không có để giải mã nó.",
+ "Play Video": "Phát Video",
+ "Close": "Đóng",
+ "Close Modal Dialog": "Đóng cửa sổ",
+ "Modal Window": "Cửa sổ",
+ "This is a modal window": "Đây là một cửa sổ",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Cửa sổ này có thể thoát bằng việc nhấn phím Esc hoặc kích hoạt nút đóng.",
+ ", opens captions settings dialog": ", mở hộp thoại cài đặt chú thích",
+ ", opens subtitles settings dialog": ", mở hộp thoại cài đặt phụ đề",
+ ", opens descriptions settings dialog": ", mở hộp thoại cài đặt mô tả",
+ ", selected": ", đã chọn",
+ "captions settings": "cài đặt chú thích",
+ "subtitles settings": "cài đặt phụ đề",
+ "descriptions settings": "cài đặt mô tả",
+ "Text": "Văn bản",
+ "White": "Trắng",
+ "Black": "Đen",
+ "Red": "Đỏ",
+ "Green": "Xanh lá cây",
+ "Blue": "Xanh da trời",
+ "Yellow": "Vàng",
+ "Magenta": "Đỏ tươi",
+ "Cyan": "Lam",
+ "Background": "Nền",
+ "Window": "Cửa sổ",
+ "Transparent": "Trong suốt",
+ "Semi-Transparent": "Bán trong suốt",
+ "Opaque": "Mờ",
+ "Font Size": "Kích cỡ phông chữ",
+ "Text Edge Style": "Dạng viền văn bản",
+ "None": "None",
+ "Raised": "Raised",
+ "Depressed": "Depressed",
+ "Uniform": "Uniform",
+ "Dropshadow": "Dropshadow",
+ "Font Family": "Phông chữ",
+ "Proportional Sans-Serif": "Proportional Sans-Serif",
+ "Monospace Sans-Serif": "Monospace Sans-Serif",
+ "Proportional Serif": "Proportional Serif",
+ "Monospace Serif": "Monospace Serif",
+ "Casual": "Casual",
+ "Script": "Script",
+ "Small Caps": "Small Caps",
+ "Reset": "Đặt lại",
+ "restore all settings to the default values": "khôi phục lại tất cả các cài đặt về giá trị mặc định",
+ "Done": "Xong",
+ "Caption Settings Dialog": "Hộp thoại cài đặt chú thích",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Bắt đầu cửa sổ hộp thoại. Esc sẽ thoát và đóng cửa sổ.",
+ "End of dialog window.": "Kết thúc cửa sổ hộp thoại."
});
\ No newline at end of file
--- /dev/null
+{
+ "Audio Player": "Trình phát Audio",
+ "Video Player": "Trình phát Video",
+ "Play": "Phát",
+ "Pause": "Tạm dừng",
+ "Replay": "Phát lại",
+ "Current Time": "Thời gian hiện tại",
+ "Duration": "Độ dài",
+ "Remaining Time": "Thời gian còn lại",
+ "Stream Type": "Kiểu Stream",
+ "LIVE": "TRỰC TIẾP",
+ "Loaded": "Đã tải",
+ "Progress": "Tiến trình",
+ "Progress Bar": "Thanh tiến trình",
+ "progress bar timing: currentTime={1} duration={2}": "{1} của {2}",
+ "Fullscreen": "Toàn màn hình",
+ "Non-Fullscreen": "Thoát toàn màn hình",
+ "Mute": "Tắt tiếng",
+ "Unmute": "Bật âm thanh",
+ "Playback Rate": "Tỉ lệ phát lại",
+ "Subtitles": "Phụ đề",
+ "subtitles off": "tắt phụ đề",
+ "Captions": "Chú thích",
+ "captions off": "tắt chú thích",
+ "Chapters": "Chương",
+ "Descriptions": "Mô tả",
+ "descriptions off": "tắt mô tả",
+ "Audio Track": "Track âm thanh",
+ "Volume Level": "Mức âm lượng",
+ "You aborted the media playback": "Bạn đã hủy việc phát lại media.",
+ "A network error caused the media download to fail part-way.": "Một lỗi mạng dẫn đến việc tải media bị lỗi.",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video không tải được, mạng hay server có lỗi hoặc định dạng không được hỗ trợ.",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Phát media đã bị hủy do một sai lỗi hoặc media sử dụng những tính năng trình duyệt không hỗ trợ.",
+ "No compatible source was found for this media.": "Không có nguồn tương thích cho media này.",
+ "The media is encrypted and we do not have the keys to decrypt it.": "Media đã được mã hóa và chúng tôi không có để giải mã nó.",
+ "Play Video": "Phát Video",
+ "Close": "Đóng",
+ "Close Modal Dialog": "Đóng cửa sổ",
+ "Modal Window": "Cửa sổ",
+ "This is a modal window": "Đây là một cửa sổ",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "Cửa sổ này có thể thoát bằng việc nhấn phím Esc hoặc kích hoạt nút đóng.",
+ ", opens captions settings dialog": ", mở hộp thoại cài đặt chú thích",
+ ", opens subtitles settings dialog": ", mở hộp thoại cài đặt phụ đề",
+ ", opens descriptions settings dialog": ", mở hộp thoại cài đặt mô tả",
+ ", selected": ", đã chọn",
+ "captions settings": "cài đặt chú thích",
+ "subtitles settings": "cài đặt phụ đề",
+ "descriptions settings": "cài đặt mô tả",
+ "Text": "Văn bản",
+ "White": "Trắng",
+ "Black": "Đen",
+ "Red": "Đỏ",
+ "Green": "Xanh lá cây",
+ "Blue": "Xanh da trời",
+ "Yellow": "Vàng",
+ "Magenta": "Đỏ tươi",
+ "Cyan": "Lam",
+ "Background": "Nền",
+ "Window": "Cửa sổ",
+ "Transparent": "Trong suốt",
+ "Semi-Transparent": "Bán trong suốt",
+ "Opaque": "Mờ",
+ "Font Size": "Kích cỡ phông chữ",
+ "Text Edge Style": "Dạng viền văn bản",
+ "None": "None",
+ "Raised": "Raised",
+ "Depressed": "Depressed",
+ "Uniform": "Uniform",
+ "Dropshadow": "Dropshadow",
+ "Font Family": "Phông chữ",
+ "Proportional Sans-Serif": "Proportional Sans-Serif",
+ "Monospace Sans-Serif": "Monospace Sans-Serif",
+ "Proportional Serif": "Proportional Serif",
+ "Monospace Serif": "Monospace Serif",
+ "Casual": "Casual",
+ "Script": "Script",
+ "Small Caps": "Small Caps",
+ "Reset": "Đặt lại",
+ "restore all settings to the default values": "khôi phục lại tất cả các cài đặt về giá trị mặc định",
+ "Done": "Xong",
+ "Caption Settings Dialog": "Hộp thoại cài đặt chú thích",
+ "Beginning of dialog window. Escape will cancel and close the window.": "Bắt đầu cửa sổ hộp thoại. Esc sẽ thoát và đóng cửa sổ.",
+ "End of dialog window.": "Kết thúc cửa sổ hộp thoại."
+}
-videojs.addLanguage("zh-CN",{
- "Play": "播放",
- "Pause": "暂停",
- "Current Time": "当前时间",
- "Duration Time": "时长",
- "Remaining Time": "剩余时间",
- "Stream Type": "媒体流类型",
- "LIVE": "直播",
- "Loaded": "加载完毕",
- "Progress": "进度",
- "Fullscreen": "全屏",
- "Non-Fullscreen": "退出全屏",
- "Mute": "静音",
- "Unmute": "取消静音",
- "Playback Rate": "播放速度",
- "Subtitles": "字幕",
- "subtitles off": "关闭字幕",
- "Captions": "内嵌字幕",
- "captions off": "关闭内嵌字幕",
- "Chapters": "节目段落",
- "Close Modal Dialog": "关闭弹窗",
- "Descriptions": "描述",
- "descriptions off": "关闭描述",
- "Audio Track": "音轨",
- "You aborted the media playback": "视频播放被终止",
- "A network error caused the media download to fail part-way.": "网络错误导致视频下载中途失败。",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "视频因格式不支持或者服务器或网络的问题无法加载。",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "由于视频文件损坏或是该视频使用了你的浏览器不支持的功能,播放终止。",
- "No compatible source was found for this media.": "无法找到此视频兼容的源。",
- "The media is encrypted and we do not have the keys to decrypt it.": "视频已加密,无法解密。",
- "Play Video": "播放视频",
- "Close": "关闭",
- "Modal Window": "弹窗",
- "This is a modal window": "这是一个弹窗",
- "This modal can be closed by pressing the Escape key or activating the close button.": "可以按ESC按键或启用关闭按钮来关闭此弹窗。",
- ", opens captions settings dialog": ", 开启标题设置弹窗",
- ", opens subtitles settings dialog": ", 开启字幕设置弹窗",
- ", opens descriptions settings dialog": ", 开启描述设置弹窗",
- ", selected": ", 选择"
+videojs.addLanguage('zh-CN', {
+ "Play": "播放",
+ "Pause": "暂停",
+ "Current Time": "当前时间",
+ "Duration": "时长",
+ "Remaining Time": "剩余时间",
+ "Stream Type": "媒体流类型",
+ "LIVE": "直播",
+ "Loaded": "加载完成",
+ "Progress": "进度",
+ "Fullscreen": "全屏",
+ "Non-Fullscreen": "退出全屏",
+ "Picture-in-Picture": "画中画",
+ "Exit Picture-in-Picture": "退出画中画",
+ "Mute": "静音",
+ "Unmute": "取消静音",
+ "Playback Rate": "播放速度",
+ "Subtitles": "字幕",
+ "subtitles off": "关闭字幕",
+ "Captions": "内嵌字幕",
+ "captions off": "关闭内嵌字幕",
+ "Chapters": "节目段落",
+ "Close Modal Dialog": "关闭弹窗",
+ "Descriptions": "描述",
+ "descriptions off": "关闭描述",
+ "Audio Track": "音轨",
+ "You aborted the media playback": "视频播放被终止",
+ "A network error caused the media download to fail part-way.": "网络错误导致视频下载中途失败。",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "视频因格式不支持或者服务器或网络的问题无法加载。",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "由于视频文件损坏或是该视频使用了你的浏览器不支持的功能,播放终止。",
+ "No compatible source was found for this media.": "无法找到此视频兼容的源。",
+ "The media is encrypted and we do not have the keys to decrypt it.": "视频已加密,无法解密。",
+ "Play Video": "播放视频",
+ "Close": "关闭",
+ "Modal Window": "弹窗",
+ "This is a modal window": "这是一个弹窗",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "可以按ESC按键或启用关闭按钮来关闭此弹窗。",
+ ", opens captions settings dialog": ", 开启标题设置弹窗",
+ ", opens subtitles settings dialog": ", 开启字幕设置弹窗",
+ ", opens descriptions settings dialog": ", 开启描述设置弹窗",
+ ", selected": ", 选择",
+ "captions settings": "字幕设定",
+ "Audio Player": "音频播放器",
+ "Video Player": "视频播放器",
+ "Replay": "重新播放",
+ "Progress Bar": "进度条",
+ "Volume Level": "音量",
+ "subtitles settings": "字幕设定",
+ "descriptions settings": "描述设定",
+ "Text": "文字",
+ "White": "白",
+ "Black": "黑",
+ "Red": "红",
+ "Green": "绿",
+ "Blue": "蓝",
+ "Yellow": "黄",
+ "Magenta": "紫红",
+ "Cyan": "青",
+ "Background": "背景",
+ "Window": "窗口",
+ "Transparent": "透明",
+ "Semi-Transparent": "半透明",
+ "Opaque": "不透明",
+ "Font Size": "字体尺寸",
+ "Text Edge Style": "字体边缘样式",
+ "None": "无",
+ "Raised": "浮雕",
+ "Depressed": "压低",
+ "Uniform": "均匀",
+ "Dropshadow": "下阴影",
+ "Font Family": "字体库",
+ "Proportional Sans-Serif": "比例无细体",
+ "Monospace Sans-Serif": "单间隔无细体",
+ "Proportional Serif": "比例细体",
+ "Monospace Serif": "单间隔细体",
+ "Casual": "舒适",
+ "Script": "手写体",
+ "Small Caps": "小型大写字体",
+ "Reset": "重置",
+ "restore all settings to the default values": "恢复全部设定至预设值",
+ "Done": "完成",
+ "Caption Settings Dialog": "字幕设定窗口",
+ "Beginning of dialog window. Escape will cancel and close the window.": "打开对话窗口。Escape键将取消并关闭对话窗口",
+ "End of dialog window.": "结束对话窗口",
+ "Seek to live, currently behind live": "尝试直播,当前为延时播放",
+ "Seek to live, currently playing live": "尝试直播,当前为实时播放",
+ "progress bar timing: currentTime={1} duration={2}": "{1}/{2}",
+ "{1} is loading.": "正在加载 {1}。"
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "播放",
+ "Pause": "暂停",
+ "Current Time": "当前时间",
+ "Duration": "时长",
+ "Remaining Time": "剩余时间",
+ "Stream Type": "媒体流类型",
+ "LIVE": "直播",
+ "Loaded": "加载完成",
+ "Progress": "进度",
+ "Fullscreen": "全屏",
+ "Non-Fullscreen": "退出全屏",
+ "Picture-in-Picture": "画中画",
+ "Exit Picture-in-Picture": "退出画中画",
+ "Mute": "静音",
+ "Unmute": "取消静音",
+ "Playback Rate": "播放速度",
+ "Subtitles": "字幕",
+ "subtitles off": "关闭字幕",
+ "Captions": "内嵌字幕",
+ "captions off": "关闭内嵌字幕",
+ "Chapters": "节目段落",
+ "Close Modal Dialog": "关闭弹窗",
+ "Descriptions": "描述",
+ "descriptions off": "关闭描述",
+ "Audio Track": "音轨",
+ "You aborted the media playback": "视频播放被终止",
+ "A network error caused the media download to fail part-way.": "网络错误导致视频下载中途失败。",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "视频因格式不支持或者服务器或网络的问题无法加载。",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "由于视频文件损坏或是该视频使用了你的浏览器不支持的功能,播放终止。",
+ "No compatible source was found for this media.": "无法找到此视频兼容的源。",
+ "The media is encrypted and we do not have the keys to decrypt it.": "视频已加密,无法解密。",
+ "Play Video": "播放视频",
+ "Close": "关闭",
+ "Modal Window": "弹窗",
+ "This is a modal window": "这是一个弹窗",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "可以按ESC按键或启用关闭按钮来关闭此弹窗。",
+ ", opens captions settings dialog": ", 开启标题设置弹窗",
+ ", opens subtitles settings dialog": ", 开启字幕设置弹窗",
+ ", opens descriptions settings dialog": ", 开启描述设置弹窗",
+ ", selected": ", 选择",
+ "captions settings": "字幕设定",
+ "Audio Player": "音频播放器",
+ "Video Player": "视频播放器",
+ "Replay": "重新播放",
+ "Progress Bar": "进度条",
+ "Volume Level": "音量",
+ "subtitles settings": "字幕设定",
+ "descriptions settings": "描述设定",
+ "Text": "文字",
+ "White": "白",
+ "Black": "黑",
+ "Red": "红",
+ "Green": "绿",
+ "Blue": "蓝",
+ "Yellow": "黄",
+ "Magenta": "紫红",
+ "Cyan": "青",
+ "Background": "背景",
+ "Window": "窗口",
+ "Transparent": "透明",
+ "Semi-Transparent": "半透明",
+ "Opaque": "不透明",
+ "Font Size": "字体尺寸",
+ "Text Edge Style": "字体边缘样式",
+ "None": "无",
+ "Raised": "浮雕",
+ "Depressed": "压低",
+ "Uniform": "均匀",
+ "Dropshadow": "下阴影",
+ "Font Family": "字体库",
+ "Proportional Sans-Serif": "比例无细体",
+ "Monospace Sans-Serif": "单间隔无细体",
+ "Proportional Serif": "比例细体",
+ "Monospace Serif": "单间隔细体",
+ "Casual": "舒适",
+ "Script": "手写体",
+ "Small Caps": "小型大写字体",
+ "Reset": "重置",
+ "restore all settings to the default values": "恢复全部设定至预设值",
+ "Done": "完成",
+ "Caption Settings Dialog": "字幕设定窗口",
+ "Beginning of dialog window. Escape will cancel and close the window.": "打开对话窗口。Escape键将取消并关闭对话窗口",
+ "End of dialog window.": "结束对话窗口",
+ "Seek to live, currently behind live": "尝试直播,当前为延时播放",
+ "Seek to live, currently playing live": "尝试直播,当前为实时播放",
+ "progress bar timing: currentTime={1} duration={2}": "{1}/{2}",
+ "{1} is loading.": "正在加载 {1}。"
+}
--- /dev/null
+videojs.addLanguage('zh-Hans', {
+ "Play": "播放",
+ "Pause": "暂停",
+ "Current Time": "当前时间",
+ "Duration": "时长",
+ "Remaining Time": "剩余时间",
+ "Stream Type": "媒体流类型",
+ "LIVE": "直播",
+ "Loaded": "加载完成",
+ "Progress": "进度",
+ "Fullscreen": "全屏",
+ "Non-Fullscreen": "退出全屏",
+ "Picture-in-Picture": "画中画",
+ "Exit Picture-in-Picture": "退出画中画",
+ "Mute": "静音",
+ "Unmute": "取消静音",
+ "Playback Rate": "播放速度",
+ "Subtitles": "字幕",
+ "subtitles off": "关闭字幕",
+ "Captions": "内嵌字幕",
+ "captions off": "关闭内嵌字幕",
+ "Chapters": "节目段落",
+ "Close Modal Dialog": "关闭弹窗",
+ "Descriptions": "描述",
+ "descriptions off": "关闭描述",
+ "Audio Track": "音轨",
+ "You aborted the media playback": "视频播放被终止",
+ "A network error caused the media download to fail part-way.": "网络错误导致视频下载中途失败。",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "视频因格式不支持或者服务器或网络的问题无法加载。",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "由于视频文件损坏或是该视频使用了你的浏览器不支持的功能,播放终止。",
+ "No compatible source was found for this media.": "无法找到此视频兼容的源。",
+ "The media is encrypted and we do not have the keys to decrypt it.": "视频已加密,无法解密。",
+ "Play Video": "播放视频",
+ "Close": "关闭",
+ "Modal Window": "弹窗",
+ "This is a modal window": "这是一个弹窗",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "可以按ESC按键或启用关闭按钮来关闭此弹窗。",
+ ", opens captions settings dialog": ", 开启标题设置弹窗",
+ ", opens subtitles settings dialog": ", 开启字幕设置弹窗",
+ ", opens descriptions settings dialog": ", 开启描述设置弹窗",
+ ", selected": ", 选择",
+ "captions settings": "字幕设定",
+ "Audio Player": "音频播放器",
+ "Video Player": "视频播放器",
+ "Replay": "重新播放",
+ "Progress Bar": "进度条",
+ "Volume Level": "音量",
+ "subtitles settings": "字幕设定",
+ "descriptions settings": "描述设定",
+ "Text": "文字",
+ "White": "白",
+ "Black": "黑",
+ "Red": "红",
+ "Green": "绿",
+ "Blue": "蓝",
+ "Yellow": "黄",
+ "Magenta": "紫红",
+ "Cyan": "青",
+ "Background": "背景",
+ "Window": "窗口",
+ "Transparent": "透明",
+ "Semi-Transparent": "半透明",
+ "Opaque": "不透明",
+ "Font Size": "字体尺寸",
+ "Text Edge Style": "字体边缘样式",
+ "None": "无",
+ "Raised": "浮雕",
+ "Depressed": "压低",
+ "Uniform": "均匀",
+ "Dropshadow": "下阴影",
+ "Font Family": "字体库",
+ "Proportional Sans-Serif": "比例无细体",
+ "Monospace Sans-Serif": "单间隔无细体",
+ "Proportional Serif": "比例细体",
+ "Monospace Serif": "单间隔细体",
+ "Casual": "舒适",
+ "Script": "手写体",
+ "Small Caps": "小型大写字体",
+ "Reset": "重置",
+ "restore all settings to the default values": "恢复全部设定至预设值",
+ "Done": "完成",
+ "Caption Settings Dialog": "字幕设定窗口",
+ "Beginning of dialog window. Escape will cancel and close the window.": "打开对话窗口。Escape键将取消并关闭对话窗口",
+ "End of dialog window.": "结束对话窗口",
+ "Seek to live, currently behind live": "尝试直播,当前为延时播放",
+ "Seek to live, currently playing live": "尝试直播,当前为实时播放",
+ "progress bar timing: currentTime={1} duration={2}": "{1}/{2}",
+ "{1} is loading.": "正在加载 {1}。"
+});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "播放",
+ "Pause": "暂停",
+ "Current Time": "当前时间",
+ "Duration": "时长",
+ "Remaining Time": "剩余时间",
+ "Stream Type": "媒体流类型",
+ "LIVE": "直播",
+ "Loaded": "加载完成",
+ "Progress": "进度",
+ "Fullscreen": "全屏",
+ "Non-Fullscreen": "退出全屏",
+ "Picture-in-Picture": "画中画",
+ "Exit Picture-in-Picture": "退出画中画",
+ "Mute": "静音",
+ "Unmute": "取消静音",
+ "Playback Rate": "播放速度",
+ "Subtitles": "字幕",
+ "subtitles off": "关闭字幕",
+ "Captions": "内嵌字幕",
+ "captions off": "关闭内嵌字幕",
+ "Chapters": "节目段落",
+ "Close Modal Dialog": "关闭弹窗",
+ "Descriptions": "描述",
+ "descriptions off": "关闭描述",
+ "Audio Track": "音轨",
+ "You aborted the media playback": "视频播放被终止",
+ "A network error caused the media download to fail part-way.": "网络错误导致视频下载中途失败。",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "视频因格式不支持或者服务器或网络的问题无法加载。",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "由于视频文件损坏或是该视频使用了你的浏览器不支持的功能,播放终止。",
+ "No compatible source was found for this media.": "无法找到此视频兼容的源。",
+ "The media is encrypted and we do not have the keys to decrypt it.": "视频已加密,无法解密。",
+ "Play Video": "播放视频",
+ "Close": "关闭",
+ "Modal Window": "弹窗",
+ "This is a modal window": "这是一个弹窗",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "可以按ESC按键或启用关闭按钮来关闭此弹窗。",
+ ", opens captions settings dialog": ", 开启标题设置弹窗",
+ ", opens subtitles settings dialog": ", 开启字幕设置弹窗",
+ ", opens descriptions settings dialog": ", 开启描述设置弹窗",
+ ", selected": ", 选择",
+ "captions settings": "字幕设定",
+ "Audio Player": "音频播放器",
+ "Video Player": "视频播放器",
+ "Replay": "重新播放",
+ "Progress Bar": "进度条",
+ "Volume Level": "音量",
+ "subtitles settings": "字幕设定",
+ "descriptions settings": "描述设定",
+ "Text": "文字",
+ "White": "白",
+ "Black": "黑",
+ "Red": "红",
+ "Green": "绿",
+ "Blue": "蓝",
+ "Yellow": "黄",
+ "Magenta": "紫红",
+ "Cyan": "青",
+ "Background": "背景",
+ "Window": "窗口",
+ "Transparent": "透明",
+ "Semi-Transparent": "半透明",
+ "Opaque": "不透明",
+ "Font Size": "字体尺寸",
+ "Text Edge Style": "字体边缘样式",
+ "None": "无",
+ "Raised": "浮雕",
+ "Depressed": "压低",
+ "Uniform": "均匀",
+ "Dropshadow": "下阴影",
+ "Font Family": "字体库",
+ "Proportional Sans-Serif": "比例无细体",
+ "Monospace Sans-Serif": "单间隔无细体",
+ "Proportional Serif": "比例细体",
+ "Monospace Serif": "单间隔细体",
+ "Casual": "舒适",
+ "Script": "手写体",
+ "Small Caps": "小型大写字体",
+ "Reset": "重置",
+ "restore all settings to the default values": "恢复全部设定至预设值",
+ "Done": "完成",
+ "Caption Settings Dialog": "字幕设定窗口",
+ "Beginning of dialog window. Escape will cancel and close the window.": "打开对话窗口。Escape键将取消并关闭对话窗口",
+ "End of dialog window.": "结束对话窗口",
+ "Seek to live, currently behind live": "尝试直播,当前为延时播放",
+ "Seek to live, currently playing live": "尝试直播,当前为实时播放",
+ "progress bar timing: currentTime={1} duration={2}": "{1}/{2}",
+ "{1} is loading.": "正在加载 {1}。"
+}
--- /dev/null
+videojs.addLanguage('zh-Hant', {
+ "Play": "播放",
+ "Pause": "暫停",
+ "Current Time": "目前時間",
+ "Duration": "總共時間",
+ "Remaining Time": "剩餘時間",
+ "Stream Type": "串流類型",
+ "LIVE": "直播",
+ "Loaded": "載入完畢",
+ "Progress": "進度",
+ "Fullscreen": "全螢幕",
+ "Non-Fullscreen": "退出全螢幕",
+ "Mute": "靜音",
+ "Unmute": "取消靜音",
+ "Playback Rate": " 播放速率",
+ "Subtitles": "字幕",
+ "subtitles off": "關閉字幕",
+ "Captions": "內嵌字幕",
+ "captions off": "關閉內嵌字幕",
+ "Chapters": "章節",
+ "Close Modal Dialog": "關閉對話框",
+ "Descriptions": "描述",
+ "descriptions off": "關閉描述",
+ "Audio Track": "音軌",
+ "You aborted the media playback": "影片播放已終止",
+ "A network error caused the media download to fail part-way.": "網路錯誤導致影片下載失敗。",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "影片因格式不支援或者伺服器或網路的問題無法載入。",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "由於影片檔案損毀或是該影片使用了您的瀏覽器不支援的功能,播放終止。",
+ "No compatible source was found for this media.": "無法找到相容此影片的來源。",
+ "The media is encrypted and we do not have the keys to decrypt it.": "影片已加密,無法解密。",
+ "Play Video": "播放影片",
+ "Close": "關閉",
+ "Modal Window": "對話框",
+ "This is a modal window": "這是一個對話框",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "可以按ESC按鍵或啟用關閉按鈕來關閉此對話框。",
+ ", opens captions settings dialog": ", 開啟標題設定對話框",
+ ", opens subtitles settings dialog": ", 開啟字幕設定對話框",
+ ", opens descriptions settings dialog": ", 開啟描述設定對話框",
+ ", selected": ", 選擇",
+ "captions settings": "字幕設定",
+ "Audio Player": "音頻播放器",
+ "Video Player": "視頻播放器",
+ "Replay": "重播",
+ "Progress Bar": "進度小節",
+ "Volume Level": "音量",
+ "subtitles settings": "字幕設定",
+ "descriptions settings": "描述設定",
+ "Text": "文字",
+ "White": "白",
+ "Black": "黑",
+ "Red": "紅",
+ "Green": "綠",
+ "Blue": "藍",
+ "Yellow": "黃",
+ "Magenta": "紫紅",
+ "Cyan": "青",
+ "Background": "背景",
+ "Window": "視窗",
+ "Transparent": "透明",
+ "Semi-Transparent": "半透明",
+ "Opaque": "不透明",
+ "Font Size": "字型尺寸",
+ "Text Edge Style": "字型邊緣樣式",
+ "None": "無",
+ "Raised": "浮雕",
+ "Depressed": "壓低",
+ "Uniform": "均勻",
+ "Dropshadow": "下陰影",
+ "Font Family": "字型庫",
+ "Proportional Sans-Serif": "比例無細體",
+ "Monospace Sans-Serif": "單間隔無細體",
+ "Proportional Serif": "比例細體",
+ "Monospace Serif": "單間隔細體",
+ "Casual": "輕便的",
+ "Script": "手寫體",
+ "Small Caps": "小型大寫字體",
+ "Reset": "重置",
+ "restore all settings to the default values": "恢復全部設定至預設值",
+ "Done": "完成",
+ "Caption Settings Dialog": "字幕設定視窗",
+ "Beginning of dialog window. Escape will cancel and close the window.": "開始對話視窗。離開會取消及關閉視窗",
+ "End of dialog window.": "結束對話視窗",
+ "Seek to live, currently behind live": "試圖直播,目前延時播放",
+ "Seek to live, currently playing live": "試圖直播,目前即時播放",
+ "progress bar timing: currentTime={1} duration={2}": "{1}/{2}",
+ "{1} is loading.": "{1} 正在載入。"
+});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "播放",
+ "Pause": "暫停",
+ "Current Time": "目前時間",
+ "Duration": "總共時間",
+ "Remaining Time": "剩餘時間",
+ "Stream Type": "串流類型",
+ "LIVE": "直播",
+ "Loaded": "載入完畢",
+ "Progress": "進度",
+ "Fullscreen": "全螢幕",
+ "Non-Fullscreen": "退出全螢幕",
+ "Mute": "靜音",
+ "Unmute": "取消靜音",
+ "Playback Rate": " 播放速率",
+ "Subtitles": "字幕",
+ "subtitles off": "關閉字幕",
+ "Captions": "內嵌字幕",
+ "captions off": "關閉內嵌字幕",
+ "Chapters": "章節",
+ "Close Modal Dialog": "關閉對話框",
+ "Descriptions": "描述",
+ "descriptions off": "關閉描述",
+ "Audio Track": "音軌",
+ "You aborted the media playback": "影片播放已終止",
+ "A network error caused the media download to fail part-way.": "網路錯誤導致影片下載失敗。",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "影片因格式不支援或者伺服器或網路的問題無法載入。",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "由於影片檔案損毀或是該影片使用了您的瀏覽器不支援的功能,播放終止。",
+ "No compatible source was found for this media.": "無法找到相容此影片的來源。",
+ "The media is encrypted and we do not have the keys to decrypt it.": "影片已加密,無法解密。",
+ "Play Video": "播放影片",
+ "Close": "關閉",
+ "Modal Window": "對話框",
+ "This is a modal window": "這是一個對話框",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "可以按ESC按鍵或啟用關閉按鈕來關閉此對話框。",
+ ", opens captions settings dialog": ", 開啟標題設定對話框",
+ ", opens subtitles settings dialog": ", 開啟字幕設定對話框",
+ ", opens descriptions settings dialog": ", 開啟描述設定對話框",
+ ", selected": ", 選擇",
+ "captions settings": "字幕設定",
+ "Audio Player": "音頻播放器",
+ "Video Player": "視頻播放器",
+ "Replay": "重播",
+ "Progress Bar": "進度小節",
+ "Volume Level": "音量",
+ "subtitles settings": "字幕設定",
+ "descriptions settings": "描述設定",
+ "Text": "文字",
+ "White": "白",
+ "Black": "黑",
+ "Red": "紅",
+ "Green": "綠",
+ "Blue": "藍",
+ "Yellow": "黃",
+ "Magenta": "紫紅",
+ "Cyan": "青",
+ "Background": "背景",
+ "Window": "視窗",
+ "Transparent": "透明",
+ "Semi-Transparent": "半透明",
+ "Opaque": "不透明",
+ "Font Size": "字型尺寸",
+ "Text Edge Style": "字型邊緣樣式",
+ "None": "無",
+ "Raised": "浮雕",
+ "Depressed": "壓低",
+ "Uniform": "均勻",
+ "Dropshadow": "下陰影",
+ "Font Family": "字型庫",
+ "Proportional Sans-Serif": "比例無細體",
+ "Monospace Sans-Serif": "單間隔無細體",
+ "Proportional Serif": "比例細體",
+ "Monospace Serif": "單間隔細體",
+ "Casual": "輕便的",
+ "Script": "手寫體",
+ "Small Caps": "小型大寫字體",
+ "Reset": "重置",
+ "restore all settings to the default values": "恢復全部設定至預設值",
+ "Done": "完成",
+ "Caption Settings Dialog": "字幕設定視窗",
+ "Beginning of dialog window. Escape will cancel and close the window.": "開始對話視窗。離開會取消及關閉視窗",
+ "End of dialog window.": "結束對話視窗",
+ "Seek to live, currently behind live": "試圖直播,目前延時播放",
+ "Seek to live, currently playing live": "試圖直播,目前即時播放",
+ "progress bar timing: currentTime={1} duration={2}": "{1}/{2}",
+ "{1} is loading.": "{1} 正在載入。"
+}
-videojs.addLanguage("zh-TW",{
- "Play": "播放",
- "Pause": "暫停",
- "Current Time": "目前時間",
- "Duration Time": "總共時間",
- "Remaining Time": "剩餘時間",
- "Stream Type": "串流類型",
- "LIVE": "直播",
- "Loaded": "載入完畢",
- "Progress": "進度",
- "Fullscreen": "全螢幕",
- "Non-Fullscreen": "退出全螢幕",
- "Mute": "靜音",
- "Unmute": "取消靜音",
- "Playback Rate": " 播放速率",
- "Subtitles": "字幕",
- "subtitles off": "關閉字幕",
- "Captions": "內嵌字幕",
- "captions off": "關閉內嵌字幕",
- "Chapters": "章節",
- "Close Modal Dialog": "關閉對話框",
- "Descriptions": "描述",
- "descriptions off": "關閉描述",
- "Audio Track": "音軌",
- "You aborted the media playback": "影片播放已終止",
- "A network error caused the media download to fail part-way.": "網路錯誤導致影片下載失敗。",
- "The media could not be loaded, either because the server or network failed or because the format is not supported.": "影片因格式不支援或者伺服器或網路的問題無法載入。",
- "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "由於影片檔案損毀或是該影片使用了您的瀏覽器不支援的功能,播放終止。",
- "No compatible source was found for this media.": "無法找到相容此影片的來源。",
- "The media is encrypted and we do not have the keys to decrypt it.": "影片已加密,無法解密。",
- "Play Video": "播放影片",
- "Close": "關閉",
- "Modal Window": "對話框",
- "This is a modal window": "這是一個對話框",
- "This modal can be closed by pressing the Escape key or activating the close button.": "可以按ESC按鍵或啟用關閉按鈕來關閉此對話框。",
- ", opens captions settings dialog": ", 開啟標題設定對話框",
- ", opens subtitles settings dialog": ", 開啟字幕設定對話框",
- ", opens descriptions settings dialog": ", 開啟描述設定對話框",
- ", selected": ", 選擇"
+videojs.addLanguage('zh-TW', {
+ "Play": "播放",
+ "Pause": "暫停",
+ "Current Time": "目前時間",
+ "Duration": "總共時間",
+ "Remaining Time": "剩餘時間",
+ "Stream Type": "串流類型",
+ "LIVE": "直播",
+ "Loaded": "載入完畢",
+ "Progress": "進度",
+ "Fullscreen": "全螢幕",
+ "Non-Fullscreen": "退出全螢幕",
+ "Mute": "靜音",
+ "Unmute": "取消靜音",
+ "Playback Rate": " 播放速率",
+ "Subtitles": "字幕",
+ "subtitles off": "關閉字幕",
+ "Captions": "內嵌字幕",
+ "captions off": "關閉內嵌字幕",
+ "Chapters": "章節",
+ "Close Modal Dialog": "關閉對話框",
+ "Descriptions": "描述",
+ "descriptions off": "關閉描述",
+ "Audio Track": "音軌",
+ "You aborted the media playback": "影片播放已終止",
+ "A network error caused the media download to fail part-way.": "網路錯誤導致影片下載失敗。",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "影片因格式不支援或者伺服器或網路的問題無法載入。",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "由於影片檔案損毀或是該影片使用了您的瀏覽器不支援的功能,播放終止。",
+ "No compatible source was found for this media.": "無法找到相容此影片的來源。",
+ "The media is encrypted and we do not have the keys to decrypt it.": "影片已加密,無法解密。",
+ "Play Video": "播放影片",
+ "Close": "關閉",
+ "Modal Window": "對話框",
+ "This is a modal window": "這是一個對話框",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "可以按ESC按鍵或啟用關閉按鈕來關閉此對話框。",
+ ", opens captions settings dialog": ", 開啟標題設定對話框",
+ ", opens subtitles settings dialog": ", 開啟字幕設定對話框",
+ ", opens descriptions settings dialog": ", 開啟描述設定對話框",
+ ", selected": ", 選擇",
+ "captions settings": "字幕設定",
+ "Audio Player": "音頻播放器",
+ "Video Player": "視頻播放器",
+ "Replay": "重播",
+ "Progress Bar": "進度小節",
+ "Volume Level": "音量",
+ "subtitles settings": "字幕設定",
+ "descriptions settings": "描述設定",
+ "Text": "文字",
+ "White": "白",
+ "Black": "黑",
+ "Red": "紅",
+ "Green": "綠",
+ "Blue": "藍",
+ "Yellow": "黃",
+ "Magenta": "紫紅",
+ "Cyan": "青",
+ "Background": "背景",
+ "Window": "視窗",
+ "Transparent": "透明",
+ "Semi-Transparent": "半透明",
+ "Opaque": "不透明",
+ "Font Size": "字型尺寸",
+ "Text Edge Style": "字型邊緣樣式",
+ "None": "無",
+ "Raised": "浮雕",
+ "Depressed": "壓低",
+ "Uniform": "均勻",
+ "Dropshadow": "下陰影",
+ "Font Family": "字型庫",
+ "Proportional Sans-Serif": "比例無細體",
+ "Monospace Sans-Serif": "單間隔無細體",
+ "Proportional Serif": "比例細體",
+ "Monospace Serif": "單間隔細體",
+ "Casual": "輕便的",
+ "Script": "手寫體",
+ "Small Caps": "小型大寫字體",
+ "Reset": "重置",
+ "restore all settings to the default values": "恢復全部設定至預設值",
+ "Done": "完成",
+ "Caption Settings Dialog": "字幕設定視窗",
+ "Beginning of dialog window. Escape will cancel and close the window.": "開始對話視窗。離開會取消及關閉視窗",
+ "End of dialog window.": "結束對話視窗",
+ "Seek to live, currently behind live": "試圖直播,目前延時播放",
+ "Seek to live, currently playing live": "試圖直播,目前即時播放",
+ "progress bar timing: currentTime={1} duration={2}": "{1}/{2}",
+ "{1} is loading.": "{1} 正在載入。"
});
\ No newline at end of file
--- /dev/null
+{
+ "Play": "播放",
+ "Pause": "暫停",
+ "Current Time": "目前時間",
+ "Duration": "總共時間",
+ "Remaining Time": "剩餘時間",
+ "Stream Type": "串流類型",
+ "LIVE": "直播",
+ "Loaded": "載入完畢",
+ "Progress": "進度",
+ "Fullscreen": "全螢幕",
+ "Non-Fullscreen": "退出全螢幕",
+ "Mute": "靜音",
+ "Unmute": "取消靜音",
+ "Playback Rate": " 播放速率",
+ "Subtitles": "字幕",
+ "subtitles off": "關閉字幕",
+ "Captions": "內嵌字幕",
+ "captions off": "關閉內嵌字幕",
+ "Chapters": "章節",
+ "Close Modal Dialog": "關閉對話框",
+ "Descriptions": "描述",
+ "descriptions off": "關閉描述",
+ "Audio Track": "音軌",
+ "You aborted the media playback": "影片播放已終止",
+ "A network error caused the media download to fail part-way.": "網路錯誤導致影片下載失敗。",
+ "The media could not be loaded, either because the server or network failed or because the format is not supported.": "影片因格式不支援或者伺服器或網路的問題無法載入。",
+ "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "由於影片檔案損毀或是該影片使用了您的瀏覽器不支援的功能,播放終止。",
+ "No compatible source was found for this media.": "無法找到相容此影片的來源。",
+ "The media is encrypted and we do not have the keys to decrypt it.": "影片已加密,無法解密。",
+ "Play Video": "播放影片",
+ "Close": "關閉",
+ "Modal Window": "對話框",
+ "This is a modal window": "這是一個對話框",
+ "This modal can be closed by pressing the Escape key or activating the close button.": "可以按ESC按鍵或啟用關閉按鈕來關閉此對話框。",
+ ", opens captions settings dialog": ", 開啟標題設定對話框",
+ ", opens subtitles settings dialog": ", 開啟字幕設定對話框",
+ ", opens descriptions settings dialog": ", 開啟描述設定對話框",
+ ", selected": ", 選擇",
+ "captions settings": "字幕設定",
+ "Audio Player": "音頻播放器",
+ "Video Player": "視頻播放器",
+ "Replay": "重播",
+ "Progress Bar": "進度小節",
+ "Volume Level": "音量",
+ "subtitles settings": "字幕設定",
+ "descriptions settings": "描述設定",
+ "Text": "文字",
+ "White": "白",
+ "Black": "黑",
+ "Red": "紅",
+ "Green": "綠",
+ "Blue": "藍",
+ "Yellow": "黃",
+ "Magenta": "紫紅",
+ "Cyan": "青",
+ "Background": "背景",
+ "Window": "視窗",
+ "Transparent": "透明",
+ "Semi-Transparent": "半透明",
+ "Opaque": "不透明",
+ "Font Size": "字型尺寸",
+ "Text Edge Style": "字型邊緣樣式",
+ "None": "無",
+ "Raised": "浮雕",
+ "Depressed": "壓低",
+ "Uniform": "均勻",
+ "Dropshadow": "下陰影",
+ "Font Family": "字型庫",
+ "Proportional Sans-Serif": "比例無細體",
+ "Monospace Sans-Serif": "單間隔無細體",
+ "Proportional Serif": "比例細體",
+ "Monospace Serif": "單間隔細體",
+ "Casual": "輕便的",
+ "Script": "手寫體",
+ "Small Caps": "小型大寫字體",
+ "Reset": "重置",
+ "restore all settings to the default values": "恢復全部設定至預設值",
+ "Done": "完成",
+ "Caption Settings Dialog": "字幕設定視窗",
+ "Beginning of dialog window. Escape will cancel and close the window.": "開始對話視窗。離開會取消及關閉視窗",
+ "End of dialog window.": "結束對話視窗",
+ "Seek to live, currently behind live": "試圖直播,目前延時播放",
+ "Seek to live, currently playing live": "試圖直播,目前即時播放",
+ "progress bar timing: currentTime={1} duration={2}": "{1}/{2}",
+ "{1} is loading.": "{1} 正在載入。"
+}
--- /dev/null
+/**
+ * @license
+ * Video.js 7.15.4 <http://videojs.com/>
+ * Copyright Brightcove, Inc. <https://www.brightcove.com/>
+ * Available under Apache License Version 2.0
+ * <https://github.com/videojs/video.js/blob/main/LICENSE>
+ *
+ * Includes vtt.js <https://github.com/mozilla/vtt.js>
+ * Available under Apache License Version 2.0
+ * <https://github.com/mozilla/vtt.js/blob/main/LICENSE>
+ */
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).videojs=t()}(this,function(){"use strict";var u="7.15.4",e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function t(e,t){return e(t={exports:{}},t.exports),t.exports}for(var i,_="undefined"!=typeof window?window:"undefined"!=typeof e?e:"undefined"!=typeof self?self:{},n={},a=function(e,t){return n[e]=n[e]||[],t&&(n[e]=n[e].concat(t)),n[e]},r=function(e,t){t=a(e).indexOf(t);return!(t<=-1)&&(n[e]=n[e].slice(),n[e].splice(t,1),!0)},s="undefined"!=typeof e?e:"undefined"!=typeof window?window:{},o="undefined"!=typeof document?document:(o=s["__GLOBAL_DOCUMENT_CACHE@4"])||(s["__GLOBAL_DOCUMENT_CACHE@4"]={}),d=o,l={prefixed:!0},c=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror","fullscreen"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror","-webkit-full-screen"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror","-moz-full-screen"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError","-ms-fullscreen"]],h=c[0],p=0;p<c.length;p++)if(c[p][1]in d){i=c[p];break}if(i){for(var f=0;f<i.length;f++)l[h[f]]=i[f];l.prefixed=i[0]!==h[0]}var m=[],g=function(a,s){return function(e,t,i){var n,r=s.levels[t],t=new RegExp("^("+r+")$");"log"!==e&&i.unshift(e.toUpperCase()+":"),i.unshift(a+":"),m&&(m.push([].concat(i)),n=m.length-1e3,m.splice(0,0<n?n:0)),!_.console||(n=!(n=_.console[e])&&"debug"===e?_.console.info||_.console.log:n)&&r&&t.test(e)&&n[Array.isArray(i)?"apply":"call"](_.console,i)}};var y=function t(i){function n(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];a("log",r,t)}var r="info",a=g(i,n);return n.createLogger=function(e){return t(i+": "+e)},n.levels={all:"debug|log|warn|error",off:"",debug:"debug|log|warn|error",info:"log|warn|error",warn:"warn|error",error:"error",DEFAULT:r},n.level=function(e){if("string"==typeof e){if(!n.levels.hasOwnProperty(e))throw new Error('"'+e+'" in not a valid log level');r=e}return r},(n.history=function(){return m?[].concat(m):[]}).filter=function(t){return(m||[]).filter(function(e){return new RegExp(".*"+t+".*").test(e[0])})},n.history.clear=function(){m&&(m.length=0)},n.history.disable=function(){null!==m&&(m.length=0,m=null)},n.history.enable=function(){null===m&&(m=[])},n.error=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return a("error",r,t)},n.warn=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return a("warn",r,t)},n.debug=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return a("debug",r,t)},n}("VIDEOJS"),v=y.createLogger,b=t(function(e){function t(){return e.exports=t=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var i,n=arguments[t];for(i in n)Object.prototype.hasOwnProperty.call(n,i)&&(e[i]=n[i])}return e},t.apply(this,arguments)}e.exports=t}),T=Object.prototype.toString,S=function(e){return C(e)?Object.keys(e):[]};function E(t,i){S(t).forEach(function(e){return i(t[e],e)})}function k(i){for(var e=arguments.length,t=new Array(1<e?e-1:0),n=1;n<e;n++)t[n-1]=arguments[n];return Object.assign?b.apply(void 0,[i].concat(t)):(t.forEach(function(e){e&&E(e,function(e,t){i[t]=e})}),i)}function C(e){return!!e&&"object"==typeof e}function w(e){return C(e)&&"[object Object]"===T.call(e)&&e.constructor===Object}function I(e,t){if(!e||!t)return"";if("function"!=typeof _.getComputedStyle)return"";var i;try{i=_.getComputedStyle(e)}catch(e){return""}return i?i.getPropertyValue(t)||i[t]:""}var x=_.navigator&&_.navigator.userAgent||"",A=/AppleWebKit\/([\d.]+)/i.exec(x),P=A?parseFloat(A.pop()):null,L=/iPod/i.test(x),D=(Kt=x.match(/OS (\d+)_/i))&&Kt[1]?Kt[1]:null,O=/Android/i.test(x),R=function(){var e=x.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);if(!e)return null;var t=e[1]&&parseFloat(e[1]),i=e[2]&&parseFloat(e[2]);return t&&i?parseFloat(e[1]+"."+e[2]):t||null}(),M=O&&R<5&&P<537,N=/Firefox/i.test(x),U=/Edg/i.test(x),B=!U&&(/Chrome/i.test(x)||/CriOS/i.test(x)),F=(ai=x.match(/(Chrome|CriOS)\/(\d+)/))&&ai[2]?parseFloat(ai[2]):null,j=si=!(si=(si=/MSIE\s(\d+)\.\d/.exec(x))&&parseFloat(si[1]))&&/Trident\/7.0/i.test(x)&&/rv:11.0/.test(x)?11:si,H=/Safari/i.test(x)&&!B&&!O&&!U,q=/Windows/i.test(x),V=Boolean($()&&("ontouchstart"in _||_.navigator.maxTouchPoints||_.DocumentTouch&&_.document instanceof _.DocumentTouch)),W=/iPad/i.test(x)||H&&V&&!/iPhone/i.test(x),z=/iPhone/i.test(x)&&!W,G=z||W||L,X=(H||G)&&!B,K=Object.freeze({__proto__:null,IS_IPOD:L,IOS_VERSION:D,IS_ANDROID:O,ANDROID_VERSION:R,IS_NATIVE_ANDROID:M,IS_FIREFOX:N,IS_EDGE:U,IS_CHROME:B,CHROME_VERSION:F,IE_VERSION:j,IS_SAFARI:H,IS_WINDOWS:q,TOUCH_ENABLED:V,IS_IPAD:W,IS_IPHONE:z,IS_IOS:G,IS_ANY_SAFARI:X});function Y(e){return"string"==typeof e&&Boolean(e.trim())}function Q(e){if(0<=e.indexOf(" "))throw new Error("class has illegal whitespace characters")}function $(){return d===_.document}function J(e){return C(e)&&1===e.nodeType}function Z(){try{return _.parent!==_.self}catch(e){return!0}}function ee(i){return function(e,t){if(!Y(e))return d[i](null);t=J(t=Y(t)?d.querySelector(t):t)?t:d;return t[i]&&t[i](e)}}function te(e,i,t,n){void 0===i&&(i={}),void 0===t&&(t={});var r=d.createElement(e=void 0===e?"div":e);return Object.getOwnPropertyNames(i).forEach(function(e){var t=i[e];-1!==e.indexOf("aria-")||"role"===e||"type"===e?(y.warn("Setting attributes in the second argument of createEl()\nhas been deprecated. Use the third argument instead.\ncreateEl(type, properties, attributes). Attempting to set "+e+" to "+t+"."),r.setAttribute(e,t)):"textContent"===e?ie(r,t):r[e]===t&&"tabIndex"!==e||(r[e]=t)}),Object.getOwnPropertyNames(t).forEach(function(e){r.setAttribute(e,t[e])}),n&&Te(r,n),r}function ie(e,t){return"undefined"==typeof e.textContent?e.innerText=t:e.textContent=t,e}function ne(e,t){t.firstChild?t.insertBefore(e,t.firstChild):t.appendChild(e)}function re(e,t){return Q(t),e.classList?e.classList.contains(t):new RegExp("(^|\\s)"+t+"($|\\s)").test(e.className)}function ae(e,t){return e.classList?e.classList.add(t):re(e,t)||(e.className=(e.className+" "+t).trim()),e}function se(e,t){return e?(e.classList?e.classList.remove(t):(Q(t),e.className=e.className.split(/\s+/).filter(function(e){return e!==t}).join(" ")),e):(y.warn("removeClass was called with an element that doesn't exist"),null)}function oe(e,t,i){var n=re(e,t);if((i="boolean"!=typeof(i="function"==typeof i?i(e,t):i)?!n:i)!==n)return(i?ae:se)(e,t),e}function ue(i,n){Object.getOwnPropertyNames(n).forEach(function(e){var t=n[e];null===t||"undefined"==typeof t||!1===t?i.removeAttribute(e):i.setAttribute(e,!0===t?"":t)})}function le(e){var t={},i=",autoplay,controls,playsinline,loop,muted,default,defaultMuted,";if(e&&e.attributes&&0<e.attributes.length)for(var n=e.attributes,r=n.length-1;0<=r;r--){var a=n[r].name,s=n[r].value;"boolean"!=typeof e[a]&&-1===i.indexOf(","+a+",")||(s=null!==s),t[a]=s}return t}function ce(e,t){return e.getAttribute(t)}function de(e,t,i){e.setAttribute(t,i)}function he(e,t){e.removeAttribute(t)}function pe(){d.body.focus(),d.onselectstart=function(){return!1}}function fe(){d.onselectstart=function(){return!0}}function me(e){if(e&&e.getBoundingClientRect&&e.parentNode){var t=e.getBoundingClientRect(),i={};return["bottom","height","left","right","top","width"].forEach(function(e){void 0!==t[e]&&(i[e]=t[e])}),i.height||(i.height=parseFloat(I(e,"height"))),i.width||(i.width=parseFloat(I(e,"width"))),i}}function ge(e){if(!e||e&&!e.offsetParent)return{left:0,top:0,width:0,height:0};for(var t=e.offsetWidth,i=e.offsetHeight,n=0,r=0;e.offsetParent&&e!==d[l.fullscreenElement];)n+=e.offsetLeft,r+=e.offsetTop,e=e.offsetParent;return{left:n,top:r,width:t,height:i}}function ye(e,t){var i={x:0,y:0};if(G)for(var n=e;n&&"html"!==n.nodeName.toLowerCase();){var r,a=I(n,"transform");/^matrix/.test(a)?(r=a.slice(7,-1).split(/,\s/).map(Number),i.x+=r[4],i.y+=r[5]):/^matrix3d/.test(a)&&(a=a.slice(9,-1).split(/,\s/).map(Number),i.x+=a[12],i.y+=a[13]),n=n.parentNode}var s={},o=ge(t.target),u=ge(e),l=u.width,c=u.height,e=t.offsetY-(u.top-o.top),o=t.offsetX-(u.left-o.left);return t.changedTouches&&(o=t.changedTouches[0].pageX-u.left,e=t.changedTouches[0].pageY+u.top,G&&(o-=i.x,e-=i.y)),s.y=1-Math.max(0,Math.min(1,e/c)),s.x=Math.max(0,Math.min(1,o/l)),s}function ve(e){return C(e)&&3===e.nodeType}function _e(e){for(;e.firstChild;)e.removeChild(e.firstChild);return e}function be(e){return"function"==typeof e&&(e=e()),(Array.isArray(e)?e:[e]).map(function(e){return J(e="function"==typeof e?e():e)||ve(e)?e:"string"==typeof e&&/\S/.test(e)?d.createTextNode(e):void 0}).filter(function(e){return e})}function Te(t,e){return be(e).forEach(function(e){return t.appendChild(e)}),t}function Se(e,t){return Te(_e(e),t)}function Ee(e){return void 0===e.button&&void 0===e.buttons||(0===e.button&&void 0===e.buttons||("mouseup"===e.type&&0===e.button&&0===e.buttons||0===e.button&&1===e.buttons))}var ke,Ce=ee("querySelector"),we=ee("querySelectorAll"),Ie=Object.freeze({__proto__:null,isReal:$,isEl:J,isInFrame:Z,createEl:te,textContent:ie,prependTo:ne,hasClass:re,addClass:ae,removeClass:se,toggleClass:oe,setAttributes:ue,getAttributes:le,getAttribute:ce,setAttribute:de,removeAttribute:he,blockTextSelection:pe,unblockTextSelection:fe,getBoundingClientRect:me,findPosition:ge,getPointerPosition:ye,isTextNode:ve,emptyEl:_e,normalizeContent:be,appendContent:Te,insertContent:Se,isSingleLeftClick:Ee,$:Ce,$$:we}),xe=!1,Ae=function(){if(!1!==ke.options.autoSetup){var e=Array.prototype.slice.call(d.getElementsByTagName("video")),t=Array.prototype.slice.call(d.getElementsByTagName("audio")),i=Array.prototype.slice.call(d.getElementsByTagName("video-js")),n=e.concat(t,i);if(n&&0<n.length)for(var r=0,a=n.length;r<a;r++){var s=n[r];if(!s||!s.getAttribute){Pe(1);break}void 0===s.player&&null!==s.getAttribute("data-setup")&&ke(s)}else xe||Pe(1)}};function Pe(e,t){$()&&(t&&(ke=t),_.setTimeout(Ae,e))}function Le(){xe=!0,_.removeEventListener("load",Le)}$()&&("complete"===d.readyState?Le():_.addEventListener("load",Le));function De(e){var t=d.createElement("style");return t.className=e,t}function Oe(e,t){e.styleSheet?e.styleSheet.cssText=t:e.textContent=t}var Re=3;_.WeakMap||(on=function(){function e(){this.vdata="vdata"+Math.floor(_.performance&&_.performance.now()||Date.now()),this.data={}}var t=e.prototype;return t.set=function(e,t){var i=e[this.vdata]||Re++;return e[this.vdata]||(e[this.vdata]=i),this.data[i]=t,this},t.get=function(e){var t=e[this.vdata];if(t)return this.data[t];y("We have no data for this element",e)},t.has=function(e){return e[this.vdata]in this.data},t.delete=function(e){var t=e[this.vdata];t&&(delete this.data[t],delete e[this.vdata])},e}());var Me,Ne=new(_.WeakMap?WeakMap:on);function Ue(e,t){var i;Ne.has(e)&&(0===(i=Ne.get(e)).handlers[t].length&&(delete i.handlers[t],e.removeEventListener?e.removeEventListener(t,i.dispatcher,!1):e.detachEvent&&e.detachEvent("on"+t,i.dispatcher)),Object.getOwnPropertyNames(i.handlers).length<=0&&(delete i.handlers,delete i.dispatcher,delete i.disabled),0===Object.getOwnPropertyNames(i).length&&Ne.delete(e))}function Be(t,i,e,n){e.forEach(function(e){t(i,e,n)})}function Fe(e){if(e.fixed_)return e;function t(){return!0}function i(){return!1}if(!e||!e.isPropagationStopped||!e.isImmediatePropagationStopped){var n,r,a,s=e||_.event;for(n in e={},s)"layerX"!==n&&"layerY"!==n&&"keyLocation"!==n&&"webkitMovementX"!==n&&"webkitMovementY"!==n&&("returnValue"===n&&s.preventDefault||(e[n]=s[n]));e.target||(e.target=e.srcElement||d),e.relatedTarget||(e.relatedTarget=e.fromElement===e.target?e.toElement:e.fromElement),e.preventDefault=function(){s.preventDefault&&s.preventDefault(),e.returnValue=!1,s.returnValue=!1,e.defaultPrevented=!0},e.defaultPrevented=!1,e.stopPropagation=function(){s.stopPropagation&&s.stopPropagation(),e.cancelBubble=!0,s.cancelBubble=!0,e.isPropagationStopped=t},e.isPropagationStopped=i,e.stopImmediatePropagation=function(){s.stopImmediatePropagation&&s.stopImmediatePropagation(),e.isImmediatePropagationStopped=t,e.stopPropagation()},e.isImmediatePropagationStopped=i,null!==e.clientX&&void 0!==e.clientX&&(r=d.documentElement,a=d.body,e.pageX=e.clientX+(r&&r.scrollLeft||a&&a.scrollLeft||0)-(r&&r.clientLeft||a&&a.clientLeft||0),e.pageY=e.clientY+(r&&r.scrollTop||a&&a.scrollTop||0)-(r&&r.clientTop||a&&a.clientTop||0)),e.which=e.charCode||e.keyCode,null!==e.button&&void 0!==e.button&&(e.button=1&e.button?0:4&e.button?1:2&e.button?2:0)}return e.fixed_=!0,e}var je=function(){if("boolean"!=typeof Me){Me=!1;try{var e=Object.defineProperty({},"passive",{get:function(){Me=!0}});_.addEventListener("test",null,e),_.removeEventListener("test",null,e)}catch(e){}}return Me},He=["touchstart","touchmove"];function qe(s,e,t){if(Array.isArray(e))return Be(qe,s,e,t);Ne.has(s)||Ne.set(s,{});var o=Ne.get(s);o.handlers||(o.handlers={}),o.handlers[e]||(o.handlers[e]=[]),t.guid||(t.guid=Re++),o.handlers[e].push(t),o.dispatcher||(o.disabled=!1,o.dispatcher=function(e,t){if(!o.disabled){e=Fe(e);var i=o.handlers[e.type];if(i)for(var n=i.slice(0),r=0,a=n.length;r<a&&!e.isImmediatePropagationStopped();r++)try{n[r].call(s,e,t)}catch(e){y.error(e)}}}),1===o.handlers[e].length&&(s.addEventListener?(t=!1,je()&&-1<He.indexOf(e)&&(t={passive:!0}),s.addEventListener(e,o.dispatcher,t)):s.attachEvent&&s.attachEvent("on"+e,o.dispatcher))}function Ve(e,t,i){if(Ne.has(e)){var n=Ne.get(e);if(n.handlers){if(Array.isArray(t))return Be(Ve,e,t,i);var r=function(e,t){n.handlers[t]=[],Ue(e,t)};if(void 0!==t){var a=n.handlers[t];if(a)if(i){if(i.guid)for(var s=0;s<a.length;s++)a[s].guid===i.guid&&a.splice(s--,1);Ue(e,t)}else r(e,t)}else for(var o in n.handlers)Object.prototype.hasOwnProperty.call(n.handlers||{},o)&&r(e,o)}}}function We(e,t,i){var n=Ne.has(e)?Ne.get(e):{},r=e.parentNode||e.ownerDocument;return"string"==typeof t?t={type:t,target:e}:t.target||(t.target=e),t=Fe(t),n.dispatcher&&n.dispatcher.call(e,t,i),r&&!t.isPropagationStopped()&&!0===t.bubbles?We.call(null,r,t,i):!r&&!t.defaultPrevented&&t.target&&t.target[t.type]&&(Ne.has(t.target)||Ne.set(t.target,{}),r=Ne.get(t.target),t.target[t.type]&&(r.disabled=!0,"function"==typeof t.target[t.type]&&t.target[t.type](),r.disabled=!1)),!t.defaultPrevented}function ze(e,t,i){if(Array.isArray(t))return Be(ze,e,t,i);function n(){Ve(e,t,n),i.apply(this,arguments)}n.guid=i.guid=i.guid||Re++,qe(e,t,n)}function Ge(e,t,i){function n(){Ve(e,t,n),i.apply(this,arguments)}n.guid=i.guid=i.guid||Re++,qe(e,t,n)}function Xe(e,t,i){return t.guid||(t.guid=Re++),(e=t.bind(e)).guid=i?i+"_"+t.guid:t.guid,e}function Ke(t,i){var n=_.performance.now();return function(){var e=_.performance.now();i<=e-n&&(t.apply(void 0,arguments),n=e)}}function Ye(n,r,a,s){var o;function e(){var e=this,t=arguments,i=function(){i=o=null,a||n.apply(e,t)};!o&&a&&n.apply(e,t),s.clearTimeout(o),o=s.setTimeout(i,r)}return void 0===s&&(s=_),e.cancel=function(){s.clearTimeout(o),o=null},e}function Qe(){}var $e,Je=Object.freeze({__proto__:null,fixEvent:Fe,on:qe,off:Ve,trigger:We,one:ze,any:Ge});Qe.prototype.allowedEvents_={},Qe.prototype.addEventListener=Qe.prototype.on=function(e,t){var i=this.addEventListener;this.addEventListener=function(){},qe(this,e,t),this.addEventListener=i},Qe.prototype.removeEventListener=Qe.prototype.off=function(e,t){Ve(this,e,t)},Qe.prototype.one=function(e,t){var i=this.addEventListener;this.addEventListener=function(){},ze(this,e,t),this.addEventListener=i},Qe.prototype.any=function(e,t){var i=this.addEventListener;this.addEventListener=function(){},Ge(this,e,t),this.addEventListener=i},Qe.prototype.dispatchEvent=Qe.prototype.trigger=function(e){var t=e.type||e;e=Fe(e="string"==typeof e?{type:t}:e),this.allowedEvents_[t]&&this["on"+t]&&this["on"+t](e),We(this,e)},Qe.prototype.queueTrigger=function(e){var t=this;$e=$e||new Map;var i=e.type||e,n=$e.get(this);n||(n=new Map,$e.set(this,n));var r=n.get(i);n.delete(i),_.clearTimeout(r);r=_.setTimeout(function(){0===n.size&&(n=null,$e.delete(t)),t.trigger(e)},0);n.set(i,r)};function Ze(e){return"function"==typeof e.name?e.name():"string"==typeof e.name?e.name:e.name_||(e.constructor&&e.constructor.name?e.constructor.name:typeof e)}function et(e){return"string"==typeof e&&/\S/.test(e)||Array.isArray(e)&&!!e.length}function tt(e,t,i){if(!e||!e.nodeName&&!st(e))throw new Error("Invalid target for "+Ze(t)+"#"+i+"; must be a DOM node or evented object.")}function it(e,t,i){if(!et(e))throw new Error("Invalid event type for "+Ze(t)+"#"+i+"; must be a non-empty string or array.")}function nt(e,t,i){if("function"!=typeof e)throw new Error("Invalid listener for "+Ze(t)+"#"+i+"; must be a function.")}function rt(e,t,i){var n,r,a=t.length<3||t[0]===e||t[0]===e.eventBusEl_,t=a?(n=e.eventBusEl_,3<=t.length&&t.shift(),r=t[0],t[1]):(n=t[0],r=t[1],t[2]);return tt(n,e,i),it(r,e,i),nt(t,e,i),{isTargetingSelf:a,target:n,type:r,listener:t=Xe(e,t)}}function at(e,t,i,n){tt(e,e,t),e.nodeName?Je[t](e,i,n):e[t](i,n)}var st=function(t){return t instanceof Qe||!!t.eventBusEl_&&["on","one","off","trigger"].every(function(e){return"function"==typeof t[e]})},ot={on:function(){for(var e=this,t=arguments.length,i=new Array(t),n=0;n<t;n++)i[n]=arguments[n];var r,a=rt(this,i,"on"),s=a.isTargetingSelf,o=a.target,u=a.type,l=a.listener;at(o,"on",u,l),s||((r=function(){return e.off(o,u,l)}).guid=l.guid,(s=function(){return e.off("dispose",r)}).guid=l.guid,at(this,"on","dispose",r),at(o,"on","dispose",s))},one:function(){for(var r=this,e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var n=rt(this,t,"one"),a=n.isTargetingSelf,s=n.target,o=n.type,u=n.listener;a?at(s,"one",o,u):((a=function e(){r.off(s,o,e);for(var t=arguments.length,i=new Array(t),n=0;n<t;n++)i[n]=arguments[n];u.apply(null,i)}).guid=u.guid,at(s,"one",o,a))},any:function(){for(var r=this,e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var n=rt(this,t,"any"),a=n.isTargetingSelf,s=n.target,o=n.type,u=n.listener;a?at(s,"any",o,u):((a=function e(){r.off(s,o,e);for(var t=arguments.length,i=new Array(t),n=0;n<t;n++)i[n]=arguments[n];u.apply(null,i)}).guid=u.guid,at(s,"any",o,a))},off:function(e,t,i){!e||et(e)?Ve(this.eventBusEl_,e,t):(t=t,tt(e=e,this,"off"),it(t,this,"off"),nt(i,this,"off"),i=Xe(this,i),this.off("dispose",i),e.nodeName?(Ve(e,t,i),Ve(e,"dispose",i)):st(e)&&(e.off(t,i),e.off("dispose",i)))},trigger:function(e,t){tt(this.eventBusEl_,this,"trigger");var i=e&&"string"!=typeof e?e.type:e;if(!et(i)){i="Invalid event type for "+Ze(this)+"#trigger; must be a non-empty string or object with a type key that has a non-empty value.";if(!e)throw new Error(i);(this.log||y).error(i)}return We(this.eventBusEl_,e,t)}};function ut(e,t){t=(t=void 0===t?{}:t).eventBusKey;if(t){if(!e[t].nodeName)throw new Error('The eventBusKey "'+t+'" does not refer to an element.');e.eventBusEl_=e[t]}else e.eventBusEl_=te("span",{className:"vjs-event-bus"});return k(e,ot),e.eventedCallbacks&&e.eventedCallbacks.forEach(function(e){e()}),e.on("dispose",function(){e.off(),[e,e.el_,e.eventBusEl_].forEach(function(e){e&&Ne.has(e)&&Ne.delete(e)}),_.setTimeout(function(){e.eventBusEl_=null},0)}),e}var lt={state:{},setState:function(e){var i,n=this;return E(e="function"==typeof e?e():e,function(e,t){n.state[t]!==e&&((i=i||{})[t]={from:n.state[t],to:e}),n.state[t]=e}),i&&st(this)&&this.trigger({changes:i,type:"statechanged"}),i}};function ct(e,t){return k(e,lt),e.state=k({},e.state,t),"function"==typeof e.handleStateChanged&&st(e)&&e.on("statechanged",e.handleStateChanged),e}function dt(e){return"string"!=typeof e?e:e.replace(/./,function(e){return e.toLowerCase()})}function ht(e){return"string"!=typeof e?e:e.replace(/./,function(e){return e.toUpperCase()})}function pt(){for(var i={},e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.forEach(function(e){e&&E(e,function(e,t){w(e)?(w(i[t])||(i[t]={}),i[t]=pt(i[t],e)):i[t]=e})}),i}var ft=_.Map||function(){function e(){this.map_={}}var t=e.prototype;return t.has=function(e){return e in this.map_},t.delete=function(e){var t=this.has(e);return delete this.map_[e],t},t.set=function(e,t){return this.map_[e]=t,this},t.forEach=function(e,t){for(var i in this.map_)e.call(t,this.map_[i],i,this)},e}(),mt=_.Set||function(){function e(){this.set_={}}var t=e.prototype;return t.has=function(e){return e in this.set_},t.delete=function(e){var t=this.has(e);return delete this.set_[e],t},t.add=function(e){return this.set_[e]=1,this},t.forEach=function(e,t){for(var i in this.set_)e.call(t,i,i,this)},e}(),gt=function(){function s(e,t,i){!e&&this.play?this.player_=e=this:this.player_=e,this.isDisposed_=!1,this.parentComponent_=null,this.options_=pt({},this.options_),t=this.options_=pt(this.options_,t),this.id_=t.id||t.el&&t.el.id,this.id_||(e=e&&e.id&&e.id()||"no_player",this.id_=e+"_component_"+Re++),this.name_=t.name||null,t.el?this.el_=t.el:!1!==t.createEl&&(this.el_=this.createEl()),!1!==t.evented&&(ut(this,{eventBusKey:this.el_?"el_":null}),this.handleLanguagechange=this.handleLanguagechange.bind(this),this.on(this.player_,"languagechange",this.handleLanguagechange)),ct(this,this.constructor.defaultState),this.children_=[],this.childIndex_={},this.childNameIndex_={},this.setTimeoutIds_=new mt,this.setIntervalIds_=new mt,this.rafIds_=new mt,this.namedRafs_=new ft,(this.clearingTimersOnDispose_=!1)!==t.initChildren&&this.initChildren(),this.ready(i),!1!==t.reportTouchActivity&&this.enableTouchActivity()}var e=s.prototype;return e.dispose=function(){if(!this.isDisposed_){if(this.readyQueue_&&(this.readyQueue_.length=0),this.trigger({type:"dispose",bubbles:!1}),this.isDisposed_=!0,this.children_)for(var e=this.children_.length-1;0<=e;e--)this.children_[e].dispose&&this.children_[e].dispose();this.children_=null,this.childIndex_=null,this.childNameIndex_=null,this.parentComponent_=null,this.el_&&(this.el_.parentNode&&this.el_.parentNode.removeChild(this.el_),this.el_=null),this.player_=null}},e.isDisposed=function(){return Boolean(this.isDisposed_)},e.player=function(){return this.player_},e.options=function(e){return e&&(this.options_=pt(this.options_,e)),this.options_},e.el=function(){return this.el_},e.createEl=function(e,t,i){return te(e,t,i)},e.localize=function(e,i,t){void 0===t&&(t=e);var n=this.player_.language&&this.player_.language(),r=this.player_.languages&&this.player_.languages(),a=r&&r[n],n=n&&n.split("-")[0],n=r&&r[n],t=t;return a&&a[e]?t=a[e]:n&&n[e]&&(t=n[e]),t=i?t.replace(/\{(\d+)\}/g,function(e,t){t=i[t-1];return"undefined"==typeof t?e:t}):t},e.handleLanguagechange=function(){},e.contentEl=function(){return this.contentEl_||this.el_},e.id=function(){return this.id_},e.name=function(){return this.name_},e.children=function(){return this.children_},e.getChildById=function(e){return this.childIndex_[e]},e.getChild=function(e){if(e)return this.childNameIndex_[e]},e.getDescendant=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];for(var t=t.reduce(function(e,t){return e.concat(t)},[]),n=this,r=0;r<t.length;r++)if(!(n=n.getChild(t[r]))||!n.getChild)return;return n},e.addChild=function(e,t,i){if(void 0===t&&(t={}),void 0===i&&(i=this.children_.length),"string"==typeof e){var n=ht(e),r=t.componentClass||n;t.name=n;var a=s.getComponent(r);if(!a)throw new Error("Component "+r+" does not exist");if("function"!=typeof a)return null;a=new a(this.player_||this,t)}else a=e;return a.parentComponent_&&a.parentComponent_.removeChild(a),this.children_.splice(i,0,a),a.parentComponent_=this,"function"==typeof a.id&&(this.childIndex_[a.id()]=a),(n=n||a.name&&ht(a.name()))&&(this.childNameIndex_[n]=a,this.childNameIndex_[dt(n)]=a),"function"==typeof a.el&&a.el()&&(n=null,this.children_[i+1]&&(this.children_[i+1].el_?n=this.children_[i+1].el_:J(this.children_[i+1])&&(n=this.children_[i+1])),this.contentEl().insertBefore(a.el(),n)),a},e.removeChild=function(e){if((e="string"==typeof e?this.getChild(e):e)&&this.children_){for(var t,i=!1,n=this.children_.length-1;0<=n;n--)if(this.children_[n]===e){i=!0,this.children_.splice(n,1);break}i&&(e.parentComponent_=null,this.childIndex_[e.id()]=null,this.childNameIndex_[ht(e.name())]=null,this.childNameIndex_[dt(e.name())]=null,(t=e.el())&&t.parentNode===this.contentEl()&&this.contentEl().removeChild(e.el()))}},e.initChildren=function(){var i,t,e,n=this,r=this.options_.children;r&&(i=this.options_,t=s.getComponent("Tech"),(e=Array.isArray(r)?r:Object.keys(r)).concat(Object.keys(this.options_).filter(function(t){return!e.some(function(e){return"string"==typeof e?t===e:t===e.name})})).map(function(e){var t,e="string"==typeof e?r[t=e]||n.options_[t]||{}:(t=e.name,e);return{name:t,opts:e}}).filter(function(e){e=s.getComponent(e.opts.componentClass||ht(e.name));return e&&!t.isTech(e)}).forEach(function(e){var t=e.name,e=e.opts;!1!==(e=void 0!==i[t]?i[t]:e)&&((e=!0===e?{}:e).playerOptions=n.options_.playerOptions,(e=n.addChild(t,e))&&(n[t]=e))}))},e.buildCSSClass=function(){return""},e.ready=function(e,t){if(void 0===t&&(t=!1),e)return this.isReady_?void(t?e.call(this):this.setTimeout(e,1)):(this.readyQueue_=this.readyQueue_||[],void this.readyQueue_.push(e))},e.triggerReady=function(){this.isReady_=!0,this.setTimeout(function(){var e=this.readyQueue_;this.readyQueue_=[],e&&0<e.length&&e.forEach(function(e){e.call(this)},this),this.trigger("ready")},1)},e.$=function(e,t){return Ce(e,t||this.contentEl())},e.$$=function(e,t){return we(e,t||this.contentEl())},e.hasClass=function(e){return re(this.el_,e)},e.addClass=function(e){ae(this.el_,e)},e.removeClass=function(e){se(this.el_,e)},e.toggleClass=function(e,t){oe(this.el_,e,t)},e.show=function(){this.removeClass("vjs-hidden")},e.hide=function(){this.addClass("vjs-hidden")},e.lockShowing=function(){this.addClass("vjs-lock-showing")},e.unlockShowing=function(){this.removeClass("vjs-lock-showing")},e.getAttribute=function(e){return ce(this.el_,e)},e.setAttribute=function(e,t){de(this.el_,e,t)},e.removeAttribute=function(e){he(this.el_,e)},e.width=function(e,t){return this.dimension("width",e,t)},e.height=function(e,t){return this.dimension("height",e,t)},e.dimensions=function(e,t){this.width(e,!0),this.height(t)},e.dimension=function(e,t,i){if(void 0!==t)return-1!==(""+(t=null===t||t!=t?0:t)).indexOf("%")||-1!==(""+t).indexOf("px")?this.el_.style[e]=t:this.el_.style[e]="auto"===t?"":t+"px",void(i||this.trigger("componentresize"));if(!this.el_)return 0;t=this.el_.style[e],i=t.indexOf("px");return-1!==i?parseInt(t.slice(0,i),10):parseInt(this.el_["offset"+ht(e)],10)},e.currentDimension=function(e){var t=0;if("width"!==e&&"height"!==e)throw new Error("currentDimension only accepts width or height value");return t=I(this.el_,e),0!==(t=parseFloat(t))&&!isNaN(t)||(e="offset"+ht(e),t=this.el_[e]),t},e.currentDimensions=function(){return{width:this.currentDimension("width"),height:this.currentDimension("height")}},e.currentWidth=function(){return this.currentDimension("width")},e.currentHeight=function(){return this.currentDimension("height")},e.focus=function(){this.el_.focus()},e.blur=function(){this.el_.blur()},e.handleKeyDown=function(e){this.player_&&(e.stopPropagation(),this.player_.handleKeyDown(e))},e.handleKeyPress=function(e){this.handleKeyDown(e)},e.emitTapEvents=function(){var i,t=0,n=null;this.on("touchstart",function(e){1===e.touches.length&&(n={pageX:e.touches[0].pageX,pageY:e.touches[0].pageY},t=_.performance.now(),i=!0)}),this.on("touchmove",function(e){var t;1<e.touches.length?i=!1:n&&(t=e.touches[0].pageX-n.pageX,e=e.touches[0].pageY-n.pageY,10<Math.sqrt(t*t+e*e)&&(i=!1))});function e(){i=!1}this.on("touchleave",e),this.on("touchcancel",e),this.on("touchend",function(e){!(n=null)===i&&_.performance.now()-t<200&&(e.preventDefault(),this.trigger("tap"))})},e.enableTouchActivity=function(){var t,i,e;this.player()&&this.player().reportUserActivity&&(t=Xe(this.player(),this.player().reportUserActivity),this.on("touchstart",function(){t(),this.clearInterval(i),i=this.setInterval(t,250)}),e=function(e){t(),this.clearInterval(i)},this.on("touchmove",t),this.on("touchend",e),this.on("touchcancel",e))},e.setTimeout=function(e,t){var i,n=this;return e=Xe(this,e),this.clearTimersOnDispose_(),i=_.setTimeout(function(){n.setTimeoutIds_.has(i)&&n.setTimeoutIds_.delete(i),e()},t),this.setTimeoutIds_.add(i),i},e.clearTimeout=function(e){return this.setTimeoutIds_.has(e)&&(this.setTimeoutIds_.delete(e),_.clearTimeout(e)),e},e.setInterval=function(e,t){e=Xe(this,e),this.clearTimersOnDispose_();t=_.setInterval(e,t);return this.setIntervalIds_.add(t),t},e.clearInterval=function(e){return this.setIntervalIds_.has(e)&&(this.setIntervalIds_.delete(e),_.clearInterval(e)),e},e.requestAnimationFrame=function(e){var t,i=this;return this.supportsRaf_?(this.clearTimersOnDispose_(),e=Xe(this,e),t=_.requestAnimationFrame(function(){i.rafIds_.has(t)&&i.rafIds_.delete(t),e()}),this.rafIds_.add(t),t):this.setTimeout(e,1e3/60)},e.requestNamedAnimationFrame=function(e,t){var i=this;if(!this.namedRafs_.has(e)){this.clearTimersOnDispose_(),t=Xe(this,t);var n=this.requestAnimationFrame(function(){t(),i.namedRafs_.has(e)&&i.namedRafs_.delete(e)});return this.namedRafs_.set(e,n),e}},e.cancelNamedAnimationFrame=function(e){this.namedRafs_.has(e)&&(this.cancelAnimationFrame(this.namedRafs_.get(e)),this.namedRafs_.delete(e))},e.cancelAnimationFrame=function(e){return this.supportsRaf_?(this.rafIds_.has(e)&&(this.rafIds_.delete(e),_.cancelAnimationFrame(e)),e):this.clearTimeout(e)},e.clearTimersOnDispose_=function(){var n=this;this.clearingTimersOnDispose_||(this.clearingTimersOnDispose_=!0,this.one("dispose",function(){[["namedRafs_","cancelNamedAnimationFrame"],["rafIds_","cancelAnimationFrame"],["setTimeoutIds_","clearTimeout"],["setIntervalIds_","clearInterval"]].forEach(function(e){var t=e[0],i=e[1];n[t].forEach(function(e,t){return n[i](t)})}),n.clearingTimersOnDispose_=!1}))},s.registerComponent=function(e,t){if("string"!=typeof e||!e)throw new Error('Illegal component name, "'+e+'"; must be a non-empty string.');var i=s.getComponent("Tech"),n=i&&i.isTech(t),i=s===t||s.prototype.isPrototypeOf(t.prototype);if(n||!i){var r=n?"techs must be registered using Tech.registerTech()":"must be a Component subclass";throw new Error('Illegal component, "'+e+'"; '+r+".")}e=ht(e),s.components_||(s.components_={});r=s.getComponent("Player");if("Player"===e&&r&&r.players){var a=r.players,r=Object.keys(a);if(a&&0<r.length&&r.map(function(e){return a[e]}).every(Boolean))throw new Error("Can not register Player component after player has been created.")}return s.components_[e]=t,s.components_[dt(e)]=t},s.getComponent=function(e){if(e&&s.components_)return s.components_[e]},s}();gt.prototype.supportsRaf_="function"==typeof _.requestAnimationFrame&&"function"==typeof _.cancelAnimationFrame,gt.registerComponent("Component",gt);var yt=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e};var vt=function(e,t){e.prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t};function _t(e,t,i,n){return function(e,t,i){if("number"!=typeof t||t<0||i<t)throw new Error("Failed to execute '"+e+"' on 'TimeRanges': The index provided ("+t+") is non-numeric or out of bounds (0-"+i+").")}(e,n,i.length-1),i[n][t]}function bt(e){var t=void 0===e||0===e.length?{length:0,start:function(){throw new Error("This TimeRanges object is empty")},end:function(){throw new Error("This TimeRanges object is empty")}}:{length:e.length,start:_t.bind(null,"start",0,e),end:_t.bind(null,"end",1,e)};return _.Symbol&&_.Symbol.iterator&&(t[_.Symbol.iterator]=function(){return(e||[]).values()}),t}function Tt(e,t){return Array.isArray(e)?bt(e):void 0===e||void 0===t?bt():bt([[e,t]])}function St(e,t){var i,n,r=0;if(!t)return 0;e&&e.length||(e=Tt(0,0));for(var a=0;a<e.length;a++)i=e.start(a),r+=(n=t<(n=e.end(a))?t:n)-i;return r/t}function Et(e){if(e instanceof Et)return e;"number"==typeof e?this.code=e:"string"==typeof e?this.message=e:C(e)&&("number"==typeof e.code&&(this.code=e.code),k(this,e)),this.message||(this.message=Et.defaultMessages[this.code]||"")}Et.prototype.code=0,Et.prototype.message="",Et.prototype.status=null,Et.errorTypes=["MEDIA_ERR_CUSTOM","MEDIA_ERR_ABORTED","MEDIA_ERR_NETWORK","MEDIA_ERR_DECODE","MEDIA_ERR_SRC_NOT_SUPPORTED","MEDIA_ERR_ENCRYPTED"],Et.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."};for(var kt=0;kt<Et.errorTypes.length;kt++)Et[Et.errorTypes[kt]]=kt,Et.prototype[Et.errorTypes[kt]]=kt;var Ct=function(e,t){var i,n=null;try{i=JSON.parse(e,t)}catch(e){n=e}return[n,i]};function wt(e){return null!=e&&"function"==typeof e.then}function It(e){wt(e)&&e.then(null,function(e){})}function xt(n){return["kind","label","language","id","inBandMetadataTrackDispatchType","mode","src"].reduce(function(e,t,i){return n[t]&&(e[t]=n[t]),e},{cues:n.cues&&Array.prototype.map.call(n.cues,function(e){return{startTime:e.startTime,endTime:e.endTime,text:e.text,id:e.id}})})}var At=function(e){var t=e.$$("track"),i=Array.prototype.map.call(t,function(e){return e.track});return Array.prototype.map.call(t,function(e){var t=xt(e.track);return e.src&&(t.src=e.src),t}).concat(Array.prototype.filter.call(e.textTracks(),function(e){return-1===i.indexOf(e)}).map(xt))},Pt=function(e,i){return e.forEach(function(e){var t=i.addRemoteTextTrack(e).track;!e.src&&e.cues&&e.cues.forEach(function(e){return t.addCue(e)})}),i.textTracks()},Lt=t(function(e,t){function i(e){if(!e||"object"!=typeof e||(t=e.which||e.keyCode||e.charCode)&&(e=t),"number"==typeof e)return o[e];var t=String(e),e=n[t.toLowerCase()];return e||((e=r[t.toLowerCase()])?e:1===t.length?t.charCodeAt(0):void 0)}i.isEventKey=function(e,t){if(e&&"object"==typeof e){var i=e.which||e.keyCode||e.charCode;if(null==i)return!1;if("string"==typeof t){e=n[t.toLowerCase()];if(e)return e===i;if(e=r[t.toLowerCase()])return e===i}else if("number"==typeof t)return t===i;return!1}};for(var n=(t=e.exports=i).code=t.codes={backspace:8,tab:9,enter:13,shift:16,ctrl:17,alt:18,"pause/break":19,"caps lock":20,esc:27,space:32,"page up":33,"page down":34,end:35,home:36,left:37,up:38,right:39,down:40,insert:45,delete:46,command:91,"left command":91,"right command":93,"numpad *":106,"numpad +":107,"numpad -":109,"numpad .":110,"numpad /":111,"num lock":144,"scroll lock":145,"my computer":182,"my calculator":183,";":186,"=":187,",":188,"-":189,".":190,"/":191,"`":192,"[":219,"\\":220,"]":221,"'":222},r=t.aliases={windows:91,"⇧":16,"⌥":18,"⌃":17,"⌘":91,ctl:17,control:17,option:18,pause:19,break:19,caps:20,return:13,escape:27,spc:32,spacebar:32,pgup:33,pgdn:34,ins:45,del:46,cmd:91},a=97;a<123;a++)n[String.fromCharCode(a)]=a-32;for(var a=48;a<58;a++)n[a-48]=a;for(a=1;a<13;a++)n["f"+a]=a+111;for(a=0;a<10;a++)n["numpad "+a]=a+96;var s,o=t.names=t.title={};for(a in n)o[n[a]]=a;for(s in r)n[s]=r[s]});Lt.code,Lt.codes,Lt.aliases,Lt.names,Lt.title;var Dt="vjs-modal-dialog",Ot=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.handleKeyDown_=function(e){return i.handleKeyDown(e)},i.close_=function(e){return i.close(e)},i.opened_=i.hasBeenOpened_=i.hasBeenFilled_=!1,i.closeable(!i.options_.uncloseable),i.content(i.options_.content),i.contentEl_=te("div",{className:Dt+"-content"},{role:"document"}),i.descEl_=te("p",{className:Dt+"-description vjs-control-text",id:i.el().getAttribute("aria-describedby")}),ie(i.descEl_,i.description()),i.el_.appendChild(i.descEl_),i.el_.appendChild(i.contentEl_),i}vt(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:this.buildCSSClass(),tabIndex:-1},{"aria-describedby":this.id()+"_description","aria-hidden":"true","aria-label":this.label(),role:"dialog"})},t.dispose=function(){this.contentEl_=null,this.descEl_=null,this.previouslyActiveEl_=null,n.prototype.dispose.call(this)},t.buildCSSClass=function(){return Dt+" vjs-hidden "+n.prototype.buildCSSClass.call(this)},t.label=function(){return this.localize(this.options_.label||"Modal Window")},t.description=function(){var e=this.options_.description||this.localize("This is a modal window.");return this.closeable()&&(e+=" "+this.localize("This modal can be closed by pressing the Escape key or activating the close button.")),e},t.open=function(){var e;this.opened_||(e=this.player(),this.trigger("beforemodalopen"),this.opened_=!0,!this.options_.fillAlways&&(this.hasBeenOpened_||this.hasBeenFilled_)||this.fill(),this.wasPlaying_=!e.paused(),this.options_.pauseOnOpen&&this.wasPlaying_&&e.pause(),this.on("keydown",this.handleKeyDown_),this.hadControls_=e.controls(),e.controls(!1),this.show(),this.conditionalFocus_(),this.el().setAttribute("aria-hidden","false"),this.trigger("modalopen"),this.hasBeenOpened_=!0)},t.opened=function(e){return"boolean"==typeof e&&this[e?"open":"close"](),this.opened_},t.close=function(){var e;this.opened_&&(e=this.player(),this.trigger("beforemodalclose"),this.opened_=!1,this.wasPlaying_&&this.options_.pauseOnOpen&&e.play(),this.off("keydown",this.handleKeyDown_),this.hadControls_&&e.controls(!0),this.hide(),this.el().setAttribute("aria-hidden","true"),this.trigger("modalclose"),this.conditionalBlur_(),this.options_.temporary&&this.dispose())},t.closeable=function(e){var t,i;return"boolean"==typeof e&&(t=this.closeable_=!!e,i=this.getChild("closeButton"),t&&!i&&(e=this.contentEl_,this.contentEl_=this.el_,i=this.addChild("closeButton",{controlText:"Close Modal Dialog"}),this.contentEl_=e,this.on(i,"close",this.close_)),!t&&i&&(this.off(i,"close",this.close_),this.removeChild(i),i.dispose())),this.closeable_},t.fill=function(){this.fillWith(this.content())},t.fillWith=function(e){var t=this.contentEl(),i=t.parentNode,n=t.nextSibling;this.trigger("beforemodalfill"),this.hasBeenFilled_=!0,i.removeChild(t),this.empty(),Se(t,e),this.trigger("modalfill"),n?i.insertBefore(t,n):i.appendChild(t);t=this.getChild("closeButton");t&&i.appendChild(t.el_)},t.empty=function(){this.trigger("beforemodalempty"),_e(this.contentEl()),this.trigger("modalempty")},t.content=function(e){return"undefined"!=typeof e&&(this.content_=e),this.content_},t.conditionalFocus_=function(){var e=d.activeElement,t=this.player_.el_;this.previouslyActiveEl_=null,!t.contains(e)&&t!==e||(this.previouslyActiveEl_=e,this.focus())},t.conditionalBlur_=function(){this.previouslyActiveEl_&&(this.previouslyActiveEl_.focus(),this.previouslyActiveEl_=null)},t.handleKeyDown=function(e){if(e.stopPropagation(),Lt.isEventKey(e,"Escape")&&this.closeable())return e.preventDefault(),void this.close();if(Lt.isEventKey(e,"Tab")){for(var t,i=this.focusableEls_(),n=this.el_.querySelector(":focus"),r=0;r<i.length;r++)if(n===i[r]){t=r;break}d.activeElement===this.el_&&(t=0),e.shiftKey&&0===t?(i[i.length-1].focus(),e.preventDefault()):e.shiftKey||t!==i.length-1||(i[0].focus(),e.preventDefault())}},t.focusableEls_=function(){var e=this.el_.querySelectorAll("*");return Array.prototype.filter.call(e,function(e){return(e instanceof _.HTMLAnchorElement||e instanceof _.HTMLAreaElement)&&e.hasAttribute("href")||(e instanceof _.HTMLInputElement||e instanceof _.HTMLSelectElement||e instanceof _.HTMLTextAreaElement||e instanceof _.HTMLButtonElement)&&!e.hasAttribute("disabled")||e instanceof _.HTMLIFrameElement||e instanceof _.HTMLObjectElement||e instanceof _.HTMLEmbedElement||e.hasAttribute("tabindex")&&-1!==e.getAttribute("tabindex")||e.hasAttribute("contenteditable")})},e}(gt);Ot.prototype.options_={pauseOnOpen:!0,temporary:!0},gt.registerComponent("ModalDialog",Ot);var Rt,Mt=function(n){function e(e){var t;void 0===e&&(e=[]),(t=n.call(this)||this).tracks_=[],Object.defineProperty(yt(t),"length",{get:function(){return this.tracks_.length}});for(var i=0;i<e.length;i++)t.addTrack(e[i]);return t}vt(e,n);var t=e.prototype;return t.addTrack=function(e){var t=this,i=this.tracks_.length;""+i in this||Object.defineProperty(this,i,{get:function(){return this.tracks_[i]}}),-1===this.tracks_.indexOf(e)&&(this.tracks_.push(e),this.trigger({track:e,type:"addtrack",target:this})),e.labelchange_=function(){t.trigger({track:e,type:"labelchange",target:t})},st(e)&&e.addEventListener("labelchange",e.labelchange_)},t.removeTrack=function(e){for(var t,i=0,n=this.length;i<n;i++)if(this[i]===e){(t=this[i]).off&&t.off(),this.tracks_.splice(i,1);break}t&&this.trigger({track:t,type:"removetrack",target:this})},t.getTrackById=function(e){for(var t=null,i=0,n=this.length;i<n;i++){var r=this[i];if(r.id===e){t=r;break}}return t},e}(Qe);for(Rt in Mt.prototype.allowedEvents_={change:"change",addtrack:"addtrack",removetrack:"removetrack",labelchange:"labelchange"},Mt.prototype.allowedEvents_)Mt.prototype["on"+Rt]=null;function Nt(e,t){for(var i=0;i<e.length;i++)Object.keys(e[i]).length&&t.id!==e[i].id&&(e[i].enabled=!1)}function Ut(e,t){for(var i=0;i<e.length;i++)Object.keys(e[i]).length&&t.id!==e[i].id&&(e[i].selected=!1)}function Bt(e){var t=["protocol","hostname","port","pathname","search","hash","host"],i=d.createElement("a");i.href=e;for(var n={},r=0;r<t.length;r++)n[t[r]]=i[t[r]];return"http:"===n.protocol&&(n.host=n.host.replace(/:80$/,"")),"https:"===n.protocol&&(n.host=n.host.replace(/:443$/,"")),n.protocol||(n.protocol=_.location.protocol),n.host||(n.host=_.location.host),n}function Ft(e){var t;return e.match(/^https?:\/\//)||((t=d.createElement("a")).href=e,e=t.href),e}function jt(e){if("string"==typeof e){e=/^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/.exec(e);if(e)return e.pop().toLowerCase()}return""}function Ht(e,t){return void 0===t&&(t=_.location),(":"===(e=Bt(e)).protocol?t:e).protocol+e.host!==t.protocol+t.host}var qt=function(n){function e(e){for(var t,i=(e=void 0===e?[]:e).length-1;0<=i;i--)if(e[i].enabled){Nt(e,e[i]);break}return(t=n.call(this,e)||this).changing_=!1,t}vt(e,n);var t=e.prototype;return t.addTrack=function(e){var t=this;e.enabled&&Nt(this,e),n.prototype.addTrack.call(this,e),e.addEventListener&&(e.enabledChange_=function(){t.changing_||(t.changing_=!0,Nt(t,e),t.changing_=!1,t.trigger("change"))},e.addEventListener("enabledchange",e.enabledChange_))},t.removeTrack=function(e){n.prototype.removeTrack.call(this,e),e.removeEventListener&&e.enabledChange_&&(e.removeEventListener("enabledchange",e.enabledChange_),e.enabledChange_=null)},e}(Mt),e=function(n){function e(e){for(var t,i=(e=void 0===e?[]:e).length-1;0<=i;i--)if(e[i].selected){Ut(e,e[i]);break}return(t=n.call(this,e)||this).changing_=!1,Object.defineProperty(yt(t),"selectedIndex",{get:function(){for(var e=0;e<this.length;e++)if(this[e].selected)return e;return-1},set:function(){}}),t}vt(e,n);var t=e.prototype;return t.addTrack=function(e){var t=this;e.selected&&Ut(this,e),n.prototype.addTrack.call(this,e),e.addEventListener&&(e.selectedChange_=function(){t.changing_||(t.changing_=!0,Ut(t,e),t.changing_=!1,t.trigger("change"))},e.addEventListener("selectedchange",e.selectedChange_))},t.removeTrack=function(e){n.prototype.removeTrack.call(this,e),e.removeEventListener&&e.selectedChange_&&(e.removeEventListener("selectedchange",e.selectedChange_),e.selectedChange_=null)},e}(Mt),s=function(i){function e(){return i.apply(this,arguments)||this}vt(e,i);var t=e.prototype;return t.addTrack=function(e){var t=this;i.prototype.addTrack.call(this,e),this.queueChange_||(this.queueChange_=function(){return t.queueTrigger("change")}),this.triggerSelectedlanguagechange||(this.triggerSelectedlanguagechange_=function(){return t.trigger("selectedlanguagechange")}),e.addEventListener("modechange",this.queueChange_);-1===["metadata","chapters"].indexOf(e.kind)&&e.addEventListener("modechange",this.triggerSelectedlanguagechange_)},t.removeTrack=function(e){i.prototype.removeTrack.call(this,e),e.removeEventListener&&(this.queueChange_&&e.removeEventListener("modechange",this.queueChange_),this.selectedlanguagechange_&&e.removeEventListener("modechange",this.triggerSelectedlanguagechange_))},e}(Mt),o=function(){function e(e){void 0===e&&(e=[]),this.trackElements_=[],Object.defineProperty(this,"length",{get:function(){return this.trackElements_.length}});for(var t=0,i=e.length;t<i;t++)this.addTrackElement_(e[t])}var t=e.prototype;return t.addTrackElement_=function(e){var t=this.trackElements_.length;""+t in this||Object.defineProperty(this,t,{get:function(){return this.trackElements_[t]}}),-1===this.trackElements_.indexOf(e)&&this.trackElements_.push(e)},t.getTrackElementByTrack_=function(e){for(var t,i=0,n=this.trackElements_.length;i<n;i++)if(e===this.trackElements_[i].track){t=this.trackElements_[i];break}return t},t.removeTrackElement_=function(e){for(var t=0,i=this.trackElements_.length;t<i;t++)if(e===this.trackElements_[t]){this.trackElements_[t].track&&"function"==typeof this.trackElements_[t].track.off&&this.trackElements_[t].track.off(),"function"==typeof this.trackElements_[t].off&&this.trackElements_[t].off(),this.trackElements_.splice(t,1);break}},e}(),Vt=function(){function t(e){t.prototype.setCues_.call(this,e),Object.defineProperty(this,"length",{get:function(){return this.length_}})}var e=t.prototype;return e.setCues_=function(e){var t=this.length||0,i=0,n=e.length;this.cues_=e,this.length_=e.length;function r(e){""+e in this||Object.defineProperty(this,""+e,{get:function(){return this.cues_[e]}})}if(t<n)for(i=t;i<n;i++)r.call(this,i)},e.getCueById=function(e){for(var t=null,i=0,n=this.length;i<n;i++){var r=this[i];if(r.id===e){t=r;break}}return t},t}(),Wt={alternative:"alternative",captions:"captions",main:"main",sign:"sign",subtitles:"subtitles",commentary:"commentary"},zt={alternative:"alternative",descriptions:"descriptions",main:"main","main-desc":"main-desc",translation:"translation",commentary:"commentary"},Gt={subtitles:"subtitles",captions:"captions",descriptions:"descriptions",chapters:"chapters",metadata:"metadata"},Xt={disabled:"disabled",hidden:"hidden",showing:"showing"},A=function(a){function e(e){void 0===e&&(e={});var t,i=a.call(this)||this,n={id:e.id||"vjs_track_"+Re++,kind:e.kind||"",language:e.language||""},r=e.label||"";for(t in n)!function(e){Object.defineProperty(yt(i),e,{get:function(){return n[e]},set:function(){}})}(t);return Object.defineProperty(yt(i),"label",{get:function(){return r},set:function(e){e!==r&&(r=e,this.trigger("labelchange"))}}),i}return vt(e,a),e}(Qe),Kt=Object.freeze({__proto__:null,parseUrl:Bt,getAbsoluteURL:Ft,getFileExtension:jt,isCrossOrigin:Ht}),Yt=function(e){if(!e)return!1;var t=Qt.call(e);return"[object Function]"===t||"function"==typeof e&&"[object RegExp]"!==t||"undefined"!=typeof window&&(e===window.setTimeout||e===window.alert||e===window.confirm||e===window.prompt)},Qt=Object.prototype.toString;ei.httpHandler=function(n,r){return void 0===r&&(r=!1),function(e,t,i){if(e)n(e);else if(400<=t.statusCode&&t.statusCode<=599){e=i;if(r)if(_.TextDecoder){t=function(e){void 0===e&&(e="");return e.toLowerCase().split(";").reduce(function(e,t){var i=t.split("="),t=i[0],i=i[1];return"charset"===t.trim()?i.trim():e},"utf-8")}(t.headers&&t.headers["content-type"]);try{e=new TextDecoder(t).decode(i)}catch(e){}}else e=String.fromCharCode.apply(null,new Uint8Array(i));n({cause:e})}else n(null,i)}};
+/**
+ * @license
+ * slighly modified parse-headers 2.0.2 <https://github.com/kesla/parse-headers/>
+ * Copyright (c) 2014 David Björklund
+ * Available under the MIT license
+ * <https://github.com/kesla/parse-headers/blob/master/LICENCE>
+ */
+var $t=function(e){var n={};return e&&e.trim().split("\n").forEach(function(e){var t=e.indexOf(":"),i=e.slice(0,t).trim().toLowerCase(),t=e.slice(t+1).trim();"undefined"==typeof n[i]?n[i]=t:Array.isArray(n[i])?n[i].push(t):n[i]=[n[i],t]}),n},Jt=ei,P=ei;function Zt(e,t,i){var n=e;return Yt(t)?(i=t,"string"==typeof e&&(n={uri:e})):n=b({},t,{uri:e}),n.callback=i,n}function ei(e,t,i){return ti(t=Zt(e,t,i))}function ti(n){if("undefined"==typeof n.callback)throw new Error("callback argument missing");var r=!1,a=function(e,t,i){r||(r=!0,n.callback(e,t,i))};function s(){var e=void 0,e=l.response||l.responseText||function(e){try{if("document"===e.responseType)return e.responseXML;var t=e.responseXML&&"parsererror"===e.responseXML.documentElement.nodeName;if(""===e.responseType&&!t)return e.responseXML}catch(e){}return null}(l);if(m)try{e=JSON.parse(e)}catch(e){}return e}function t(e){return clearTimeout(u),(e=!(e instanceof Error)?new Error(""+(e||"Unknown XMLHttpRequest Error")):e).statusCode=0,a(e,g)}function e(){if(!o){clearTimeout(u);var e=n.useXDR&&void 0===l.status?200:1223===l.status?204:l.status,t=g,i=null;return 0!==e?(t={body:s(),statusCode:e,method:d,headers:{},url:c,rawRequest:l},l.getAllResponseHeaders&&(t.headers=$t(l.getAllResponseHeaders()))):i=new Error("Internal XMLHttpRequest Error"),a(i,t,t.body)}}var i,o,u,l=n.xhr||null,c=(l=l||new(n.cors||n.useXDR?ei.XDomainRequest:ei.XMLHttpRequest)).url=n.uri||n.url,d=l.method=n.method||"GET",h=n.body||n.data,p=l.headers=n.headers||{},f=!!n.sync,m=!1,g={body:void 0,headers:{},statusCode:0,method:d,url:c,rawRequest:l};if("json"in n&&!1!==n.json&&(m=!0,p.accept||p.Accept||(p.Accept="application/json"),"GET"!==d&&"HEAD"!==d&&(p["content-type"]||p["Content-Type"]||(p["Content-Type"]="application/json"),h=JSON.stringify(!0===n.json?h:n.json))),l.onreadystatechange=function(){4===l.readyState&&setTimeout(e,0)},l.onload=e,l.onerror=t,l.onprogress=function(){},l.onabort=function(){o=!0},l.ontimeout=t,l.open(d,c,!f,n.username,n.password),f||(l.withCredentials=!!n.withCredentials),!f&&0<n.timeout&&(u=setTimeout(function(){var e;o||(o=!0,l.abort("timeout"),(e=new Error("XMLHttpRequest timeout")).code="ETIMEDOUT",t(e))},n.timeout)),l.setRequestHeader)for(i in p)p.hasOwnProperty(i)&&l.setRequestHeader(i,p[i]);else if(n.headers&&!function(e){for(var t in e)if(e.hasOwnProperty(t))return;return 1}(n.headers))throw new Error("Headers cannot be set on an XDomainRequest object");return"responseType"in n&&(l.responseType=n.responseType),"beforeSend"in n&&"function"==typeof n.beforeSend&&n.beforeSend(l),l.send(h||null),l}ei.XMLHttpRequest=_.XMLHttpRequest||function(){},ei.XDomainRequest="withCredentials"in new ei.XMLHttpRequest?ei.XMLHttpRequest:_.XDomainRequest,function(e,t){for(var i=0;i<e.length;i++)t(e[i])}(["get","put","post","patch","head","delete"],function(n){ei["delete"===n?"del":n]=function(e,t,i){return(t=Zt(e,t,i)).method=n.toUpperCase(),ti(t)}}),Jt.default=P;function ii(e,t){var i=new _.WebVTT.Parser(_,_.vttjs,_.WebVTT.StringDecoder()),n=[];i.oncue=function(e){t.addCue(e)},i.onparsingerror=function(e){n.push(e)},i.onflush=function(){t.trigger({type:"loadeddata",target:t})},i.parse(e),0<n.length&&(_.console&&_.console.groupCollapsed&&_.console.groupCollapsed("Text Track parsing errors for "+t.src),n.forEach(function(e){return y.error(e)}),_.console&&_.console.groupEnd&&_.console.groupEnd()),i.flush()}function ni(e,n){var t={uri:e};(e=Ht(e))&&(t.cors=e),(e="use-credentials"===n.tech_.crossOrigin())&&(t.withCredentials=e),Jt(t,Xe(this,function(e,t,i){return e?y.error(e,t):(n.loaded_=!0,void("function"!=typeof _.WebVTT?n.tech_&&n.tech_.any(["vttjsloaded","vttjserror"],function(e){return"vttjserror"!==e.type?ii(i,n):void y.error("vttjs failed to load, stopping trying to process "+n.src)}):ii(i,n)))}))}var ri=function(u){function e(e){var t;if(!(e=void 0===e?{}:e).tech)throw new Error("A tech was not provided.");var e=pt(e,{kind:Gt[e.kind]||"subtitles",language:e.language||e.srclang||""}),i=Xt[e.mode]||"disabled",n=e.default;"metadata"!==e.kind&&"chapters"!==e.kind||(i="hidden"),(t=u.call(this,e)||this).tech_=e.tech,t.cues_=[],t.activeCues_=[],t.preload_=!1!==t.tech_.preloadTextTracks;var r=new Vt(t.cues_),s=new Vt(t.activeCues_),o=!1,a=Xe(yt(t),function(){this.tech_.isReady_&&!this.tech_.isDisposed()&&(this.activeCues=this.activeCues,o&&(this.trigger("cuechange"),o=!1))});return t.tech_.one("dispose",function(){t.tech_.off("timeupdate",a)}),"disabled"!==i&&t.tech_.on("timeupdate",a),Object.defineProperties(yt(t),{default:{get:function(){return n},set:function(){}},mode:{get:function(){return i},set:function(e){Xt[e]&&i!==e&&(i=e,this.preload_||"disabled"===i||0!==this.cues.length||ni(this.src,this),this.tech_.off("timeupdate",a),"disabled"!==i&&this.tech_.on("timeupdate",a),this.trigger("modechange"))}},cues:{get:function(){return this.loaded_?r:null},set:function(){}},activeCues:{get:function(){if(!this.loaded_)return null;if(0===this.cues.length)return s;for(var e=this.tech_.currentTime(),t=[],i=0,n=this.cues.length;i<n;i++){var r=this.cues[i];(r.startTime<=e&&r.endTime>=e||r.startTime===r.endTime&&r.startTime<=e&&r.startTime+.5>=e)&&t.push(r)}if(o=!1,t.length!==this.activeCues_.length)o=!0;else for(var a=0;a<t.length;a++)-1===this.activeCues_.indexOf(t[a])&&(o=!0);return this.activeCues_=t,s.setCues_(this.activeCues_),s},set:function(){}}}),e.src?(t.src=e.src,t.preload_||(t.loaded_=!0),(t.preload_||"subtitles"!==e.kind&&"captions"!==e.kind)&&ni(t.src,yt(t))):t.loaded_=!0,t}vt(e,u);var t=e.prototype;return t.addCue=function(e){var t=e;if(_.vttjs&&!(e instanceof _.vttjs.VTTCue)){for(var i in t=new _.vttjs.VTTCue(e.startTime,e.endTime,e.text),e)i in t||(t[i]=e[i]);t.id=e.id,t.originalCue_=e}for(var n=this.tech_.textTracks(),r=0;r<n.length;r++)n[r]!==this&&n[r].removeCue(t);this.cues_.push(t),this.cues.setCues_(this.cues_)},t.removeCue=function(e){for(var t=this.cues_.length;t--;){var i=this.cues_[t];if(i===e||i.originalCue_&&i.originalCue_===e){this.cues_.splice(t,1),this.cues.setCues_(this.cues_);break}}},e}(A);ri.prototype.allowedEvents_={cuechange:"cuechange"};var ai=function(n){function e(e){var t=pt(e=void 0===e?{}:e,{kind:zt[e.kind]||""}),e=n.call(this,t)||this,i=!1;return Object.defineProperty(yt(e),"enabled",{get:function(){return i},set:function(e){"boolean"==typeof e&&e!==i&&(i=e,this.trigger("enabledchange"))}}),t.enabled&&(e.enabled=t.enabled),e.loaded_=!0,e}return vt(e,n),e}(A),si=function(n){function e(e){var t=pt(e=void 0===e?{}:e,{kind:Wt[e.kind]||""}),e=n.call(this,t)||this,i=!1;return Object.defineProperty(yt(e),"selected",{get:function(){return i},set:function(e){"boolean"==typeof e&&e!==i&&(i=e,this.trigger("selectedchange"))}}),t.selected&&(e.selected=t.selected),e}return vt(e,n),e}(A),L=function(r){function e(e){var t;void 0===e&&(e={});var i=r.call(this)||this,n=new ri(e);return i.kind=n.kind,i.src=n.src,i.srclang=n.language,i.label=n.label,i.default=n.default,Object.defineProperties(yt(i),{readyState:{get:function(){return t}},track:{get:function(){return n}}}),t=0,n.addEventListener("loadeddata",function(){t=2,i.trigger({type:"load",target:yt(i)})}),i}return vt(e,r),e}(Qe);L.prototype.allowedEvents_={load:"load"},L.NONE=0,L.LOADING=1,L.LOADED=2,L.ERROR=3;var oi={audio:{ListClass:qt,TrackClass:ai,capitalName:"Audio"},video:{ListClass:e,TrackClass:si,capitalName:"Video"},text:{ListClass:s,TrackClass:ri,capitalName:"Text"}};Object.keys(oi).forEach(function(e){oi[e].getterName=e+"Tracks",oi[e].privateName=e+"Tracks_"});var ui={remoteText:{ListClass:s,TrackClass:ri,capitalName:"RemoteText",getterName:"remoteTextTracks",privateName:"remoteTextTracks_"},remoteTextEl:{ListClass:o,TrackClass:L,capitalName:"RemoteTextTrackEls",getterName:"remoteTextTrackEls",privateName:"remoteTextTrackEls_"}},li=b({},oi,ui);ui.names=Object.keys(ui),oi.names=Object.keys(oi),li.names=[].concat(ui.names).concat(oi.names);var ci=Object.create||function(e){if(1!==arguments.length)throw new Error("Object.create shim only accepts one parameter.");return di.prototype=e,new di};function di(){}function hi(e,t){this.name="ParsingError",this.code=e.code,this.message=t||e.message}function pi(e){function t(e,t,i,n){return 3600*(0|e)+60*(0|t)+(0|i)+(0|n)/1e3}e=e.match(/^(\d+):(\d{1,2})(:\d{1,2})?\.(\d{3})/);return e?e[3]?t(e[1],e[2],e[3].replace(":",""),e[4]):59<e[1]?t(e[1],e[2],0,e[4]):t(0,e[1],e[2],e[4]):null}function fi(){this.values=ci(null)}function mi(e,t,i,n){var r,a,s=n?e.split(n):[e];for(r in s)"string"==typeof s[r]&&(2===(a=s[r].split(i)).length&&t(a[0],a[1]))}function gi(t,e,s){var i=t;function n(){var e=pi(t);if(null===e)throw new hi(hi.Errors.BadTimeStamp,"Malformed timestamp: "+i);return t=t.replace(/^[^\sa-zA-Z-]+/,""),e}function r(){t=t.replace(/^\s+/,"")}if(r(),e.startTime=n(),r(),"--\x3e"!==t.substr(0,3))throw new hi(hi.Errors.BadTimeStamp,"Malformed time stamp (time stamps must be separated by '--\x3e'): "+i);t=t.substr(3),r(),e.endTime=n(),r(),function(e,t){var a=new fi;mi(e,function(e,t){switch(e){case"region":for(var i=s.length-1;0<=i;i--)if(s[i].id===t){a.set(e,s[i].region);break}break;case"vertical":a.alt(e,t,["rl","lr"]);break;case"line":var n=t.split(","),r=n[0];a.integer(e,r),a.percent(e,r)&&a.set("snapToLines",!1),a.alt(e,r,["auto"]),2===n.length&&a.alt("lineAlign",n[1],["start","center","end"]);break;case"position":n=t.split(","),a.percent(e,n[0]),2===n.length&&a.alt("positionAlign",n[1],["start","center","end"]);break;case"size":a.percent(e,t);break;case"align":a.alt(e,t,["start","center","end","left","right"])}},/:/,/\s/),t.region=a.get("region",null),t.vertical=a.get("vertical","");try{t.line=a.get("line","auto")}catch(e){}t.lineAlign=a.get("lineAlign","start"),t.snapToLines=a.get("snapToLines",!0),t.size=a.get("size",100);try{t.align=a.get("align","center")}catch(e){t.align=a.get("align","middle")}try{t.position=a.get("position","auto")}catch(e){t.position=a.get("position",{start:0,left:0,center:50,middle:50,end:100,right:100},t.align)}t.positionAlign=a.get("positionAlign",{start:"start",left:"start",center:"center",middle:"center",end:"end",right:"end"},t.align)}(t,e)}((hi.prototype=ci(Error.prototype)).constructor=hi).Errors={BadSignature:{code:0,message:"Malformed WebVTT signature."},BadTimeStamp:{code:1,message:"Malformed time stamp."}},fi.prototype={set:function(e,t){this.get(e)||""===t||(this.values[e]=t)},get:function(e,t,i){return i?this.has(e)?this.values[e]:t[i]:this.has(e)?this.values[e]:t},has:function(e){return e in this.values},alt:function(e,t,i){for(var n=0;n<i.length;++n)if(t===i[n]){this.set(e,t);break}},integer:function(e,t){/^-?\d+$/.test(t)&&this.set(e,parseInt(t,10))},percent:function(e,t){return!!(t.match(/^([\d]{1,3})(\.[\d]*)?%$/)&&0<=(t=parseFloat(t))&&t<=100)&&(this.set(e,t),!0)}};var yi=d.createElement&&d.createElement("textarea"),vi={c:"span",i:"i",b:"b",u:"u",ruby:"ruby",rt:"rt",v:"span",lang:"span"},_i={white:"rgba(255,255,255,1)",lime:"rgba(0,255,0,1)",cyan:"rgba(0,255,255,1)",red:"rgba(255,0,0,1)",yellow:"rgba(255,255,0,1)",magenta:"rgba(255,0,255,1)",blue:"rgba(0,0,255,1)",black:"rgba(0,0,0,1)"},bi={v:"title",lang:"lang"},Ti={rt:"ruby"};function Si(e,t){for(var i,n,r,a,s,o,u,l,c,d,h=e.document.createElement("div"),p=h,f=[];null!==(i=function(){if(!t)return null;var e=t.match(/^([^<]*)(<[^>]*>?)?/);return e=e[1]||e[2],t=t.substr(e.length),e}());)"<"!==i[0]?p.appendChild(e.document.createTextNode((s=i,yi.innerHTML=s,s=yi.textContent,yi.textContent="",s))):"/"!==i[1]?(a=pi(i.substr(1,i.length-2)))?(n=e.document.createProcessingInstruction("timestamp",a),p.appendChild(n)):(r=i.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/))&&(l=r[1],c=r[3],d=void 0,d=vi[l],(n=d?(d=e.document.createElement(d),(l=bi[l])&&c&&(d[l]=c.trim()),d):null)&&(o=p,Ti[(u=n).localName]&&Ti[u.localName]!==o.localName||(r[2]&&((a=r[2].split(".")).forEach(function(e){var t=/^bg_/.test(e),e=t?e.slice(3):e;_i.hasOwnProperty(e)&&(e=_i[e],n.style[t?"background-color":"color"]=e)}),n.className=a.join(" ")),f.push(r[1]),p.appendChild(n),p=n))):f.length&&f[f.length-1]===i.substr(2).replace(">","")&&(f.pop(),p=p.parentNode);return h}var Ei=[[1470,1470],[1472,1472],[1475,1475],[1478,1478],[1488,1514],[1520,1524],[1544,1544],[1547,1547],[1549,1549],[1563,1563],[1566,1610],[1645,1647],[1649,1749],[1765,1766],[1774,1775],[1786,1805],[1807,1808],[1810,1839],[1869,1957],[1969,1969],[1984,2026],[2036,2037],[2042,2042],[2048,2069],[2074,2074],[2084,2084],[2088,2088],[2096,2110],[2112,2136],[2142,2142],[2208,2208],[2210,2220],[8207,8207],[64285,64285],[64287,64296],[64298,64310],[64312,64316],[64318,64318],[64320,64321],[64323,64324],[64326,64449],[64467,64829],[64848,64911],[64914,64967],[65008,65020],[65136,65140],[65142,65276],[67584,67589],[67592,67592],[67594,67637],[67639,67640],[67644,67644],[67647,67669],[67671,67679],[67840,67867],[67872,67897],[67903,67903],[67968,68023],[68030,68031],[68096,68096],[68112,68115],[68117,68119],[68121,68147],[68160,68167],[68176,68184],[68192,68223],[68352,68405],[68416,68437],[68440,68466],[68472,68479],[68608,68680],[126464,126467],[126469,126495],[126497,126498],[126500,126500],[126503,126503],[126505,126514],[126516,126519],[126521,126521],[126523,126523],[126530,126530],[126535,126535],[126537,126537],[126539,126539],[126541,126543],[126545,126546],[126548,126548],[126551,126551],[126553,126553],[126555,126555],[126557,126557],[126559,126559],[126561,126562],[126564,126564],[126567,126570],[126572,126578],[126580,126583],[126585,126588],[126590,126590],[126592,126601],[126603,126619],[126625,126627],[126629,126633],[126635,126651],[1114109,1114109]];function ki(e){var t=[],i="";if(!e||!e.childNodes)return"ltr";function a(e,t){for(var i=t.childNodes.length-1;0<=i;i--)e.push(t.childNodes[i])}for(a(t,e);i=function e(t){if(!t||!t.length)return null;var i=t.pop(),n=i.textContent||i.innerText;if(n){var r=n.match(/^.*(\n|\r)/);return r?r[t.length=0]:n}return"ruby"===i.tagName?e(t):i.childNodes?(a(t,i),e(t)):void 0}(t);)for(var n=0;n<i.length;n++)if(function(e){for(var t=0;t<Ei.length;t++){var i=Ei[t];if(e>=i[0]&&e<=i[1])return 1}}(i.charCodeAt(n)))return"rtl";return"ltr"}function Ci(){}function wi(e,t,i){Ci.call(this),this.cue=t,this.cueDiv=Si(e,t.text);var n={color:"rgba(255, 255, 255, 1)",backgroundColor:"rgba(0, 0, 0, 0.8)",position:"relative",left:0,right:0,top:0,bottom:0,display:"inline",writingMode:""===t.vertical?"horizontal-tb":"lr"===t.vertical?"vertical-lr":"vertical-rl",unicodeBidi:"plaintext"};this.applyStyles(n,this.cueDiv),this.div=e.document.createElement("div"),n={direction:ki(this.cueDiv),writingMode:""===t.vertical?"horizontal-tb":"lr"===t.vertical?"vertical-lr":"vertical-rl",unicodeBidi:"plaintext",textAlign:"middle"===t.align?"center":t.align,font:i.font,whiteSpace:"pre-line",position:"absolute"},this.applyStyles(n),this.div.appendChild(this.cueDiv);var r=0;switch(t.positionAlign){case"start":r=t.position;break;case"center":r=t.position-t.size/2;break;case"end":r=t.position-t.size}""===t.vertical?this.applyStyles({left:this.formatStyle(r,"%"),width:this.formatStyle(t.size,"%")}):this.applyStyles({top:this.formatStyle(r,"%"),height:this.formatStyle(t.size,"%")}),this.move=function(e){this.applyStyles({top:this.formatStyle(e.top,"px"),bottom:this.formatStyle(e.bottom,"px"),left:this.formatStyle(e.left,"px"),right:this.formatStyle(e.right,"px"),height:this.formatStyle(e.height,"px"),width:this.formatStyle(e.width,"px")})}}function Ii(e){var t,i,n,r;e.div&&(t=e.div.offsetHeight,i=e.div.offsetWidth,n=e.div.offsetTop,r=(r=e.div.childNodes)&&(r=r[0])&&r.getClientRects&&r.getClientRects(),e=e.div.getBoundingClientRect(),r=r?Math.max(r[0]&&r[0].height||0,e.height/r.length):0),this.left=e.left,this.right=e.right,this.top=e.top||n,this.height=e.height||t,this.bottom=e.bottom||n+(e.height||t),this.width=e.width||i,this.lineHeight=void 0!==r?r:e.lineHeight}function xi(e,t,o,u){var i,n=new Ii(t),r=t.cue,a=function(e){if("number"==typeof e.line&&(e.snapToLines||0<=e.line&&e.line<=100))return e.line;if(!e.track||!e.track.textTrackList||!e.track.textTrackList.mediaElement)return-1;for(var t=e.track,i=t.textTrackList,n=0,r=0;r<i.length&&i[r]!==t;r++)"showing"===i[r].mode&&n++;return-1*++n}(r),s=[];if(r.snapToLines){switch(r.vertical){case"":s=["+y","-y"],i="height";break;case"rl":s=["+x","-x"],i="width";break;case"lr":s=["-x","+x"],i="width"}var l=n.lineHeight,c=l*Math.round(a),d=o[i]+l,h=s[0];Math.abs(c)>d&&(c=c<0?-1:1,c*=Math.ceil(d/l)*l),a<0&&(c+=""===r.vertical?o.height:o.width,s=s.reverse()),n.move(h,c)}else{var p=n.lineHeight/o.height*100;switch(r.lineAlign){case"center":a-=p/2;break;case"end":a-=p}switch(r.vertical){case"":t.applyStyles({top:t.formatStyle(a,"%")});break;case"rl":t.applyStyles({left:t.formatStyle(a,"%")});break;case"lr":t.applyStyles({right:t.formatStyle(a,"%")})}s=["+y","-x","+x","-y"],n=new Ii(t)}n=function(e,t){for(var i,n=new Ii(e),r=1,a=0;a<t.length;a++){for(;e.overlapsOppositeAxis(o,t[a])||e.within(o)&&e.overlapsAny(u);)e.move(t[a]);if(e.within(o))return e;var s=e.intersectPercentage(o);s<r&&(i=new Ii(e),r=s),e=new Ii(n)}return i||n}(n,s);t.move(n.toCSSCompatValues(o))}function Ai(){}Ci.prototype.applyStyles=function(e,t){for(var i in t=t||this.div,e)e.hasOwnProperty(i)&&(t.style[i]=e[i])},Ci.prototype.formatStyle=function(e,t){return 0===e?0:e+t},(wi.prototype=ci(Ci.prototype)).constructor=wi,Ii.prototype.move=function(e,t){switch(t=void 0!==t?t:this.lineHeight,e){case"+x":this.left+=t,this.right+=t;break;case"-x":this.left-=t,this.right-=t;break;case"+y":this.top+=t,this.bottom+=t;break;case"-y":this.top-=t,this.bottom-=t}},Ii.prototype.overlaps=function(e){return this.left<e.right&&this.right>e.left&&this.top<e.bottom&&this.bottom>e.top},Ii.prototype.overlapsAny=function(e){for(var t=0;t<e.length;t++)if(this.overlaps(e[t]))return!0;return!1},Ii.prototype.within=function(e){return this.top>=e.top&&this.bottom<=e.bottom&&this.left>=e.left&&this.right<=e.right},Ii.prototype.overlapsOppositeAxis=function(e,t){switch(t){case"+x":return this.left<e.left;case"-x":return this.right>e.right;case"+y":return this.top<e.top;case"-y":return this.bottom>e.bottom}},Ii.prototype.intersectPercentage=function(e){return Math.max(0,Math.min(this.right,e.right)-Math.max(this.left,e.left))*Math.max(0,Math.min(this.bottom,e.bottom)-Math.max(this.top,e.top))/(this.height*this.width)},Ii.prototype.toCSSCompatValues=function(e){return{top:this.top-e.top,bottom:e.bottom-this.bottom,left:this.left-e.left,right:e.right-this.right,height:this.height,width:this.width}},Ii.getSimpleBoxPosition=function(e){var t=e.div?e.div.offsetHeight:e.tagName?e.offsetHeight:0,i=e.div?e.div.offsetWidth:e.tagName?e.offsetWidth:0,n=e.div?e.div.offsetTop:e.tagName?e.offsetTop:0;return{left:(e=e.div?e.div.getBoundingClientRect():e.tagName?e.getBoundingClientRect():e).left,right:e.right,top:e.top||n,height:e.height||t,bottom:e.bottom||n+(e.height||t),width:e.width||i}},Ai.StringDecoder=function(){return{decode:function(e){if(!e)return"";if("string"!=typeof e)throw new Error("Error - expected string data.");return decodeURIComponent(encodeURIComponent(e))}}},Ai.convertCueToDOMTree=function(e,t){return e&&t?Si(e,t):null};Ai.processCues=function(n,r,e){if(!n||!r||!e)return null;for(;e.firstChild;)e.removeChild(e.firstChild);var a=n.document.createElement("div");if(a.style.position="absolute",a.style.left="0",a.style.right="0",a.style.top="0",a.style.bottom="0",a.style.margin="1.5%",e.appendChild(a),function(e){for(var t=0;t<e.length;t++)if(e[t].hasBeenReset||!e[t].displayState)return 1}(r)){var s=[],o=Ii.getSimpleBoxPosition(a),u={font:Math.round(.05*o.height*100)/100+"px sans-serif"};!function(){for(var e,t,i=0;i<r.length;i++)t=r[i],e=new wi(n,t,u),a.appendChild(e.div),xi(0,e,o,s),t.displayState=e.div,s.push(Ii.getSimpleBoxPosition(e))}()}else for(var t=0;t<r.length;t++)a.appendChild(r[t].displayState)},(Ai.Parser=function(e,t,i){i||(i=t,t={}),t=t||{},this.window=e,this.vttjs=t,this.state="INITIAL",this.buffer="",this.decoder=i||new TextDecoder("utf8"),this.regionList=[]}).prototype={reportOrThrowError:function(e){if(!(e instanceof hi))throw e;this.onparsingerror&&this.onparsingerror(e)},parse:function(e){var n=this;function t(){for(var e=n.buffer,t=0;t<e.length&&"\r"!==e[t]&&"\n"!==e[t];)++t;var i=e.substr(0,t);return"\r"===e[t]&&++t,"\n"===e[t]&&++t,n.buffer=e.substr(t),i}function i(e){e.match(/X-TIMESTAMP-MAP/)?mi(e,function(e,t){var i;"X-TIMESTAMP-MAP"===e&&(t=t,i=new fi,mi(t,function(e,t){switch(e){case"MPEGT":i.integer(e+"S",t);break;case"LOCA":i.set(e+"L",pi(t))}},/[^\d]:/,/,/),n.ontimestampmap&&n.ontimestampmap({MPEGTS:i.get("MPEGTS"),LOCAL:i.get("LOCAL")}))},/=/):mi(e,function(e,t){var r;"Region"===e&&(t=t,r=new fi,mi(t,function(e,t){switch(e){case"id":r.set(e,t);break;case"width":r.percent(e,t);break;case"lines":r.integer(e,t);break;case"regionanchor":case"viewportanchor":var i=t.split(",");if(2!==i.length)break;var n=new fi;if(n.percent("x",i[0]),n.percent("y",i[1]),!n.has("x")||!n.has("y"))break;r.set(e+"X",n.get("x")),r.set(e+"Y",n.get("y"));break;case"scroll":r.alt(e,t,["up"])}},/=/,/\s/),r.has("id")&&((t=new(n.vttjs.VTTRegion||n.window.VTTRegion)).width=r.get("width",100),t.lines=r.get("lines",3),t.regionAnchorX=r.get("regionanchorX",0),t.regionAnchorY=r.get("regionanchorY",100),t.viewportAnchorX=r.get("viewportanchorX",0),t.viewportAnchorY=r.get("viewportanchorY",100),t.scroll=r.get("scroll",""),n.onregion&&n.onregion(t),n.regionList.push({id:r.get("id"),region:t})))},/:/)}e&&(n.buffer+=n.decoder.decode(e,{stream:!0}));try{if("INITIAL"===n.state){if(!/\r\n|\n/.test(n.buffer))return this;var r,a=(r=t()).match(/^WEBVTT([ \t].*)?$/);if(!a||!a[0])throw new hi(hi.Errors.BadSignature);n.state="HEADER"}for(var s=!1;n.buffer;){if(!/\r\n|\n/.test(n.buffer))return this;switch(s?s=!1:r=t(),n.state){case"HEADER":/:/.test(r)?i(r):r||(n.state="ID");continue;case"NOTE":r||(n.state="ID");continue;case"ID":if(/^NOTE($|[ \t])/.test(r)){n.state="NOTE";break}if(!r)continue;n.cue=new(n.vttjs.VTTCue||n.window.VTTCue)(0,0,"");try{n.cue.align="center"}catch(e){n.cue.align="middle"}if(n.state="CUE",-1===r.indexOf("--\x3e")){n.cue.id=r;continue}case"CUE":try{gi(r,n.cue,n.regionList)}catch(e){n.reportOrThrowError(e),n.cue=null,n.state="BADCUE";continue}n.state="CUETEXT";continue;case"CUETEXT":var o=-1!==r.indexOf("--\x3e");if(!r||o&&(s=!0)){n.oncue&&n.oncue(n.cue),n.cue=null,n.state="ID";continue}n.cue.text&&(n.cue.text+="\n"),n.cue.text+=r.replace(/\u2028/g,"\n").replace(/u2029/g,"\n");continue;case"BADCUE":r||(n.state="ID");continue}}}catch(e){n.reportOrThrowError(e),"CUETEXT"===n.state&&n.cue&&n.oncue&&n.oncue(n.cue),n.cue=null,n.state="INITIAL"===n.state?"BADWEBVTT":"BADCUE"}return this},flush:function(){var t=this;try{if(t.buffer+=t.decoder.decode(),!t.cue&&"HEADER"!==t.state||(t.buffer+="\n\n",t.parse()),"INITIAL"===t.state)throw new hi(hi.Errors.BadSignature)}catch(e){t.reportOrThrowError(e)}return t.onflush&&t.onflush(),this}};var Pi=Ai,Li={"":1,lr:1,rl:1},Di={start:1,center:1,end:1,left:1,right:1,auto:1,"line-left":1,"line-right":1};function Oi(e){return"string"==typeof e&&(!!Di[e.toLowerCase()]&&e.toLowerCase())}function Ri(e,t,i){this.hasBeenReset=!1;var n="",r=!1,a=e,s=t,o=i,u=null,l="",c=!0,d="auto",h="start",p="auto",f="auto",m=100,g="center";Object.defineProperties(this,{id:{enumerable:!0,get:function(){return n},set:function(e){n=""+e}},pauseOnExit:{enumerable:!0,get:function(){return r},set:function(e){r=!!e}},startTime:{enumerable:!0,get:function(){return a},set:function(e){if("number"!=typeof e)throw new TypeError("Start time must be set to a number.");a=e,this.hasBeenReset=!0}},endTime:{enumerable:!0,get:function(){return s},set:function(e){if("number"!=typeof e)throw new TypeError("End time must be set to a number.");s=e,this.hasBeenReset=!0}},text:{enumerable:!0,get:function(){return o},set:function(e){o=""+e,this.hasBeenReset=!0}},region:{enumerable:!0,get:function(){return u},set:function(e){u=e,this.hasBeenReset=!0}},vertical:{enumerable:!0,get:function(){return l},set:function(e){e="string"==typeof(e=e)&&(!!Li[e.toLowerCase()]&&e.toLowerCase());if(!1===e)throw new SyntaxError("Vertical: an invalid or illegal direction string was specified.");l=e,this.hasBeenReset=!0}},snapToLines:{enumerable:!0,get:function(){return c},set:function(e){c=!!e,this.hasBeenReset=!0}},line:{enumerable:!0,get:function(){return d},set:function(e){if("number"!=typeof e&&"auto"!==e)throw new SyntaxError("Line: an invalid number or illegal string was specified.");d=e,this.hasBeenReset=!0}},lineAlign:{enumerable:!0,get:function(){return h},set:function(e){e=Oi(e);e&&(h=e,this.hasBeenReset=!0)}},position:{enumerable:!0,get:function(){return p},set:function(e){if(e<0||100<e)throw new Error("Position must be between 0 and 100.");p=e,this.hasBeenReset=!0}},positionAlign:{enumerable:!0,get:function(){return f},set:function(e){e=Oi(e);e&&(f=e,this.hasBeenReset=!0)}},size:{enumerable:!0,get:function(){return m},set:function(e){if(e<0||100<e)throw new Error("Size must be between 0 and 100.");m=e,this.hasBeenReset=!0}},align:{enumerable:!0,get:function(){return g},set:function(e){e=Oi(e);if(!e)throw new SyntaxError("align: an invalid or illegal alignment string was specified.");g=e,this.hasBeenReset=!0}}}),this.displayState=void 0}Ri.prototype.getCueAsHTML=function(){return WebVTT.convertCueToDOMTree(window,this.text)};var Mi=Ri,Ni={"":!0,up:!0};function Ui(e){return"number"==typeof e&&0<=e&&e<=100}function Bi(){var t=100,i=3,n=0,r=100,a=0,s=100,o="";Object.defineProperties(this,{width:{enumerable:!0,get:function(){return t},set:function(e){if(!Ui(e))throw new Error("Width must be between 0 and 100.");t=e}},lines:{enumerable:!0,get:function(){return i},set:function(e){if("number"!=typeof e)throw new TypeError("Lines must be set to a number.");i=e}},regionAnchorY:{enumerable:!0,get:function(){return r},set:function(e){if(!Ui(e))throw new Error("RegionAnchorX must be between 0 and 100.");r=e}},regionAnchorX:{enumerable:!0,get:function(){return n},set:function(e){if(!Ui(e))throw new Error("RegionAnchorY must be between 0 and 100.");n=e}},viewportAnchorY:{enumerable:!0,get:function(){return s},set:function(e){if(!Ui(e))throw new Error("ViewportAnchorY must be between 0 and 100.");s=e}},viewportAnchorX:{enumerable:!0,get:function(){return a},set:function(e){if(!Ui(e))throw new Error("ViewportAnchorX must be between 0 and 100.");a=e}},scroll:{enumerable:!0,get:function(){return o},set:function(e){e="string"==typeof(e=e)&&(!!Ni[e.toLowerCase()]&&e.toLowerCase());!1===e||(o=e)}}})}var Fi=t(function(e){e=e.exports={WebVTT:Pi,VTTCue:Mi,VTTRegion:Bi};_.vttjs=e,_.WebVTT=e.WebVTT;var t=e.VTTCue,i=e.VTTRegion,n=_.VTTCue,r=_.VTTRegion;e.shim=function(){_.VTTCue=t,_.VTTRegion=i},e.restore=function(){_.VTTCue=n,_.VTTRegion=r},_.VTTCue||e.shim()});Fi.WebVTT,Fi.VTTCue,Fi.VTTRegion;var ji=function(n){function i(t,e){var i;return void 0===e&&(e=function(){}),(t=void 0===t?{}:t).reportTouchActivity=!1,(i=n.call(this,null,t,e)||this).onDurationChange_=function(e){return i.onDurationChange(e)},i.trackProgress_=function(e){return i.trackProgress(e)},i.trackCurrentTime_=function(e){return i.trackCurrentTime(e)},i.stopTrackingCurrentTime_=function(e){return i.stopTrackingCurrentTime(e)},i.disposeSourceHandler_=function(e){return i.disposeSourceHandler(e)},i.hasStarted_=!1,i.on("playing",function(){this.hasStarted_=!0}),i.on("loadstart",function(){this.hasStarted_=!1}),li.names.forEach(function(e){e=li[e];t&&t[e.getterName]&&(i[e.privateName]=t[e.getterName])}),i.featuresProgressEvents||i.manualProgressOn(),i.featuresTimeupdateEvents||i.manualTimeUpdatesOn(),["Text","Audio","Video"].forEach(function(e){!1===t["native"+e+"Tracks"]&&(i["featuresNative"+e+"Tracks"]=!1)}),!1===t.nativeCaptions||!1===t.nativeTextTracks?i.featuresNativeTextTracks=!1:!0!==t.nativeCaptions&&!0!==t.nativeTextTracks||(i.featuresNativeTextTracks=!0),i.featuresNativeTextTracks||i.emulateTextTracks(),i.preloadTextTracks=!1!==t.preloadTextTracks,i.autoRemoteTextTracks_=new li.text.ListClass,i.initTrackListeners(),t.nativeControlsForTouch||i.emitTapEvents(),i.constructor&&(i.name_=i.constructor.name||"Unknown Tech"),i}vt(i,n);var e=i.prototype;return e.triggerSourceset=function(e){var t=this;this.isReady_||this.one("ready",function(){return t.setTimeout(function(){return t.triggerSourceset(e)},1)}),this.trigger({src:e,type:"sourceset"})},e.manualProgressOn=function(){this.on("durationchange",this.onDurationChange_),this.manualProgress=!0,this.one("ready",this.trackProgress_)},e.manualProgressOff=function(){this.manualProgress=!1,this.stopTrackingProgress(),this.off("durationchange",this.onDurationChange_)},e.trackProgress=function(e){this.stopTrackingProgress(),this.progressInterval=this.setInterval(Xe(this,function(){var e=this.bufferedPercent();this.bufferedPercent_!==e&&this.trigger("progress"),1===(this.bufferedPercent_=e)&&this.stopTrackingProgress()}),500)},e.onDurationChange=function(e){this.duration_=this.duration()},e.buffered=function(){return Tt(0,0)},e.bufferedPercent=function(){return St(this.buffered(),this.duration_)},e.stopTrackingProgress=function(){this.clearInterval(this.progressInterval)},e.manualTimeUpdatesOn=function(){this.manualTimeUpdates=!0,this.on("play",this.trackCurrentTime_),this.on("pause",this.stopTrackingCurrentTime_)},e.manualTimeUpdatesOff=function(){this.manualTimeUpdates=!1,this.stopTrackingCurrentTime(),this.off("play",this.trackCurrentTime_),this.off("pause",this.stopTrackingCurrentTime_)},e.trackCurrentTime=function(){this.currentTimeInterval&&this.stopTrackingCurrentTime(),this.currentTimeInterval=this.setInterval(function(){this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},250)},e.stopTrackingCurrentTime=function(){this.clearInterval(this.currentTimeInterval),this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},e.dispose=function(){this.clearTracks(oi.names),this.manualProgress&&this.manualProgressOff(),this.manualTimeUpdates&&this.manualTimeUpdatesOff(),n.prototype.dispose.call(this)},e.clearTracks=function(e){var r=this;(e=[].concat(e)).forEach(function(e){for(var t=r[e+"Tracks"]()||[],i=t.length;i--;){var n=t[i];"text"===e&&r.removeRemoteTextTrack(n),t.removeTrack(n)}})},e.cleanupAutoTextTracks=function(){for(var e=this.autoRemoteTextTracks_||[],t=e.length;t--;){var i=e[t];this.removeRemoteTextTrack(i)}},e.reset=function(){},e.crossOrigin=function(){},e.setCrossOrigin=function(){},e.error=function(e){return void 0!==e&&(this.error_=new Et(e),this.trigger("error")),this.error_},e.played=function(){return this.hasStarted_?Tt(0,0):Tt()},e.play=function(){},e.setScrubbing=function(){},e.scrubbing=function(){},e.setCurrentTime=function(){this.manualTimeUpdates&&this.trigger({type:"timeupdate",target:this,manuallyTriggered:!0})},e.initTrackListeners=function(){var r=this;oi.names.forEach(function(e){function t(){r.trigger(e+"trackchange")}var i=oi[e],n=r[i.getterName]();n.addEventListener("removetrack",t),n.addEventListener("addtrack",t),r.on("dispose",function(){n.removeEventListener("removetrack",t),n.removeEventListener("addtrack",t)})})},e.addWebVttScript_=function(){var e,t=this;_.WebVTT||(d.body.contains(this.el())?!this.options_["vtt.js"]&&w(Fi)&&0<Object.keys(Fi).length?this.trigger("vttjsloaded"):((e=d.createElement("script")).src=this.options_["vtt.js"]||"https://vjs.zencdn.net/vttjs/0.14.1/vtt.min.js",e.onload=function(){t.trigger("vttjsloaded")},e.onerror=function(){t.trigger("vttjserror")},this.on("dispose",function(){e.onload=null,e.onerror=null}),_.WebVTT=!0,this.el().parentNode.appendChild(e)):this.ready(this.addWebVttScript_))},e.emulateTextTracks=function(){function t(e){return n.addTrack(e.track)}function i(e){return n.removeTrack(e.track)}var e=this,n=this.textTracks(),r=this.remoteTextTracks();r.on("addtrack",t),r.on("removetrack",i),this.addWebVttScript_();function a(){return e.trigger("texttrackchange")}function s(){a();for(var e=0;e<n.length;e++){var t=n[e];t.removeEventListener("cuechange",a),"showing"===t.mode&&t.addEventListener("cuechange",a)}}s(),n.addEventListener("change",s),n.addEventListener("addtrack",s),n.addEventListener("removetrack",s),this.on("dispose",function(){r.off("addtrack",t),r.off("removetrack",i),n.removeEventListener("change",s),n.removeEventListener("addtrack",s),n.removeEventListener("removetrack",s);for(var e=0;e<n.length;e++)n[e].removeEventListener("cuechange",a)})},e.addTextTrack=function(e,t,i){if(!e)throw new Error("TextTrack kind is required but was not provided");return function(e,t,i,n,r){void 0===r&&(r={});var a=e.textTracks();return r.kind=t,i&&(r.label=i),n&&(r.language=n),r.tech=e,r=new li.text.TrackClass(r),a.addTrack(r),r}(this,e,t,i)},e.createRemoteTextTrack=function(e){e=pt(e,{tech:this});return new ui.remoteTextEl.TrackClass(e)},e.addRemoteTextTrack=function(e,t){var i=this,n=this.createRemoteTextTrack(e=void 0===e?{}:e);return!0!==t&&!1!==t&&(y.warn('Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js'),t=!0),this.remoteTextTrackEls().addTrackElement_(n),this.remoteTextTracks().addTrack(n.track),!0!==t&&this.ready(function(){return i.autoRemoteTextTracks_.addTrack(n.track)}),n},e.removeRemoteTextTrack=function(e){var t=this.remoteTextTrackEls().getTrackElementByTrack_(e);this.remoteTextTrackEls().removeTrackElement_(t),this.remoteTextTracks().removeTrack(e),this.autoRemoteTextTracks_.removeTrack(e)},e.getVideoPlaybackQuality=function(){return{}},e.requestPictureInPicture=function(){var e=this.options_.Promise||_.Promise;if(e)return e.reject()},e.disablePictureInPicture=function(){return!0},e.setDisablePictureInPicture=function(){},e.setPoster=function(){},e.playsinline=function(){},e.setPlaysinline=function(){},e.overrideNativeAudioTracks=function(){},e.overrideNativeVideoTracks=function(){},e.canPlayType=function(){return""},i.canPlayType=function(){return""},i.canPlaySource=function(e,t){return i.canPlayType(e.type)},i.isTech=function(e){return e.prototype instanceof i||e instanceof i||e===i},i.registerTech=function(e,t){if(i.techs_||(i.techs_={}),!i.isTech(t))throw new Error("Tech "+e+" must be a Tech");if(!i.canPlayType)throw new Error("Techs must have a static canPlayType method on them");if(!i.canPlaySource)throw new Error("Techs must have a static canPlaySource method on them");return e=ht(e),i.techs_[e]=t,i.techs_[dt(e)]=t,"Tech"!==e&&i.defaultTechOrder_.push(e),t},i.getTech=function(e){if(e)return i.techs_&&i.techs_[e]?i.techs_[e]:(e=ht(e),_&&_.videojs&&_.videojs[e]?(y.warn("The "+e+" tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)"),_.videojs[e]):void 0)},i}(gt);li.names.forEach(function(e){var t=li[e];ji.prototype[t.getterName]=function(){return this[t.privateName]=this[t.privateName]||new t.ListClass,this[t.privateName]}}),ji.prototype.featuresVolumeControl=!0,ji.prototype.featuresMuteControl=!0,ji.prototype.featuresFullscreenResize=!1,ji.prototype.featuresPlaybackRate=!1,ji.prototype.featuresProgressEvents=!1,ji.prototype.featuresSourceset=!1,ji.prototype.featuresTimeupdateEvents=!1,ji.prototype.featuresNativeTextTracks=!1,ji.withSourceHandlers=function(r){r.registerSourceHandler=function(e,t){var i=(i=r.sourceHandlers)||(r.sourceHandlers=[]);void 0===t&&(t=i.length),i.splice(t,0,e)},r.canPlayType=function(e){for(var t,i=r.sourceHandlers||[],n=0;n<i.length;n++)if(t=i[n].canPlayType(e))return t;return""},r.selectSourceHandler=function(e,t){for(var i=r.sourceHandlers||[],n=0;n<i.length;n++)if(i[n].canHandleSource(e,t))return i[n];return null},r.canPlaySource=function(e,t){var i=r.selectSourceHandler(e,t);return i?i.canHandleSource(e,t):""};["seekable","seeking","duration"].forEach(function(e){var t=this[e];"function"==typeof t&&(this[e]=function(){return this.sourceHandler_&&this.sourceHandler_[e]?this.sourceHandler_[e].apply(this.sourceHandler_,arguments):t.apply(this,arguments)})},r.prototype),r.prototype.setSource=function(e){var t=r.selectSourceHandler(e,this.options_);t||(r.nativeSourceHandler?t=r.nativeSourceHandler:y.error("No source handler found for the current source.")),this.disposeSourceHandler(),this.off("dispose",this.disposeSourceHandler_),t!==r.nativeSourceHandler&&(this.currentSource_=e),this.sourceHandler_=t.handleSource(e,this,this.options_),this.one("dispose",this.disposeSourceHandler_)},r.prototype.disposeSourceHandler=function(){this.currentSource_&&(this.clearTracks(["audio","video"]),this.currentSource_=null),this.cleanupAutoTextTracks(),this.sourceHandler_&&(this.sourceHandler_.dispose&&this.sourceHandler_.dispose(),this.sourceHandler_=null)}},gt.registerComponent("Tech",ji),ji.registerTech("Tech",ji),ji.defaultTechOrder_=[];var Hi={},qi={},Vi={};function Wi(e,t,i){e.setTimeout(function(){return function i(n,e,r,a,s,o){void 0===n&&(n={});void 0===e&&(e=[]);void 0===s&&(s=[]);void 0===o&&(o=!1);var t=e,e=t[0],u=t.slice(1);if("string"==typeof e)i(n,Hi[e],r,a,s,o);else if(e){var l=Qi(a,e);if(!l.setSource)return s.push(l),i(n,u,r,a,s,o);l.setSource(k({},n),function(e,t){return e?i(n,u,r,a,s,o):(s.push(l),void i(t,n.type===t.type?u:Hi[t.type],r,a,s,o))})}else u.length?i(n,u,r,a,s,o):o?r(n,s):i(n,Hi["*"],r,a,s,!0)}(t,Hi[t.type],i,e)},1)}function zi(e,t,i,n){void 0===n&&(n=null);var r="call"+ht(i),r=e.reduce(Yi(r),n),n=r===Vi,r=n?null:t[i](r);return function(e,t,i,n){for(var r=e.length-1;0<=r;r--){var a=e[r];a[t]&&a[t](n,i)}}(e,i,r,n),r}var Gi={buffered:1,currentTime:1,duration:1,muted:1,played:1,paused:1,seekable:1,volume:1,ended:1},Xi={setCurrentTime:1,setMuted:1,setVolume:1},Ki={play:1,pause:1};function Yi(i){return function(e,t){return e===Vi?Vi:t[i]?t[i](e):e}}function Qi(e,t){var i=qi[e.id()],n=null;if(null==i)return n=t(e),qi[e.id()]=[[t,n]],n;for(var r=0;r<i.length;r++){var a=i[r],s=a[0],a=a[1];s===t&&(n=a)}return null===n&&(n=t(e),i.push([t,n])),n}function $i(e){return e=jt(e=void 0===e?"":e),Zi[e.toLowerCase()]||""}function Ji(e){var t;return e=Array.isArray(e)?(t=[],e.forEach(function(e){e=Ji(e),Array.isArray(e)?t=t.concat(e):C(e)&&t.push(e)}),t):"string"==typeof e&&e.trim()?[en({src:e})]:C(e)&&"string"==typeof e.src&&e.src&&e.src.trim()?[en(e)]:[]}var Zi={opus:"video/ogg",ogv:"video/ogg",mp4:"video/mp4",mov:"video/mp4",m4v:"video/mp4",mkv:"video/x-matroska",m4a:"audio/mp4",mp3:"audio/mpeg",aac:"audio/aac",caf:"audio/x-caf",flac:"audio/flac",oga:"audio/ogg",wav:"audio/wav",m3u8:"application/x-mpegURL",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",png:"image/png",svg:"image/svg+xml",webp:"image/webp"};function en(e){var t;return e.type||(t=$i(e.src))&&(e.type=t),e}D=function(u){function e(e,t,i){var n=pt({createEl:!1},t),i=u.call(this,e,n,i)||this;if(t.playerOptions.sources&&0!==t.playerOptions.sources.length)e.src(t.playerOptions.sources);else for(var r=0,a=t.playerOptions.techOrder;r<a.length;r++){var s=ht(a[r]),o=ji.getTech(s);if((o=!s?gt.getComponent(s):o)&&o.isSupported()){e.loadTech_(s);break}}return i}return vt(e,u),e}(gt);gt.registerComponent("MediaLoader",D);H=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.handleMouseOver_=function(e){return i.handleMouseOver(e)},i.handleMouseOut_=function(e){return i.handleMouseOut(e)},i.handleClick_=function(e){return i.handleClick(e)},i.handleKeyDown_=function(e){return i.handleKeyDown(e)},i.emitTapEvents(),i.enable(),i}vt(e,n);var t=e.prototype;return t.createEl=function(e,t,i){void 0===e&&(e="div"),void 0===t&&(t={}),void 0===i&&(i={}),t=k({className:this.buildCSSClass(),tabIndex:0},t),"button"===e&&y.error("Creating a ClickableComponent with an HTML element of "+e+" is not supported; use a Button instead."),i=k({role:"button"},i),this.tabIndex_=t.tabIndex;i=te(e,t,i);return i.appendChild(te("span",{className:"vjs-icon-placeholder"},{"aria-hidden":!0})),this.createControlTextEl(i),i},t.dispose=function(){this.controlTextEl_=null,n.prototype.dispose.call(this)},t.createControlTextEl=function(e){return this.controlTextEl_=te("span",{className:"vjs-control-text"},{"aria-live":"polite"}),e&&e.appendChild(this.controlTextEl_),this.controlText(this.controlText_,e),this.controlTextEl_},t.controlText=function(e,t){if(void 0===t&&(t=this.el()),void 0===e)return this.controlText_||"Need Text";var i=this.localize(e);this.controlText_=e,ie(this.controlTextEl_,i),this.nonIconControl||this.player_.options_.noUITitleAttributes||t.setAttribute("title",i)},t.buildCSSClass=function(){return"vjs-control vjs-button "+n.prototype.buildCSSClass.call(this)},t.enable=function(){this.enabled_||(this.enabled_=!0,this.removeClass("vjs-disabled"),this.el_.setAttribute("aria-disabled","false"),"undefined"!=typeof this.tabIndex_&&this.el_.setAttribute("tabIndex",this.tabIndex_),this.on(["tap","click"],this.handleClick_),this.on("keydown",this.handleKeyDown_))},t.disable=function(){this.enabled_=!1,this.addClass("vjs-disabled"),this.el_.setAttribute("aria-disabled","true"),"undefined"!=typeof this.tabIndex_&&this.el_.removeAttribute("tabIndex"),this.off("mouseover",this.handleMouseOver_),this.off("mouseout",this.handleMouseOut_),this.off(["tap","click"],this.handleClick_),this.off("keydown",this.handleKeyDown_)},t.handleLanguagechange=function(){this.controlText(this.controlText_)},t.handleClick=function(e){this.options_.clickHandler&&this.options_.clickHandler.call(this,arguments)},t.handleKeyDown=function(e){Lt.isEventKey(e,"Space")||Lt.isEventKey(e,"Enter")?(e.preventDefault(),e.stopPropagation(),this.trigger("click")):n.prototype.handleKeyDown.call(this,e)},e}(gt);gt.registerComponent("ClickableComponent",H),gt.registerComponent("PosterImage",function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.update(),i.update_=function(e){return i.update(e)},e.on("posterchange",i.update_),i}vt(e,n);var t=e.prototype;return t.dispose=function(){this.player().off("posterchange",this.update_),n.prototype.dispose.call(this)},t.createEl=function(){return te("div",{className:"vjs-poster",tabIndex:-1})},t.update=function(e){var t=this.player().poster();this.setSrc(t),t?this.show():this.hide()},t.setSrc=function(e){this.el_.style.backgroundImage=e?'url("'+e+'")':""},t.handleClick=function(e){var t;this.player_.controls()&&(t=this.player_.usingPlugin("eme")&&this.player_.eme.sessions&&0<this.player_.eme.sessions.length,!this.player_.tech(!0)||(j||U)&&t||this.player_.tech(!0).focus(),this.player_.paused()?It(this.player_.play()):this.player_.pause())},e}(H));var tn="#222",nn={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'};function rn(e,t){var i;if(4===e.length)i=e[1]+e[1]+e[2]+e[2]+e[3]+e[3];else{if(7!==e.length)throw new Error("Invalid color code provided, "+e+"; must be formatted as e.g. #f0e or #f604e2.");i=e.slice(1)}return"rgba("+parseInt(i.slice(0,2),16)+","+parseInt(i.slice(2,4),16)+","+parseInt(i.slice(4,6),16)+","+t+")"}function an(e,t,i){try{e.style[t]=i}catch(e){return}}gt.registerComponent("TextTrackDisplay",function(a){function e(i,e,t){function n(e){return r.updateDisplay(e)}var r=a.call(this,i,e,t)||this;return i.on("loadstart",function(e){return r.toggleDisplay(e)}),i.on("texttrackchange",n),i.on("loadedmetadata",function(e){return r.preselectTrack(e)}),i.ready(Xe(yt(r),function(){if(i.tech_&&i.tech_.featuresNativeTextTracks)this.hide();else{i.on("fullscreenchange",n),i.on("playerresize",n),_.addEventListener("orientationchange",n),i.on("dispose",function(){return _.removeEventListener("orientationchange",n)});for(var e=this.options_.playerOptions.tracks||[],t=0;t<e.length;t++)this.player_.addRemoteTextTrack(e[t],!0);this.preselectTrack()}})),r}vt(e,a);var t=e.prototype;return t.preselectTrack=function(){for(var e,t,i,n={captions:1,subtitles:1},r=this.player_.textTracks(),a=this.player_.cache_.selectedLanguage,s=0;s<r.length;s++){var o=r[s];a&&a.enabled&&a.language&&a.language===o.language&&o.kind in n?i=o.kind!==a.kind&&i||o:a&&!a.enabled?t=e=i=null:o.default&&("descriptions"!==o.kind||e?o.kind in n&&!t&&(t=o):e=o)}i?i.mode="showing":t?t.mode="showing":e&&(e.mode="showing")},t.toggleDisplay=function(){this.player_.tech_&&this.player_.tech_.featuresNativeTextTracks?this.hide():this.show()},t.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-text-track-display"},{"aria-live":"off","aria-atomic":"true"})},t.clearDisplay=function(){"function"==typeof _.WebVTT&&_.WebVTT.processCues(_,[],this.el_)},t.updateDisplay=function(){var e=this.player_.textTracks(),t=this.options_.allowMultipleShowingTracks;if(this.clearDisplay(),t){for(var i=[],n=0;n<e.length;++n){var r=e[n];"showing"===r.mode&&i.push(r)}this.updateForTrack(i)}else{for(var a=null,s=null,o=e.length;o--;){var u=e[o];"showing"===u.mode&&("descriptions"===u.kind?a=u:s=u)}s?("off"!==this.getAttribute("aria-live")&&this.setAttribute("aria-live","off"),this.updateForTrack(s)):a&&("assertive"!==this.getAttribute("aria-live")&&this.setAttribute("aria-live","assertive"),this.updateForTrack(a))}},t.updateDisplayState=function(e){for(var t=this.player_.textTrackSettings.getValues(),i=e.activeCues,n=i.length;n--;){var r,a=i[n];a&&(r=a.displayState,t.color&&(r.firstChild.style.color=t.color),t.textOpacity&&an(r.firstChild,"color",rn(t.color||"#fff",t.textOpacity)),t.backgroundColor&&(r.firstChild.style.backgroundColor=t.backgroundColor),t.backgroundOpacity&&an(r.firstChild,"backgroundColor",rn(t.backgroundColor||"#000",t.backgroundOpacity)),t.windowColor&&(t.windowOpacity?an(r,"backgroundColor",rn(t.windowColor,t.windowOpacity)):r.style.backgroundColor=t.windowColor),t.edgeStyle&&("dropshadow"===t.edgeStyle?r.firstChild.style.textShadow="2px 2px 3px #222, 2px 2px 4px #222, 2px 2px 5px "+tn:"raised"===t.edgeStyle?r.firstChild.style.textShadow="1px 1px #222, 2px 2px #222, 3px 3px "+tn:"depressed"===t.edgeStyle?r.firstChild.style.textShadow="1px 1px #ccc, 0 1px #ccc, -1px -1px #222, 0 -1px "+tn:"uniform"===t.edgeStyle&&(r.firstChild.style.textShadow="0 0 4px #222, 0 0 4px #222, 0 0 4px #222, 0 0 4px "+tn)),t.fontPercent&&1!==t.fontPercent&&(a=_.parseFloat(r.style.fontSize),r.style.fontSize=a*t.fontPercent+"px",r.style.height="auto",r.style.top="auto"),t.fontFamily&&"default"!==t.fontFamily&&("small-caps"===t.fontFamily?r.firstChild.style.fontVariant="small-caps":r.firstChild.style.fontFamily=nn[t.fontFamily]))}},t.updateForTrack=function(e){if(Array.isArray(e)||(e=[e]),"function"==typeof _.WebVTT&&!e.every(function(e){return!e.activeCues})){for(var t=[],i=0;i<e.length;++i)for(var n=e[i],r=0;r<n.activeCues.length;++r)t.push(n.activeCues[r]);_.WebVTT.processCues(_,t,this.el_);for(var a=0;a<e.length;++a){for(var s=e[a],o=0;o<s.activeCues.length;++o){var u=s.activeCues[o].displayState;ae(u,"vjs-text-track-cue"),ae(u,"vjs-text-track-cue-"+(s.language||a))}this.player_.textTrackSettings&&this.updateDisplayState(s)}}},e}(gt)),gt.registerComponent("LoadingSpinner",function(i){function e(){return i.apply(this,arguments)||this}return vt(e,i),e.prototype.createEl=function(){var e=this.player_.isAudio(),t=this.localize(e?"Audio Player":"Video Player"),e=te("span",{className:"vjs-control-text",textContent:this.localize("{1} is loading.",[t])}),t=i.prototype.createEl.call(this,"div",{className:"vjs-loading-spinner",dir:"ltr"});return t.appendChild(e),t},e}(gt));var sn=function(t){function e(){return t.apply(this,arguments)||this}vt(e,t);var i=e.prototype;return i.createEl=function(e,t,i){void 0===t&&(t={}),void 0===i&&(i={});i=te("button",t=k({className:this.buildCSSClass()},t),i=k({type:"button"},i));return i.appendChild(te("span",{className:"vjs-icon-placeholder"},{"aria-hidden":!0})),this.createControlTextEl(i),i},i.addChild=function(e,t){void 0===t&&(t={});var i=this.constructor.name;return y.warn("Adding an actionable (user controllable) child to a Button ("+i+") is not supported; use a ClickableComponent instead."),gt.prototype.addChild.call(this,e,t)},i.enable=function(){t.prototype.enable.call(this),this.el_.removeAttribute("disabled")},i.disable=function(){t.prototype.disable.call(this),this.el_.setAttribute("disabled","disabled")},i.handleKeyDown=function(e){Lt.isEventKey(e,"Space")||Lt.isEventKey(e,"Enter")?e.stopPropagation():t.prototype.handleKeyDown.call(this,e)},e}(H);gt.registerComponent("Button",sn);W=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.mouseused_=!1,i.on("mousedown",function(e){return i.handleMouseDown(e)}),i}vt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-big-play-button"},t.handleClick=function(e){var t=this.player_.play();if(this.mouseused_&&e.clientX&&e.clientY){var i=this.player_.usingPlugin("eme")&&this.player_.eme.sessions&&0<this.player_.eme.sessions.length;return It(t),void(!this.player_.tech(!0)||(j||U)&&i||this.player_.tech(!0).focus())}var i=this.player_.getChild("controlBar"),n=i&&i.getChild("playToggle");n?(i=function(){return n.focus()},wt(t)?t.then(i,function(){}):this.setTimeout(i,1)):this.player_.tech(!0).focus()},t.handleKeyDown=function(e){this.mouseused_=!1,n.prototype.handleKeyDown.call(this,e)},t.handleMouseDown=function(e){this.mouseused_=!0},e}(sn);W.prototype.controlText_="Play Video",gt.registerComponent("BigPlayButton",W),gt.registerComponent("CloseButton",function(i){function e(e,t){e=i.call(this,e,t)||this;return e.controlText(t&&t.controlText||e.localize("Close")),e}vt(e,i);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-close-button "+i.prototype.buildCSSClass.call(this)},t.handleClick=function(e){this.trigger({type:"close",bubbles:!1})},t.handleKeyDown=function(e){Lt.isEventKey(e,"Esc")?(e.preventDefault(),e.stopPropagation(),this.trigger("click")):i.prototype.handleKeyDown.call(this,e)},e}(sn));var on=function(n){function e(e,t){var i=n.call(this,e,t=void 0===t?{}:t)||this;return t.replay=void 0===t.replay||t.replay,i.on(e,"play",function(e){return i.handlePlay(e)}),i.on(e,"pause",function(e){return i.handlePause(e)}),t.replay&&i.on(e,"ended",function(e){return i.handleEnded(e)}),i}vt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-play-control "+n.prototype.buildCSSClass.call(this)},t.handleClick=function(e){this.player_.paused()?It(this.player_.play()):this.player_.pause()},t.handleSeeked=function(e){this.removeClass("vjs-ended"),this.player_.paused()?this.handlePause(e):this.handlePlay(e)},t.handlePlay=function(e){this.removeClass("vjs-ended"),this.removeClass("vjs-paused"),this.addClass("vjs-playing"),this.controlText("Pause")},t.handlePause=function(e){this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.controlText("Play")},t.handleEnded=function(e){var t=this;this.removeClass("vjs-playing"),this.addClass("vjs-ended"),this.controlText("Replay"),this.one(this.player_,"seeked",function(e){return t.handleSeeked(e)})},e}(sn);on.prototype.controlText_="Play",gt.registerComponent("PlayToggle",on);function un(e,t){e=e<0?0:e;var i=Math.floor(e%60),n=Math.floor(e/60%60),r=Math.floor(e/3600),a=Math.floor(t/60%60),t=Math.floor(t/3600);return(r=0<(r=isNaN(e)||e===1/0?n=i="-":r)||0<t?r+":":"")+(n=((r||10<=a)&&n<10?"0"+n:n)+":")+(i=i<10?"0"+i:i)}var ln=un;function cn(e,t){return ln(e,t=void 0===t?e:t)}P=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.on(e,["timeupdate","ended"],function(e){return i.updateContent(e)}),i.updateTextNode_(),i}vt(e,n);var t=e.prototype;return t.createEl=function(){var e=this.buildCSSClass(),t=n.prototype.createEl.call(this,"div",{className:e+" vjs-time-control vjs-control"}),i=te("span",{className:"vjs-control-text",textContent:this.localize(this.labelText_)+" "},{role:"presentation"});return t.appendChild(i),this.contentEl_=te("span",{className:e+"-display"},{"aria-live":"off",role:"presentation"}),t.appendChild(this.contentEl_),t},t.dispose=function(){this.contentEl_=null,this.textNode_=null,n.prototype.dispose.call(this)},t.updateTextNode_=function(e){var t=this;e=cn(e=void 0===e?0:e),this.formattedTime_!==e&&(this.formattedTime_=e,this.requestNamedAnimationFrame("TimeDisplay#updateTextNode_",function(){var e;t.contentEl_&&((e=t.textNode_)&&t.contentEl_.firstChild!==e&&(e=null,y.warn("TimeDisplay#updateTextnode_: Prevented replacement of text node element since it was no longer a child of this node. Appending a new node instead.")),t.textNode_=d.createTextNode(t.formattedTime_),t.textNode_&&(e?t.contentEl_.replaceChild(t.textNode_,e):t.contentEl_.appendChild(t.textNode_)))}))},t.updateContent=function(e){},e}(gt);P.prototype.labelText_="Time",P.prototype.controlText_="Time",gt.registerComponent("TimeDisplay",P);A=function(e){function t(){return e.apply(this,arguments)||this}vt(t,e);var i=t.prototype;return i.buildCSSClass=function(){return"vjs-current-time"},i.updateContent=function(e){var t=this.player_.ended()?this.player_.duration():this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime();this.updateTextNode_(t)},t}(P);A.prototype.labelText_="Current Time",A.prototype.controlText_="Current Time",gt.registerComponent("CurrentTimeDisplay",A);qt=function(n){function e(e,t){var i=n.call(this,e,t)||this,t=function(e){return i.updateContent(e)};return i.on(e,"durationchange",t),i.on(e,"loadstart",t),i.on(e,"loadedmetadata",t),i}vt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-duration"},t.updateContent=function(e){var t=this.player_.duration();this.updateTextNode_(t)},e}(P);qt.prototype.labelText_="Duration",qt.prototype.controlText_="Duration",gt.registerComponent("DurationDisplay",qt),gt.registerComponent("TimeDivider",function(n){function e(){return n.apply(this,arguments)||this}return vt(e,n),e.prototype.createEl=function(){var e=n.prototype.createEl.call(this,"div",{className:"vjs-time-control vjs-time-divider"},{"aria-hidden":!0}),t=n.prototype.createEl.call(this,"div"),i=n.prototype.createEl.call(this,"span",{textContent:"/"});return t.appendChild(i),e.appendChild(t),e},e}(gt));e=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.on(e,"durationchange",function(e){return i.updateContent(e)}),i}vt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-remaining-time"},t.createEl=function(){var e=n.prototype.createEl.call(this);return e.insertBefore(te("span",{},{"aria-hidden":!0},"-"),this.contentEl_),e},t.updateContent=function(e){var t;"number"==typeof this.player_.duration()&&(t=this.player_.ended()?0:this.player_.remainingTimeDisplay?this.player_.remainingTimeDisplay():this.player_.remainingTime(),this.updateTextNode_(t))},e}(P);e.prototype.labelText_="Remaining Time",e.prototype.controlText_="Remaining Time",gt.registerComponent("RemainingTimeDisplay",e),gt.registerComponent("LiveDisplay",function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.updateShowing(),i.on(i.player(),"durationchange",function(e){return i.updateShowing(e)}),i}vt(e,n);var t=e.prototype;return t.createEl=function(){var e=n.prototype.createEl.call(this,"div",{className:"vjs-live-control vjs-control"});return this.contentEl_=te("div",{className:"vjs-live-display"},{"aria-live":"off"}),this.contentEl_.appendChild(te("span",{className:"vjs-control-text",textContent:this.localize("Stream Type")+" "})),this.contentEl_.appendChild(d.createTextNode(this.localize("LIVE"))),e.appendChild(this.contentEl_),e},t.dispose=function(){this.contentEl_=null,n.prototype.dispose.call(this)},t.updateShowing=function(e){this.player().duration()===1/0?this.show():this.hide()},e}(gt));s=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.updateLiveEdgeStatus(),i.player_.liveTracker&&(i.updateLiveEdgeStatusHandler_=function(e){return i.updateLiveEdgeStatus(e)},i.on(i.player_.liveTracker,"liveedgechange",i.updateLiveEdgeStatusHandler_)),i}vt(e,n);var t=e.prototype;return t.createEl=function(){var e=n.prototype.createEl.call(this,"button",{className:"vjs-seek-to-live-control vjs-control"});return this.textEl_=te("span",{className:"vjs-seek-to-live-text",textContent:this.localize("LIVE")},{"aria-hidden":"true"}),e.appendChild(this.textEl_),e},t.updateLiveEdgeStatus=function(){!this.player_.liveTracker||this.player_.liveTracker.atLiveEdge()?(this.setAttribute("aria-disabled",!0),this.addClass("vjs-at-live-edge"),this.controlText("Seek to live, currently playing live")):(this.setAttribute("aria-disabled",!1),this.removeClass("vjs-at-live-edge"),this.controlText("Seek to live, currently behind live"))},t.handleClick=function(){this.player_.liveTracker.seekToLiveEdge()},t.dispose=function(){this.player_.liveTracker&&this.off(this.player_.liveTracker,"liveedgechange",this.updateLiveEdgeStatusHandler_),this.textEl_=null,n.prototype.dispose.call(this)},e}(sn);s.prototype.controlText_="Seek to live, currently playing live",gt.registerComponent("SeekToLive",s);function dn(e,t,i){return e=Number(e),Math.min(i,Math.max(t,isNaN(e)?t:e))}o=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.handleMouseDown_=function(e){return i.handleMouseDown(e)},i.handleMouseUp_=function(e){return i.handleMouseUp(e)},i.handleKeyDown_=function(e){return i.handleKeyDown(e)},i.handleClick_=function(e){return i.handleClick(e)},i.handleMouseMove_=function(e){return i.handleMouseMove(e)},i.update_=function(e){return i.update(e)},i.bar=i.getChild(i.options_.barName),i.vertical(!!i.options_.vertical),i.enable(),i}vt(e,n);var t=e.prototype;return t.enabled=function(){return this.enabled_},t.enable=function(){this.enabled()||(this.on("mousedown",this.handleMouseDown_),this.on("touchstart",this.handleMouseDown_),this.on("keydown",this.handleKeyDown_),this.on("click",this.handleClick_),this.on(this.player_,"controlsvisible",this.update),this.playerEvent&&this.on(this.player_,this.playerEvent,this.update),this.removeClass("disabled"),this.setAttribute("tabindex",0),this.enabled_=!0)},t.disable=function(){var e;this.enabled()&&(e=this.bar.el_.ownerDocument,this.off("mousedown",this.handleMouseDown_),this.off("touchstart",this.handleMouseDown_),this.off("keydown",this.handleKeyDown_),this.off("click",this.handleClick_),this.off(this.player_,"controlsvisible",this.update_),this.off(e,"mousemove",this.handleMouseMove_),this.off(e,"mouseup",this.handleMouseUp_),this.off(e,"touchmove",this.handleMouseMove_),this.off(e,"touchend",this.handleMouseUp_),this.removeAttribute("tabindex"),this.addClass("disabled"),this.playerEvent&&this.off(this.player_,this.playerEvent,this.update),this.enabled_=!1)},t.createEl=function(e,t,i){return void 0===i&&(i={}),(t=void 0===t?{}:t).className=t.className+" vjs-slider",t=k({tabIndex:0},t),i=k({role:"slider","aria-valuenow":0,"aria-valuemin":0,"aria-valuemax":100,tabIndex:0},i),n.prototype.createEl.call(this,e,t,i)},t.handleMouseDown=function(e){var t=this.bar.el_.ownerDocument;"mousedown"===e.type&&e.preventDefault(),"touchstart"!==e.type||B||e.preventDefault(),pe(),this.addClass("vjs-sliding"),this.trigger("slideractive"),this.on(t,"mousemove",this.handleMouseMove_),this.on(t,"mouseup",this.handleMouseUp_),this.on(t,"touchmove",this.handleMouseMove_),this.on(t,"touchend",this.handleMouseUp_),this.handleMouseMove(e)},t.handleMouseMove=function(e){},t.handleMouseUp=function(){var e=this.bar.el_.ownerDocument;fe(),this.removeClass("vjs-sliding"),this.trigger("sliderinactive"),this.off(e,"mousemove",this.handleMouseMove_),this.off(e,"mouseup",this.handleMouseUp_),this.off(e,"touchmove",this.handleMouseMove_),this.off(e,"touchend",this.handleMouseUp_),this.update()},t.update=function(){var t=this;if(this.el_&&this.bar){var i=this.getProgress();return i===this.progress_?i:(this.progress_=i,this.requestNamedAnimationFrame("Slider#update",function(){var e=t.vertical()?"height":"width";t.bar.el().style[e]=(100*i).toFixed(2)+"%"}),i)}},t.getProgress=function(){return Number(dn(this.getPercent(),0,1).toFixed(4))},t.calculateDistance=function(e){e=ye(this.el_,e);return this.vertical()?e.y:e.x},t.handleKeyDown=function(e){Lt.isEventKey(e,"Left")||Lt.isEventKey(e,"Down")?(e.preventDefault(),e.stopPropagation(),this.stepBack()):Lt.isEventKey(e,"Right")||Lt.isEventKey(e,"Up")?(e.preventDefault(),e.stopPropagation(),this.stepForward()):n.prototype.handleKeyDown.call(this,e)},t.handleClick=function(e){e.stopPropagation(),e.preventDefault()},t.vertical=function(e){if(void 0===e)return this.vertical_||!1;this.vertical_=!!e,this.vertical_?this.addClass("vjs-slider-vertical"):this.addClass("vjs-slider-horizontal")},e}(gt);gt.registerComponent("Slider",o);function hn(e,t){return dn(e/t*100,0,100).toFixed(2)+"%"}gt.registerComponent("LoadProgressBar",function(r){function e(e,t){var i=r.call(this,e,t)||this;return i.partEls_=[],i.on(e,"progress",function(e){return i.update(e)}),i}vt(e,r);var t=e.prototype;return t.createEl=function(){var e=r.prototype.createEl.call(this,"div",{className:"vjs-load-progress"}),t=te("span",{className:"vjs-control-text"}),i=te("span",{textContent:this.localize("Loaded")}),n=d.createTextNode(": ");return this.percentageEl_=te("span",{className:"vjs-control-text-loaded-percentage",textContent:"0%"}),e.appendChild(t),t.appendChild(i),t.appendChild(n),t.appendChild(this.percentageEl_),e},t.dispose=function(){this.partEls_=null,this.percentageEl_=null,r.prototype.dispose.call(this)},t.update=function(e){var l=this;this.requestNamedAnimationFrame("LoadProgressBar#update",function(){var e=l.player_.liveTracker,t=l.player_.buffered(),e=e&&e.isLive()?e.seekableEnd():l.player_.duration(),i=l.player_.bufferedEnd(),n=l.partEls_,e=hn(i,e);l.percent_!==e&&(l.el_.style.width=e,ie(l.percentageEl_,e),l.percent_=e);for(var r=0;r<t.length;r++){var a=t.start(r),s=t.end(r),o=n[r];o||(o=l.el_.appendChild(te()),n[r]=o),o.dataset.start===a&&o.dataset.end===s||(o.dataset.start=a,o.dataset.end=s,o.style.left=hn(a,i),o.style.width=hn(s-a,i))}for(var u=n.length;u>t.length;u--)l.el_.removeChild(n[u-1]);n.length=t.length})},e}(gt)),gt.registerComponent("TimeTooltip",function(i){function e(e,t){t=i.call(this,e,t)||this;return t.update=Ke(Xe(yt(t),t.update),30),t}vt(e,i);var t=e.prototype;return t.createEl=function(){return i.prototype.createEl.call(this,"div",{className:"vjs-time-tooltip"},{"aria-hidden":"true"})},t.update=function(e,t,i){var n=ge(this.el_),r=me(this.player_.el()),a=e.width*t;r&&n&&(t=e.left-r.left+a,r=e.width-a+(r.right-e.right),t<(e=n.width/2)?e+=e-t:r<e&&(e=r),e<0?e=0:e>n.width&&(e=n.width),e=Math.round(e),this.el_.style.right="-"+e+"px",this.write(i))},t.write=function(e){ie(this.el_,e)},t.updateTime=function(n,r,a,s){var o=this;this.requestNamedAnimationFrame("TimeTooltip#updateTime",function(){var e,t,i=o.player_.duration();i=o.player_.liveTracker&&o.player_.liveTracker.isLive()?((t=(e=o.player_.liveTracker.liveWindow())-r*e)<1?"":"-")+cn(t,e):cn(a,i),o.update(n,r,i),s&&s()})},e}(gt));L=function(i){function e(e,t){t=i.call(this,e,t)||this;return t.update=Ke(Xe(yt(t),t.update),30),t}vt(e,i);var t=e.prototype;return t.createEl=function(){return i.prototype.createEl.call(this,"div",{className:"vjs-play-progress vjs-slider-bar"},{"aria-hidden":"true"})},t.update=function(e,t){var i,n=this.getChild("timeTooltip");n&&(i=this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime(),n.updateTime(e,t,i))},e}(gt);L.prototype.options_={children:[]},G||O||L.prototype.options_.children.push("timeTooltip"),gt.registerComponent("PlayProgressBar",L);D=function(i){function e(e,t){t=i.call(this,e,t)||this;return t.update=Ke(Xe(yt(t),t.update),30),t}vt(e,i);var t=e.prototype;return t.createEl=function(){return i.prototype.createEl.call(this,"div",{className:"vjs-mouse-display"})},t.update=function(e,t){var i=this,n=t*this.player_.duration();this.getChild("timeTooltip").updateTime(e,t,n,function(){i.el_.style.left=e.width*t+"px"})},e}(gt);D.prototype.options_={children:["timeTooltip"]},gt.registerComponent("MouseTimeDisplay",D);W=function(a){function e(e,t){t=a.call(this,e,t)||this;return t.setEventHandlers_(),t}vt(e,a);var t=e.prototype;return t.setEventHandlers_=function(){var t=this;this.update_=Xe(this,this.update),this.update=Ke(this.update_,30),this.on(this.player_,["ended","durationchange","timeupdate"],this.update),this.player_.liveTracker&&this.on(this.player_.liveTracker,"liveedgechange",this.update),this.updateInterval=null,this.enableIntervalHandler_=function(e){return t.enableInterval_(e)},this.disableIntervalHandler_=function(e){return t.disableInterval_(e)},this.on(this.player_,["playing"],this.enableIntervalHandler_),this.on(this.player_,["ended","pause","waiting"],this.disableIntervalHandler_),"hidden"in d&&"visibilityState"in d&&this.on(d,"visibilitychange",this.toggleVisibility_)},t.toggleVisibility_=function(e){"hidden"===d.visibilityState?(this.cancelNamedAnimationFrame("SeekBar#update"),this.cancelNamedAnimationFrame("Slider#update"),this.disableInterval_(e)):(this.player_.ended()||this.player_.paused()||this.enableInterval_(),this.update())},t.enableInterval_=function(){this.updateInterval||(this.updateInterval=this.setInterval(this.update,30))},t.disableInterval_=function(e){this.player_.liveTracker&&this.player_.liveTracker.isLive()&&e&&"ended"!==e.type||this.updateInterval&&(this.clearInterval(this.updateInterval),this.updateInterval=null)},t.createEl=function(){return a.prototype.createEl.call(this,"div",{className:"vjs-progress-holder"},{"aria-label":this.localize("Progress Bar")})},t.update=function(e){var n=this;if("hidden"!==d.visibilityState){var r=a.prototype.update.call(this);return this.requestNamedAnimationFrame("SeekBar#update",function(){var e=n.player_.ended()?n.player_.duration():n.getCurrentTime_(),t=n.player_.liveTracker,i=n.player_.duration();t&&t.isLive()&&(i=n.player_.liveTracker.liveCurrentTime()),n.percent_!==r&&(n.el_.setAttribute("aria-valuenow",(100*r).toFixed(2)),n.percent_=r),n.currentTime_===e&&n.duration_===i||(n.el_.setAttribute("aria-valuetext",n.localize("progress bar timing: currentTime={1} duration={2}",[cn(e,i),cn(i,i)],"{1} of {2}")),n.currentTime_=e,n.duration_=i),n.bar&&n.bar.update(me(n.el()),n.getProgress())}),r}},t.userSeek_=function(e){this.player_.liveTracker&&this.player_.liveTracker.isLive()&&this.player_.liveTracker.nextSeekedFromUser(),this.player_.currentTime(e)},t.getCurrentTime_=function(){return this.player_.scrubbing()?this.player_.getCache().currentTime:this.player_.currentTime()},t.getPercent=function(){var e,t=this.getCurrentTime_(),i=this.player_.liveTracker;return i&&i.isLive()?(e=(t-i.seekableStart())/i.liveWindow(),i.atLiveEdge()&&(e=1)):e=t/this.player_.duration(),e},t.handleMouseDown=function(e){Ee(e)&&(e.stopPropagation(),this.player_.scrubbing(!0),this.videoWasPlaying=!this.player_.paused(),this.player_.pause(),a.prototype.handleMouseDown.call(this,e))},t.handleMouseMove=function(e){if(Ee(e)){var t=this.calculateDistance(e),i=this.player_.liveTracker;if(i&&i.isLive()){if(.99<=t)return void i.seekToLiveEdge();var n,r=i.seekableStart(),e=i.liveCurrentTime();if((n=(n=e<=(n=r+t*i.liveWindow())?e:n)<=r?r+.1:n)===1/0)return}else(n=t*this.player_.duration())===this.player_.duration()&&(n-=.1);this.userSeek_(n)}},t.enable=function(){a.prototype.enable.call(this);var e=this.getChild("mouseTimeDisplay");e&&e.show()},t.disable=function(){a.prototype.disable.call(this);var e=this.getChild("mouseTimeDisplay");e&&e.hide()},t.handleMouseUp=function(e){a.prototype.handleMouseUp.call(this,e),e&&e.stopPropagation(),this.player_.scrubbing(!1),this.player_.trigger({type:"timeupdate",target:this,manuallyTriggered:!0}),this.videoWasPlaying?It(this.player_.play()):this.update_()},t.stepForward=function(){this.userSeek_(this.player_.currentTime()+5)},t.stepBack=function(){this.userSeek_(this.player_.currentTime()-5)},t.handleAction=function(e){this.player_.paused()?this.player_.play():this.player_.pause()},t.handleKeyDown=function(e){var t,i=this.player_.liveTracker;Lt.isEventKey(e,"Space")||Lt.isEventKey(e,"Enter")?(e.preventDefault(),e.stopPropagation(),this.handleAction(e)):Lt.isEventKey(e,"Home")?(e.preventDefault(),e.stopPropagation(),this.userSeek_(0)):Lt.isEventKey(e,"End")?(e.preventDefault(),e.stopPropagation(),i&&i.isLive()?this.userSeek_(i.liveCurrentTime()):this.userSeek_(this.player_.duration())):/^[0-9]$/.test(Lt(e))?(e.preventDefault(),e.stopPropagation(),t=10*(Lt.codes[Lt(e)]-Lt.codes[0])/100,i&&i.isLive()?this.userSeek_(i.seekableStart()+i.liveWindow()*t):this.userSeek_(this.player_.duration()*t)):Lt.isEventKey(e,"PgDn")?(e.preventDefault(),e.stopPropagation(),this.userSeek_(this.player_.currentTime()-60)):Lt.isEventKey(e,"PgUp")?(e.preventDefault(),e.stopPropagation(),this.userSeek_(this.player_.currentTime()+60)):a.prototype.handleKeyDown.call(this,e)},t.dispose=function(){this.disableInterval_(),this.off(this.player_,["ended","durationchange","timeupdate"],this.update),this.player_.liveTracker&&this.off(this.player_.liveTracker,"liveedgechange",this.update),this.off(this.player_,["playing"],this.enableIntervalHandler_),this.off(this.player_,["ended","pause","waiting"],this.disableIntervalHandler_),"hidden"in d&&"visibilityState"in d&&this.off(d,"visibilitychange",this.toggleVisibility_),a.prototype.dispose.call(this)},e}(o);W.prototype.options_={children:["loadProgressBar","playProgressBar"],barName:"playProgressBar"},G||O||W.prototype.options_.children.splice(1,0,"mouseTimeDisplay"),gt.registerComponent("SeekBar",W);on=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.handleMouseMove=Ke(Xe(yt(i),i.handleMouseMove),30),i.throttledHandleMouseSeek=Ke(Xe(yt(i),i.handleMouseSeek),30),i.handleMouseUpHandler_=function(e){return i.handleMouseUp(e)},i.handleMouseDownHandler_=function(e){return i.handleMouseDown(e)},i.enable(),i}vt(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-progress-control vjs-control"})},t.handleMouseMove=function(e){var t,i,n,r,a=this.getChild("seekBar");a&&(t=a.getChild("playProgressBar"),i=a.getChild("mouseTimeDisplay"),(t||i)&&(r=ge(n=a.el()),e=ye(n,e).x,e=dn(e,0,1),i&&i.update(r,e),t&&t.update(r,a.getProgress())))},t.handleMouseSeek=function(e){var t=this.getChild("seekBar");t&&t.handleMouseMove(e)},t.enabled=function(){return this.enabled_},t.disable=function(){var e;this.children().forEach(function(e){return e.disable&&e.disable()}),this.enabled()&&(this.off(["mousedown","touchstart"],this.handleMouseDownHandler_),this.off(this.el_,"mousemove",this.handleMouseMove),this.removeListenersAddedOnMousedownAndTouchstart(),this.addClass("disabled"),this.enabled_=!1,this.player_.scrubbing()&&(e=this.getChild("seekBar"),this.player_.scrubbing(!1),e.videoWasPlaying&&It(this.player_.play())))},t.enable=function(){this.children().forEach(function(e){return e.enable&&e.enable()}),this.enabled()||(this.on(["mousedown","touchstart"],this.handleMouseDownHandler_),this.on(this.el_,"mousemove",this.handleMouseMove),this.removeClass("disabled"),this.enabled_=!0)},t.removeListenersAddedOnMousedownAndTouchstart=function(){var e=this.el_.ownerDocument;this.off(e,"mousemove",this.throttledHandleMouseSeek),this.off(e,"touchmove",this.throttledHandleMouseSeek),this.off(e,"mouseup",this.handleMouseUpHandler_),this.off(e,"touchend",this.handleMouseUpHandler_)},t.handleMouseDown=function(e){var t=this.el_.ownerDocument,i=this.getChild("seekBar");i&&i.handleMouseDown(e),this.on(t,"mousemove",this.throttledHandleMouseSeek),this.on(t,"touchmove",this.throttledHandleMouseSeek),this.on(t,"mouseup",this.handleMouseUpHandler_),this.on(t,"touchend",this.handleMouseUpHandler_)},t.handleMouseUp=function(e){var t=this.getChild("seekBar");t&&t.handleMouseUp(e),this.removeListenersAddedOnMousedownAndTouchstart()},e}(gt);on.prototype.options_={children:["seekBar"]},gt.registerComponent("ProgressControl",on);A=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.on(e,["enterpictureinpicture","leavepictureinpicture"],function(e){return i.handlePictureInPictureChange(e)}),i.on(e,["disablepictureinpicturechanged","loadedmetadata"],function(e){return i.handlePictureInPictureEnabledChange(e)}),i.disable(),i}vt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-picture-in-picture-control "+n.prototype.buildCSSClass.call(this)},t.handlePictureInPictureEnabledChange=function(){d.pictureInPictureEnabled&&!1===this.player_.disablePictureInPicture()?this.enable():this.disable()},t.handlePictureInPictureChange=function(e){this.player_.isInPictureInPicture()?this.controlText("Exit Picture-in-Picture"):this.controlText("Picture-in-Picture"),this.handlePictureInPictureEnabledChange()},t.handleClick=function(e){this.player_.isInPictureInPicture()?this.player_.exitPictureInPicture():this.player_.requestPictureInPicture()},e}(sn);A.prototype.controlText_="Picture-in-Picture",gt.registerComponent("PictureInPictureToggle",A);qt=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.on(e,"fullscreenchange",function(e){return i.handleFullscreenChange(e)}),!1===d[e.fsApi_.fullscreenEnabled]&&i.disable(),i}vt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-fullscreen-control "+n.prototype.buildCSSClass.call(this)},t.handleFullscreenChange=function(e){this.player_.isFullscreen()?this.controlText("Non-Fullscreen"):this.controlText("Fullscreen")},t.handleClick=function(e){this.player_.isFullscreen()?this.player_.exitFullscreen():this.player_.requestFullscreen()},e}(sn);qt.prototype.controlText_="Fullscreen",gt.registerComponent("FullscreenToggle",qt);gt.registerComponent("VolumeLevel",function(t){function e(){return t.apply(this,arguments)||this}return vt(e,t),e.prototype.createEl=function(){var e=t.prototype.createEl.call(this,"div",{className:"vjs-volume-level"});return e.appendChild(t.prototype.createEl.call(this,"span",{className:"vjs-control-text"})),e},e}(gt)),gt.registerComponent("VolumeLevelTooltip",function(i){function e(e,t){t=i.call(this,e,t)||this;return t.update=Ke(Xe(yt(t),t.update),30),t}vt(e,i);var t=e.prototype;return t.createEl=function(){return i.prototype.createEl.call(this,"div",{className:"vjs-volume-tooltip"},{"aria-hidden":"true"})},t.update=function(e,t,i,n){if(!i){var r=me(this.el_),a=me(this.player_.el()),i=e.width*t;if(!a||!r)return;t=e.left-a.left+i,a=e.width-i+(a.right-e.right),e=r.width/2;t<e?e+=e-t:a<e&&(e=a),e<0?e=0:e>r.width&&(e=r.width),this.el_.style.right="-"+e+"px"}this.write(n+"%")},t.write=function(e){ie(this.el_,e)},t.updateVolume=function(e,t,i,n,r){var a=this;this.requestNamedAnimationFrame("VolumeLevelTooltip#updateVolume",function(){a.update(e,t,i,n.toFixed(0)),r&&r()})},e}(gt));P=function(i){function e(e,t){t=i.call(this,e,t)||this;return t.update=Ke(Xe(yt(t),t.update),30),t}vt(e,i);var t=e.prototype;return t.createEl=function(){return i.prototype.createEl.call(this,"div",{className:"vjs-mouse-display"})},t.update=function(e,t,i){var n=this,r=100*t;this.getChild("volumeLevelTooltip").updateVolume(e,t,i,r,function(){i?n.el_.style.bottom=e.height*t+"px":n.el_.style.left=e.width*t+"px"})},e}(gt);P.prototype.options_={children:["volumeLevelTooltip"]},gt.registerComponent("MouseVolumeLevelDisplay",P);e=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.on("slideractive",function(e){return i.updateLastVolume_(e)}),i.on(e,"volumechange",function(e){return i.updateARIAAttributes(e)}),e.ready(function(){return i.updateARIAAttributes()}),i}vt(e,n);var t=e.prototype;return t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:"vjs-volume-bar vjs-slider-bar"},{"aria-label":this.localize("Volume Level"),"aria-live":"polite"})},t.handleMouseDown=function(e){Ee(e)&&n.prototype.handleMouseDown.call(this,e)},t.handleMouseMove=function(e){var t,i,n,r=this.getChild("mouseVolumeLevelDisplay");r&&(t=me(n=this.el()),i=this.vertical(),n=ye(n,e),n=i?n.y:n.x,n=dn(n,0,1),r.update(t,n,i)),Ee(e)&&(this.checkMuted(),this.player_.volume(this.calculateDistance(e)))},t.checkMuted=function(){this.player_.muted()&&this.player_.muted(!1)},t.getPercent=function(){return this.player_.muted()?0:this.player_.volume()},t.stepForward=function(){this.checkMuted(),this.player_.volume(this.player_.volume()+.1)},t.stepBack=function(){this.checkMuted(),this.player_.volume(this.player_.volume()-.1)},t.updateARIAAttributes=function(e){var t=this.player_.muted()?0:this.volumeAsPercentage_();this.el_.setAttribute("aria-valuenow",t),this.el_.setAttribute("aria-valuetext",t+"%")},t.volumeAsPercentage_=function(){return Math.round(100*this.player_.volume())},t.updateLastVolume_=function(){var e=this,t=this.player_.volume();this.one("sliderinactive",function(){0===e.player_.volume()&&e.player_.lastVolume_(t)})},e}(o);e.prototype.options_={children:["volumeLevel"],barName:"volumeLevel"},G||O||e.prototype.options_.children.splice(0,0,"mouseVolumeLevelDisplay"),e.prototype.playerEvent="volumechange",gt.registerComponent("VolumeBar",e);s=function(a){function e(e,t){var i,n,r;return(t=void 0===t?{}:t).vertical=t.vertical||!1,"undefined"!=typeof t.volumeBar&&!w(t.volumeBar)||(t.volumeBar=t.volumeBar||{},t.volumeBar.vertical=t.vertical),i=a.call(this,e,t)||this,n=yt(i),(r=e).tech_&&!r.tech_.featuresVolumeControl&&n.addClass("vjs-hidden"),n.on(r,"loadstart",function(){r.tech_.featuresVolumeControl?n.removeClass("vjs-hidden"):n.addClass("vjs-hidden")}),i.throttledHandleMouseMove=Ke(Xe(yt(i),i.handleMouseMove),30),i.handleMouseUpHandler_=function(e){return i.handleMouseUp(e)},i.on("mousedown",function(e){return i.handleMouseDown(e)}),i.on("touchstart",function(e){return i.handleMouseDown(e)}),i.on("mousemove",function(e){return i.handleMouseMove(e)}),i.on(i.volumeBar,["focus","slideractive"],function(){i.volumeBar.addClass("vjs-slider-active"),i.addClass("vjs-slider-active"),i.trigger("slideractive")}),i.on(i.volumeBar,["blur","sliderinactive"],function(){i.volumeBar.removeClass("vjs-slider-active"),i.removeClass("vjs-slider-active"),i.trigger("sliderinactive")}),i}vt(e,a);var t=e.prototype;return t.createEl=function(){var e="vjs-volume-horizontal";return this.options_.vertical&&(e="vjs-volume-vertical"),a.prototype.createEl.call(this,"div",{className:"vjs-volume-control vjs-control "+e})},t.handleMouseDown=function(e){var t=this.el_.ownerDocument;this.on(t,"mousemove",this.throttledHandleMouseMove),this.on(t,"touchmove",this.throttledHandleMouseMove),this.on(t,"mouseup",this.handleMouseUpHandler_),this.on(t,"touchend",this.handleMouseUpHandler_)},t.handleMouseUp=function(e){var t=this.el_.ownerDocument;this.off(t,"mousemove",this.throttledHandleMouseMove),this.off(t,"touchmove",this.throttledHandleMouseMove),this.off(t,"mouseup",this.handleMouseUpHandler_),this.off(t,"touchend",this.handleMouseUpHandler_)},t.handleMouseMove=function(e){this.volumeBar.handleMouseMove(e)},e}(gt);s.prototype.options_={children:["volumeBar"]},gt.registerComponent("VolumeControl",s);L=function(a){function e(e,t){var i,n,r=a.call(this,e,t)||this;return i=yt(r),(n=e).tech_&&!n.tech_.featuresMuteControl&&i.addClass("vjs-hidden"),i.on(n,"loadstart",function(){n.tech_.featuresMuteControl?i.removeClass("vjs-hidden"):i.addClass("vjs-hidden")}),r.on(e,["loadstart","volumechange"],function(e){return r.update(e)}),r}vt(e,a);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-mute-control "+a.prototype.buildCSSClass.call(this)},t.handleClick=function(e){var t=this.player_.volume(),i=this.player_.lastVolume_();0===t?(this.player_.volume(i<.1?.1:i),this.player_.muted(!1)):this.player_.muted(!this.player_.muted())},t.update=function(e){this.updateIcon_(),this.updateControlText_()},t.updateIcon_=function(){var e=this.player_.volume(),t=3;G&&this.player_.tech_&&this.player_.tech_.el_&&this.player_.muted(this.player_.tech_.el_.muted),0===e||this.player_.muted()?t=0:e<.33?t=1:e<.67&&(t=2);for(var i=0;i<4;i++)se(this.el_,"vjs-vol-"+i);ae(this.el_,"vjs-vol-"+t)},t.updateControlText_=function(){var e=this.player_.muted()||0===this.player_.volume()?"Unmute":"Mute";this.controlText()!==e&&this.controlText(e)},e}(sn);L.prototype.controlText_="Mute",gt.registerComponent("MuteToggle",L);D=function(n){function e(e,t){var i;return"undefined"!=typeof(t=void 0===t?{}:t).inline?t.inline=t.inline:t.inline=!0,"undefined"!=typeof t.volumeControl&&!w(t.volumeControl)||(t.volumeControl=t.volumeControl||{},t.volumeControl.vertical=!t.inline),(i=n.call(this,e,t)||this).handleKeyPressHandler_=function(e){return i.handleKeyPress(e)},i.on(e,["loadstart"],function(e){return i.volumePanelState_(e)}),i.on(i.muteToggle,"keyup",function(e){return i.handleKeyPress(e)}),i.on(i.volumeControl,"keyup",function(e){return i.handleVolumeControlKeyUp(e)}),i.on("keydown",function(e){return i.handleKeyPress(e)}),i.on("mouseover",function(e){return i.handleMouseOver(e)}),i.on("mouseout",function(e){return i.handleMouseOut(e)}),i.on(i.volumeControl,["slideractive"],i.sliderActive_),i.on(i.volumeControl,["sliderinactive"],i.sliderInactive_),i}vt(e,n);var t=e.prototype;return t.sliderActive_=function(){this.addClass("vjs-slider-active")},t.sliderInactive_=function(){this.removeClass("vjs-slider-active")},t.volumePanelState_=function(){this.volumeControl.hasClass("vjs-hidden")&&this.muteToggle.hasClass("vjs-hidden")&&this.addClass("vjs-hidden"),this.volumeControl.hasClass("vjs-hidden")&&!this.muteToggle.hasClass("vjs-hidden")&&this.addClass("vjs-mute-toggle-only")},t.createEl=function(){var e="vjs-volume-panel-horizontal";return this.options_.inline||(e="vjs-volume-panel-vertical"),n.prototype.createEl.call(this,"div",{className:"vjs-volume-panel vjs-control "+e})},t.dispose=function(){this.handleMouseOut(),n.prototype.dispose.call(this)},t.handleVolumeControlKeyUp=function(e){Lt.isEventKey(e,"Esc")&&this.muteToggle.focus()},t.handleMouseOver=function(e){this.addClass("vjs-hover"),qe(d,"keyup",this.handleKeyPressHandler_)},t.handleMouseOut=function(e){this.removeClass("vjs-hover"),Ve(d,"keyup",this.handleKeyPressHandler_)},t.handleKeyPress=function(e){Lt.isEventKey(e,"Esc")&&this.handleMouseOut()},e}(gt);D.prototype.options_={children:["muteToggle","volumeControl"]},gt.registerComponent("VolumePanel",D);var pn=function(n){function e(e,t){var i=n.call(this,e,t)||this;return t&&(i.menuButton_=t.menuButton),i.focusedChild_=-1,i.on("keydown",function(e){return i.handleKeyDown(e)}),i.boundHandleBlur_=function(e){return i.handleBlur(e)},i.boundHandleTapClick_=function(e){return i.handleTapClick(e)},i}vt(e,n);var t=e.prototype;return t.addEventListenerForItem=function(e){e instanceof gt&&(this.on(e,"blur",this.boundHandleBlur_),this.on(e,["tap","click"],this.boundHandleTapClick_))},t.removeEventListenerForItem=function(e){e instanceof gt&&(this.off(e,"blur",this.boundHandleBlur_),this.off(e,["tap","click"],this.boundHandleTapClick_))},t.removeChild=function(e){"string"==typeof e&&(e=this.getChild(e)),this.removeEventListenerForItem(e),n.prototype.removeChild.call(this,e)},t.addItem=function(e){e=this.addChild(e);e&&this.addEventListenerForItem(e)},t.createEl=function(){var e=this.options_.contentElType||"ul";this.contentEl_=te(e,{className:"vjs-menu-content"}),this.contentEl_.setAttribute("role","menu");e=n.prototype.createEl.call(this,"div",{append:this.contentEl_,className:"vjs-menu"});return e.appendChild(this.contentEl_),qe(e,"click",function(e){e.preventDefault(),e.stopImmediatePropagation()}),e},t.dispose=function(){this.contentEl_=null,this.boundHandleBlur_=null,this.boundHandleTapClick_=null,n.prototype.dispose.call(this)},t.handleBlur=function(e){var t=e.relatedTarget||d.activeElement;this.children().some(function(e){return e.el()===t})||(e=this.menuButton_)&&e.buttonPressed_&&t!==e.el().firstChild&&e.unpressButton()},t.handleTapClick=function(t){var e;this.menuButton_&&(this.menuButton_.unpressButton(),e=this.children(),!Array.isArray(e)||(e=e.filter(function(e){return e.el()===t.target})[0])&&"CaptionSettingsMenuItem"!==e.name()&&this.menuButton_.focus())},t.handleKeyDown=function(e){Lt.isEventKey(e,"Left")||Lt.isEventKey(e,"Down")?(e.preventDefault(),e.stopPropagation(),this.stepForward()):(Lt.isEventKey(e,"Right")||Lt.isEventKey(e,"Up"))&&(e.preventDefault(),e.stopPropagation(),this.stepBack())},t.stepForward=function(){var e=0;void 0!==this.focusedChild_&&(e=this.focusedChild_+1),this.focus(e)},t.stepBack=function(){var e=0;void 0!==this.focusedChild_&&(e=this.focusedChild_-1),this.focus(e)},t.focus=function(e){void 0===e&&(e=0);var t=this.children().slice();t.length&&t[0].hasClass("vjs-menu-title")&&t.shift(),0<t.length&&(e<0?e=0:e>=t.length&&(e=t.length-1),t[this.focusedChild_=e].el_.focus())},e}(gt);gt.registerComponent("Menu",pn);W=function(n){function e(e,t){var i;(i=n.call(this,e,t=void 0===t?{}:t)||this).menuButton_=new sn(e,t),i.menuButton_.controlText(i.controlText_),i.menuButton_.el_.setAttribute("aria-haspopup","true");t=sn.prototype.buildCSSClass();i.menuButton_.el_.className=i.buildCSSClass()+" "+t,i.menuButton_.removeClass("vjs-control"),i.addChild(i.menuButton_),i.update(),i.enabled_=!0;t=function(e){return i.handleClick(e)};return i.handleMenuKeyUp_=function(e){return i.handleMenuKeyUp(e)},i.on(i.menuButton_,"tap",t),i.on(i.menuButton_,"click",t),i.on(i.menuButton_,"keydown",function(e){return i.handleKeyDown(e)}),i.on(i.menuButton_,"mouseenter",function(){i.addClass("vjs-hover"),i.menu.show(),qe(d,"keyup",i.handleMenuKeyUp_)}),i.on("mouseleave",function(e){return i.handleMouseLeave(e)}),i.on("keydown",function(e){return i.handleSubmenuKeyDown(e)}),i}vt(e,n);var t=e.prototype;return t.update=function(){var e=this.createMenu();this.menu&&(this.menu.dispose(),this.removeChild(this.menu)),this.menu=e,this.addChild(e),this.buttonPressed_=!1,this.menuButton_.el_.setAttribute("aria-expanded","false"),this.items&&this.items.length<=this.hideThreshold_?this.hide():this.show()},t.createMenu=function(){var e,t=new pn(this.player_,{menuButton:this});if(this.hideThreshold_=0,this.options_.title&&(e=te("li",{className:"vjs-menu-title",textContent:ht(this.options_.title),tabIndex:-1}),e=new gt(this.player_,{el:e}),t.addItem(e)),this.items=this.createItems(),this.items)for(var i=0;i<this.items.length;i++)t.addItem(this.items[i]);return t},t.createItems=function(){},t.createEl=function(){return n.prototype.createEl.call(this,"div",{className:this.buildWrapperCSSClass()},{})},t.buildWrapperCSSClass=function(){var e="vjs-menu-button";return!0===this.options_.inline?e+="-inline":e+="-popup","vjs-menu-button "+e+" "+sn.prototype.buildCSSClass()+" "+n.prototype.buildCSSClass.call(this)},t.buildCSSClass=function(){var e="vjs-menu-button";return!0===this.options_.inline?e+="-inline":e+="-popup","vjs-menu-button "+e+" "+n.prototype.buildCSSClass.call(this)},t.controlText=function(e,t){return void 0===t&&(t=this.menuButton_.el()),this.menuButton_.controlText(e,t)},t.dispose=function(){this.handleMouseLeave(),n.prototype.dispose.call(this)},t.handleClick=function(e){this.buttonPressed_?this.unpressButton():this.pressButton()},t.handleMouseLeave=function(e){this.removeClass("vjs-hover"),Ve(d,"keyup",this.handleMenuKeyUp_)},t.focus=function(){this.menuButton_.focus()},t.blur=function(){this.menuButton_.blur()},t.handleKeyDown=function(e){Lt.isEventKey(e,"Esc")||Lt.isEventKey(e,"Tab")?(this.buttonPressed_&&this.unpressButton(),Lt.isEventKey(e,"Tab")||(e.preventDefault(),this.menuButton_.focus())):(Lt.isEventKey(e,"Up")||Lt.isEventKey(e,"Down"))&&(this.buttonPressed_||(e.preventDefault(),this.pressButton()))},t.handleMenuKeyUp=function(e){(Lt.isEventKey(e,"Esc")||Lt.isEventKey(e,"Tab"))&&this.removeClass("vjs-hover")},t.handleSubmenuKeyPress=function(e){this.handleSubmenuKeyDown(e)},t.handleSubmenuKeyDown=function(e){(Lt.isEventKey(e,"Esc")||Lt.isEventKey(e,"Tab"))&&(this.buttonPressed_&&this.unpressButton(),Lt.isEventKey(e,"Tab")||(e.preventDefault(),this.menuButton_.focus()))},t.pressButton=function(){this.enabled_&&(this.buttonPressed_=!0,this.menu.show(),this.menu.lockShowing(),this.menuButton_.el_.setAttribute("aria-expanded","true"),G&&Z()||this.menu.focus())},t.unpressButton=function(){this.enabled_&&(this.buttonPressed_=!1,this.menu.unlockShowing(),this.menu.hide(),this.menuButton_.el_.setAttribute("aria-expanded","false"))},t.disable=function(){this.unpressButton(),this.enabled_=!1,this.addClass("vjs-disabled"),this.menuButton_.disable()},t.enable=function(){this.enabled_=!0,this.removeClass("vjs-disabled"),this.menuButton_.enable()},e}(gt);gt.registerComponent("MenuButton",W);on=function(r){function e(e,t){var i=t.tracks,t=r.call(this,e,t)||this;if(t.items.length<=1&&t.hide(),!i)return yt(t);var n=Xe(yt(t),t.update);return i.addEventListener("removetrack",n),i.addEventListener("addtrack",n),i.addEventListener("labelchange",n),t.player_.on("ready",n),t.player_.on("dispose",function(){i.removeEventListener("removetrack",n),i.removeEventListener("addtrack",n),i.removeEventListener("labelchange",n)}),t}return vt(e,r),e}(W);gt.registerComponent("TrackButton",on);var fn=["Tab","Esc","Up","Down","Right","Left"],A=function(n){function e(e,t){e=n.call(this,e,t)||this;return e.selectable=t.selectable,e.isSelected_=t.selected||!1,e.multiSelectable=t.multiSelectable,e.selected(e.isSelected_),e.selectable?e.multiSelectable?e.el_.setAttribute("role","menuitemcheckbox"):e.el_.setAttribute("role","menuitemradio"):e.el_.setAttribute("role","menuitem"),e}vt(e,n);var t=e.prototype;return t.createEl=function(e,t,i){this.nonIconControl=!0;i=n.prototype.createEl.call(this,"li",k({className:"vjs-menu-item",tabIndex:-1},t),i);return i.replaceChild(te("span",{className:"vjs-menu-item-text",textContent:this.localize(this.options_.label)}),i.querySelector(".vjs-icon-placeholder")),i},t.handleKeyDown=function(t){fn.some(function(e){return Lt.isEventKey(t,e)})||n.prototype.handleKeyDown.call(this,t)},t.handleClick=function(e){this.selected(!0)},t.selected=function(e){this.selectable&&(e?(this.addClass("vjs-selected"),this.el_.setAttribute("aria-checked","true"),this.controlText(", selected"),this.isSelected_=!0):(this.removeClass("vjs-selected"),this.el_.setAttribute("aria-checked","false"),this.controlText(""),this.isSelected_=!1))},e}(H);gt.registerComponent("MenuItem",A);var mn=function(u){function e(e,t){var n,i=t.track,r=e.textTracks();t.label=i.label||i.language||"Unknown",t.selected="showing"===i.mode,(n=u.call(this,e,t)||this).track=i,n.kinds=(t.kinds||[t.kind||n.track.kind]).filter(Boolean);function a(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];n.handleTracksChange.apply(yt(n),t)}function s(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];n.handleSelectedLanguageChange.apply(yt(n),t)}var o;return e.on(["loadstart","texttrackchange"],a),r.addEventListener("change",a),r.addEventListener("selectedlanguagechange",s),n.on("dispose",function(){e.off(["loadstart","texttrackchange"],a),r.removeEventListener("change",a),r.removeEventListener("selectedlanguagechange",s)}),void 0===r.onchange&&n.on(["tap","click"],function(){if("object"!=typeof _.Event)try{o=new _.Event("change")}catch(e){}o||(o=d.createEvent("Event")).initEvent("change",!0,!0),r.dispatchEvent(o)}),n.handleTracksChange(),n}vt(e,u);var t=e.prototype;return t.handleClick=function(e){var t=this.track,i=this.player_.textTracks();if(u.prototype.handleClick.call(this,e),i)for(var n=0;n<i.length;n++){var r=i[n];-1!==this.kinds.indexOf(r.kind)&&(r===t?"showing"!==r.mode&&(r.mode="showing"):"disabled"!==r.mode&&(r.mode="disabled"))}},t.handleTracksChange=function(e){var t="showing"===this.track.mode;t!==this.isSelected_&&this.selected(t)},t.handleSelectedLanguageChange=function(e){var t;"showing"===this.track.mode&&((t=this.player_.cache_.selectedLanguage)&&t.enabled&&t.language===this.track.language&&t.kind!==this.track.kind||(this.player_.cache_.selectedLanguage={enabled:!0,language:this.track.language,kind:this.track.kind}))},t.dispose=function(){this.track=null,u.prototype.dispose.call(this)},e}(A);gt.registerComponent("TextTrackMenuItem",mn);var gn=function(i){function e(e,t){return t.track={player:e,kind:t.kind,kinds:t.kinds,default:!1,mode:"disabled"},t.kinds||(t.kinds=[t.kind]),t.label?t.track.label=t.label:t.track.label=t.kinds.join(" and ")+" off",t.selectable=!0,t.multiSelectable=!1,i.call(this,e,t)||this}vt(e,i);var t=e.prototype;return t.handleTracksChange=function(e){for(var t=this.player().textTracks(),i=!0,n=0,r=t.length;n<r;n++){var a=t[n];if(-1<this.options_.kinds.indexOf(a.kind)&&"showing"===a.mode){i=!1;break}}i!==this.isSelected_&&this.selected(i)},t.handleSelectedLanguageChange=function(e){for(var t=this.player().textTracks(),i=!0,n=0,r=t.length;n<r;n++){var a=t[n];if(-1<["captions","descriptions","subtitles"].indexOf(a.kind)&&"showing"===a.mode){i=!1;break}}i&&(this.player_.cache_.selectedLanguage={enabled:!1})},e}(mn);gt.registerComponent("OffTextTrackMenuItem",gn);qt=function(i){function e(e,t){return(t=void 0===t?{}:t).tracks=e.textTracks(),i.call(this,e,t)||this}return vt(e,i),e.prototype.createItems=function(e,t){var i;void 0===t&&(t=mn),this.label_&&(i=this.label_+" off"),(e=void 0===e?[]:e).push(new gn(this.player_,{kinds:this.kinds_,kind:this.kind_,label:i})),this.hideThreshold_+=1;var n=this.player_.textTracks();Array.isArray(this.kinds_)||(this.kinds_=[this.kind_]);for(var r=0;r<n.length;r++){var a,s=n[r];-1<this.kinds_.indexOf(s.kind)&&((a=new t(this.player_,{track:s,kinds:this.kinds_,kind:this.kind_,selectable:!0,multiSelectable:!1})).addClass("vjs-"+s.kind+"-menu-item"),e.push(a))}return e},e}(on);gt.registerComponent("TextTrackButton",qt);var yn=function(a){function e(e,t){var i=t.track,n=t.cue,r=e.currentTime();return t.selectable=!0,t.multiSelectable=!1,t.label=n.text,t.selected=n.startTime<=r&&r<n.endTime,(t=a.call(this,e,t)||this).track=i,t.cue=n,i.addEventListener("cuechange",Xe(yt(t),t.update)),t}vt(e,a);var t=e.prototype;return t.handleClick=function(e){a.prototype.handleClick.call(this),this.player_.currentTime(this.cue.startTime),this.update(this.cue.startTime)},t.update=function(e){var t=this.cue,i=this.player_.currentTime();this.selected(t.startTime<=i&&i<t.endTime)},e}(A);gt.registerComponent("ChaptersTrackMenuItem",yn);P=function(n){function e(e,t,i){return n.call(this,e,t,i)||this}vt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-chapters-button "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-chapters-button "+n.prototype.buildWrapperCSSClass.call(this)},t.update=function(e){this.track_&&(!e||"addtrack"!==e.type&&"removetrack"!==e.type)||this.setTrack(this.findChaptersTrack()),n.prototype.update.call(this)},t.setTrack=function(e){var t;this.track_!==e&&(this.updateHandler_||(this.updateHandler_=this.update.bind(this)),this.track_&&((t=this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_))&&t.removeEventListener("load",this.updateHandler_),this.track_=null),this.track_=e,this.track_&&(this.track_.mode="hidden",(e=this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_))&&e.addEventListener("load",this.updateHandler_)))},t.findChaptersTrack=function(){for(var e=this.player_.textTracks()||[],t=e.length-1;0<=t;t--){var i=e[t];if(i.kind===this.kind_)return i}},t.getMenuCaption=function(){return this.track_&&this.track_.label?this.track_.label:this.localize(ht(this.kind_))},t.createMenu=function(){return this.options_.title=this.getMenuCaption(),n.prototype.createMenu.call(this)},t.createItems=function(){var e=[];if(!this.track_)return e;var t=this.track_.cues;if(!t)return e;for(var i=0,n=t.length;i<n;i++){var r=t[i],r=new yn(this.player_,{track:this.track_,cue:r});e.push(r)}return e},e}(qt);P.prototype.kind_="chapters",P.prototype.controlText_="Chapters",gt.registerComponent("ChaptersButton",P);o=function(a){function e(e,t,i){var i=a.call(this,e,t,i)||this,n=e.textTracks(),r=Xe(yt(i),i.handleTracksChange);return n.addEventListener("change",r),i.on("dispose",function(){n.removeEventListener("change",r)}),i}vt(e,a);var t=e.prototype;return t.handleTracksChange=function(e){for(var t=this.player().textTracks(),i=!1,n=0,r=t.length;n<r;n++){var a=t[n];if(a.kind!==this.kind_&&"showing"===a.mode){i=!0;break}}i?this.disable():this.enable()},t.buildCSSClass=function(){return"vjs-descriptions-button "+a.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-descriptions-button "+a.prototype.buildWrapperCSSClass.call(this)},e}(qt);o.prototype.kind_="descriptions",o.prototype.controlText_="Descriptions",gt.registerComponent("DescriptionsButton",o);e=function(n){function e(e,t,i){return n.call(this,e,t,i)||this}vt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-subtitles-button "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-subtitles-button "+n.prototype.buildWrapperCSSClass.call(this)},e}(qt);e.prototype.kind_="subtitles",e.prototype.controlText_="Subtitles",gt.registerComponent("SubtitlesButton",e);var vn=function(i){function e(e,t){return t.track={player:e,kind:t.kind,label:t.kind+" settings",selectable:!1,default:!1,mode:"disabled"},t.selectable=!1,t.name="CaptionSettingsMenuItem",(e=i.call(this,e,t)||this).addClass("vjs-texttrack-settings"),e.controlText(", opens "+t.kind+" settings dialog"),e}return vt(e,i),e.prototype.handleClick=function(e){this.player().getChild("textTrackSettings").open()},e}(mn);gt.registerComponent("CaptionSettingsMenuItem",vn);s=function(n){function e(e,t,i){return n.call(this,e,t,i)||this}vt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-captions-button "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-captions-button "+n.prototype.buildWrapperCSSClass.call(this)},t.createItems=function(){var e=[];return this.player().tech_&&this.player().tech_.featuresNativeTextTracks||!this.player().getChild("textTrackSettings")||(e.push(new vn(this.player_,{kind:this.kind_})),this.hideThreshold_+=1),n.prototype.createItems.call(this,e)},e}(qt);s.prototype.kind_="captions",s.prototype.controlText_="Captions",gt.registerComponent("CaptionsButton",s);var _n=function(n){function e(){return n.apply(this,arguments)||this}return vt(e,n),e.prototype.createEl=function(e,t,i){t=n.prototype.createEl.call(this,e,t,i),i=t.querySelector(".vjs-menu-item-text");return"captions"===this.options_.track.kind&&(i.appendChild(te("span",{className:"vjs-icon-placeholder"},{"aria-hidden":!0})),i.appendChild(te("span",{className:"vjs-control-text",textContent:" "+this.localize("Captions")}))),t},e}(mn);gt.registerComponent("SubsCapsMenuItem",_n);L=function(i){function e(e,t){return(t=i.call(this,e,t=void 0===t?{}:t)||this).label_="subtitles",-1<["en","en-us","en-ca","fr-ca"].indexOf(t.player_.language_)&&(t.label_="captions"),t.menuButton_.controlText(ht(t.label_)),t}vt(e,i);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-subs-caps-button "+i.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-subs-caps-button "+i.prototype.buildWrapperCSSClass.call(this)},t.createItems=function(){var e=[];return this.player().tech_&&this.player().tech_.featuresNativeTextTracks||!this.player().getChild("textTrackSettings")||(e.push(new vn(this.player_,{kind:this.label_})),this.hideThreshold_+=1),e=i.prototype.createItems.call(this,e,_n)},e}(qt);L.prototype.kinds_=["captions","subtitles"],L.prototype.controlText_="Subtitles",gt.registerComponent("SubsCapsButton",L);var bn=function(s){function e(e,t){var n,i=t.track,r=e.audioTracks();t.label=i.label||i.language||"Unknown",t.selected=i.enabled,(n=s.call(this,e,t)||this).track=i,n.addClass("vjs-"+i.kind+"-menu-item");function a(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];n.handleTracksChange.apply(yt(n),t)}return r.addEventListener("change",a),n.on("dispose",function(){r.removeEventListener("change",a)}),n}vt(e,s);var t=e.prototype;return t.createEl=function(e,t,i){t=s.prototype.createEl.call(this,e,t,i),i=t.querySelector(".vjs-menu-item-text");return"main-desc"===this.options_.track.kind&&(i.appendChild(s.prototype.createEl.call(this,"span",{className:"vjs-icon-placeholder"},{"aria-hidden":!0})),i.appendChild(s.prototype.createEl.call(this,"span",{className:"vjs-control-text",textContent:this.localize("Descriptions")}))),t},t.handleClick=function(e){s.prototype.handleClick.call(this,e),this.track.enabled=!0},t.handleTracksChange=function(e){this.selected(this.track.enabled)},e}(A);gt.registerComponent("AudioTrackMenuItem",bn);D=function(i){function e(e,t){return(t=void 0===t?{}:t).tracks=e.audioTracks(),i.call(this,e,t)||this}vt(e,i);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-audio-button "+i.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-audio-button "+i.prototype.buildWrapperCSSClass.call(this)},t.createItems=function(e){void 0===e&&(e=[]),this.hideThreshold_=1;for(var t=this.player_.audioTracks(),i=0;i<t.length;i++){var n=t[i];e.push(new bn(this.player_,{track:n,selectable:!0,multiSelectable:!1}))}return e},e}(on);D.prototype.controlText_="Audio Track",gt.registerComponent("AudioTrackButton",D);var Tn=function(a){function e(e,t){var i,n=t.rate,r=parseFloat(n,10);return t.label=n,t.selected=r===e.playbackRate(),t.selectable=!0,t.multiSelectable=!1,(i=a.call(this,e,t)||this).label=n,i.rate=r,i.on(e,"ratechange",function(e){return i.update(e)}),i}vt(e,a);var t=e.prototype;return t.handleClick=function(e){a.prototype.handleClick.call(this),this.player().playbackRate(this.rate)},t.update=function(e){this.selected(this.player().playbackRate()===this.rate)},e}(A);Tn.prototype.contentElType="button",gt.registerComponent("PlaybackRateMenuItem",Tn);H=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.menuButton_.el_.setAttribute("aria-describedby",i.labelElId_),i.updateVisibility(),i.updateLabel(),i.on(e,"loadstart",function(e){return i.updateVisibility(e)}),i.on(e,"ratechange",function(e){return i.updateLabel(e)}),i.on(e,"playbackrateschange",function(e){return i.handlePlaybackRateschange(e)}),i}vt(e,n);var t=e.prototype;return t.createEl=function(){var e=n.prototype.createEl.call(this);return this.labelElId_="vjs-playback-rate-value-label-"+this.id_,this.labelEl_=te("div",{className:"vjs-playback-rate-value",id:this.labelElId_,textContent:"1x"}),e.appendChild(this.labelEl_),e},t.dispose=function(){this.labelEl_=null,n.prototype.dispose.call(this)},t.buildCSSClass=function(){return"vjs-playback-rate "+n.prototype.buildCSSClass.call(this)},t.buildWrapperCSSClass=function(){return"vjs-playback-rate "+n.prototype.buildWrapperCSSClass.call(this)},t.createItems=function(){for(var e=this.playbackRates(),t=[],i=e.length-1;0<=i;i--)t.push(new Tn(this.player(),{rate:e[i]+"x"}));return t},t.updateARIAAttributes=function(){this.el().setAttribute("aria-valuenow",this.player().playbackRate())},t.handleClick=function(e){for(var t=this.player().playbackRate(),i=this.playbackRates(),n=i[0],r=0;r<i.length;r++)if(i[r]>t){n=i[r];break}this.player().playbackRate(n)},t.handlePlaybackRateschange=function(e){this.update()},t.playbackRates=function(){var e=this.player();return e.playbackRates&&e.playbackRates()||[]},t.playbackRateSupported=function(){return this.player().tech_&&this.player().tech_.featuresPlaybackRate&&this.playbackRates()&&0<this.playbackRates().length},t.updateVisibility=function(e){this.playbackRateSupported()?this.removeClass("vjs-hidden"):this.addClass("vjs-hidden")},t.updateLabel=function(e){this.playbackRateSupported()&&(this.labelEl_.textContent=this.player().playbackRate()+"x")},e}(W);H.prototype.controlText_="Playback Rate",gt.registerComponent("PlaybackRateMenuButton",H);P=function(n){function e(){return n.apply(this,arguments)||this}vt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-spacer "+n.prototype.buildCSSClass.call(this)},t.createEl=function(e,t,i){return void 0===e&&(e="div"),void 0===i&&(i={}),(t=void 0===t?{}:t).className||(t.className=this.buildCSSClass()),n.prototype.createEl.call(this,e,t,i)},e}(gt);gt.registerComponent("Spacer",P),gt.registerComponent("CustomControlSpacer",function(e){function t(){return e.apply(this,arguments)||this}vt(t,e);var i=t.prototype;return i.buildCSSClass=function(){return"vjs-custom-control-spacer "+e.prototype.buildCSSClass.call(this)},i.createEl=function(){return e.prototype.createEl.call(this,"div",{className:this.buildCSSClass(),textContent:" "})},t}(P));o=function(e){function t(){return e.apply(this,arguments)||this}return vt(t,e),t.prototype.createEl=function(){return e.prototype.createEl.call(this,"div",{className:"vjs-control-bar",dir:"ltr"})},t}(gt);o.prototype.options_={children:["playToggle","volumePanel","currentTimeDisplay","timeDivider","durationDisplay","progressControl","liveDisplay","seekToLive","remainingTimeDisplay","customControlSpacer","playbackRateMenuButton","chaptersButton","descriptionsButton","subsCapsButton","audioTrackButton","fullscreenToggle"]},"exitPictureInPicture"in d&&o.prototype.options_.children.splice(o.prototype.options_.children.length-1,0,"pictureInPictureToggle"),gt.registerComponent("ControlBar",o);e=function(n){function e(e,t){var i=n.call(this,e,t)||this;return i.on(e,"error",function(e){return i.open(e)}),i}vt(e,n);var t=e.prototype;return t.buildCSSClass=function(){return"vjs-error-display "+n.prototype.buildCSSClass.call(this)},t.content=function(){var e=this.player().error();return e?this.localize(e.message):""},e}(Ot);e.prototype.options_=b({},Ot.prototype.options_,{pauseOnOpen:!1,fillAlways:!0,temporary:!1,uncloseable:!0}),gt.registerComponent("ErrorDisplay",e);var Sn="vjs-text-track-settings",s=["#000","Black"],qt=["#00F","Blue"],L=["#0FF","Cyan"],on=["#0F0","Green"],D=["#F0F","Magenta"],A=["#F00","Red"],W=["#FFF","White"],H=["#FF0","Yellow"],P=["1","Opaque"],o=["0.5","Semi-Transparent"],e=["0","Transparent"],En={backgroundColor:{selector:".vjs-bg-color > select",id:"captions-background-color-%s",label:"Color",options:[s,W,A,on,qt,H,D,L]},backgroundOpacity:{selector:".vjs-bg-opacity > select",id:"captions-background-opacity-%s",label:"Transparency",options:[P,o,e]},color:{selector:".vjs-fg-color > select",id:"captions-foreground-color-%s",label:"Color",options:[W,s,A,on,qt,H,D,L]},edgeStyle:{selector:".vjs-edge-style > select",id:"%s",label:"Text Edge Style",options:[["none","None"],["raised","Raised"],["depressed","Depressed"],["uniform","Uniform"],["dropshadow","Dropshadow"]]},fontFamily:{selector:".vjs-font-family > select",id:"captions-font-family-%s",label:"Font Family",options:[["proportionalSansSerif","Proportional Sans-Serif"],["monospaceSansSerif","Monospace Sans-Serif"],["proportionalSerif","Proportional Serif"],["monospaceSerif","Monospace Serif"],["casual","Casual"],["script","Script"],["small-caps","Small Caps"]]},fontPercent:{selector:".vjs-font-percent > select",id:"captions-font-size-%s",label:"Font Size",options:[["0.50","50%"],["0.75","75%"],["1.00","100%"],["1.25","125%"],["1.50","150%"],["1.75","175%"],["2.00","200%"],["3.00","300%"],["4.00","400%"]],default:2,parser:function(e){return"1.00"===e?null:Number(e)}},textOpacity:{selector:".vjs-text-opacity > select",id:"captions-foreground-opacity-%s",label:"Transparency",options:[P,o]},windowColor:{selector:".vjs-window-color > select",id:"captions-window-color-%s",label:"Color"},windowOpacity:{selector:".vjs-window-opacity > select",id:"captions-window-opacity-%s",label:"Transparency",options:[e,o,P]}};function kn(e,t){if((e=t?t(e):e)&&"none"!==e)return e}En.windowColor.options=En.backgroundColor.options,gt.registerComponent("TextTrackSettings",function(n){function e(e,t){var i;return t.temporary=!1,(i=n.call(this,e,t)||this).updateDisplay=i.updateDisplay.bind(yt(i)),i.fill(),i.hasBeenOpened_=i.hasBeenFilled_=!0,i.endDialog=te("p",{className:"vjs-control-text",textContent:i.localize("End of dialog window.")}),i.el().appendChild(i.endDialog),i.setDefaults(),void 0===t.persistTextTrackSettings&&(i.options_.persistTextTrackSettings=i.options_.playerOptions.persistTextTrackSettings),i.on(i.$(".vjs-done-button"),"click",function(){i.saveSettings(),i.close()}),i.on(i.$(".vjs-default-button"),"click",function(){i.setDefaults(),i.updateDisplay()}),E(En,function(e){i.on(i.$(e.selector),"change",i.updateDisplay)}),i.options_.persistTextTrackSettings&&i.restoreSettings(),i}vt(e,n);var t=e.prototype;return t.dispose=function(){this.endDialog=null,n.prototype.dispose.call(this)},t.createElSelect_=function(e,t,i){var n=this;void 0===t&&(t=""),void 0===i&&(i="label");var e=En[e],r=e.id.replace("%s",this.id_),a=[t,r].join(" ").trim();return["<"+i+' id="'+r+'" class="'+("label"===i?"vjs-label":"")+'">',this.localize(e.label),"</"+i+">",'<select aria-labelledby="'+a+'">'].concat(e.options.map(function(e){var t=r+"-"+e[1].replace(/\W+/g,"");return['<option id="'+t+'" value="'+e[0]+'" ','aria-labelledby="'+a+" "+t+'">',n.localize(e[1]),"</option>"].join("")})).concat("</select>").join("")},t.createElFgColor_=function(){var e="captions-text-legend-"+this.id_;return['<fieldset class="vjs-fg-color vjs-track-setting">','<legend id="'+e+'">',this.localize("Text"),"</legend>",this.createElSelect_("color",e),'<span class="vjs-text-opacity vjs-opacity">',this.createElSelect_("textOpacity",e),"</span>","</fieldset>"].join("")},t.createElBgColor_=function(){var e="captions-background-"+this.id_;return['<fieldset class="vjs-bg-color vjs-track-setting">','<legend id="'+e+'">',this.localize("Background"),"</legend>",this.createElSelect_("backgroundColor",e),'<span class="vjs-bg-opacity vjs-opacity">',this.createElSelect_("backgroundOpacity",e),"</span>","</fieldset>"].join("")},t.createElWinColor_=function(){var e="captions-window-"+this.id_;return['<fieldset class="vjs-window-color vjs-track-setting">','<legend id="'+e+'">',this.localize("Window"),"</legend>",this.createElSelect_("windowColor",e),'<span class="vjs-window-opacity vjs-opacity">',this.createElSelect_("windowOpacity",e),"</span>","</fieldset>"].join("")},t.createElColors_=function(){return te("div",{className:"vjs-track-settings-colors",innerHTML:[this.createElFgColor_(),this.createElBgColor_(),this.createElWinColor_()].join("")})},t.createElFont_=function(){return te("div",{className:"vjs-track-settings-font",innerHTML:['<fieldset class="vjs-font-percent vjs-track-setting">',this.createElSelect_("fontPercent","","legend"),"</fieldset>",'<fieldset class="vjs-edge-style vjs-track-setting">',this.createElSelect_("edgeStyle","","legend"),"</fieldset>",'<fieldset class="vjs-font-family vjs-track-setting">',this.createElSelect_("fontFamily","","legend"),"</fieldset>"].join("")})},t.createElControls_=function(){var e=this.localize("restore all settings to the default values");return te("div",{className:"vjs-track-settings-controls",innerHTML:['<button type="button" class="vjs-default-button" title="'+e+'">',this.localize("Reset"),'<span class="vjs-control-text"> '+e+"</span>","</button>",'<button type="button" class="vjs-done-button">'+this.localize("Done")+"</button>"].join("")})},t.content=function(){return[this.createElColors_(),this.createElFont_(),this.createElControls_()]},t.label=function(){return this.localize("Caption Settings Dialog")},t.description=function(){return this.localize("Beginning of dialog window. Escape will cancel and close the window.")},t.buildCSSClass=function(){return n.prototype.buildCSSClass.call(this)+" vjs-text-track-settings"},t.getValues=function(){var i,n,e,r=this;return n=function(e,t,i){var n,t=(n=r.$(t.selector),t=t.parser,kn(n.options[n.options.selectedIndex].value,t));return void 0!==t&&(e[i]=t),e},void 0===(e={})&&(e=0),S(i=En).reduce(function(e,t){return n(e,i[t],t)},e)},t.setValues=function(i){var n=this;E(En,function(e,t){!function(e,t,i){if(t)for(var n=0;n<e.options.length;n++)if(kn(e.options[n].value,i)===t){e.selectedIndex=n;break}}(n.$(e.selector),i[t],e.parser)})},t.setDefaults=function(){var i=this;E(En,function(e){var t=e.hasOwnProperty("default")?e.default:0;i.$(e.selector).selectedIndex=t})},t.restoreSettings=function(){var e;try{e=JSON.parse(_.localStorage.getItem(Sn))}catch(e){y.warn(e)}e&&this.setValues(e)},t.saveSettings=function(){if(this.options_.persistTextTrackSettings){var e=this.getValues();try{Object.keys(e).length?_.localStorage.setItem(Sn,JSON.stringify(e)):_.localStorage.removeItem(Sn)}catch(e){y.warn(e)}}},t.updateDisplay=function(){var e=this.player_.getChild("textTrackDisplay");e&&e.updateDisplay()},t.conditionalBlur_=function(){this.previouslyActiveEl_=null;var e=this.player_.controlBar,t=e&&e.subsCapsButton,e=e&&e.captionsButton;t?t.focus():e&&e.focus()},e}(Ot)),gt.registerComponent("ResizeManager",function(a){function e(e,t){var i,n=t.ResizeObserver||_.ResizeObserver,r=pt({createEl:!(n=null===t.ResizeObserver?!1:n),reportTouchActivity:!1},t);return(i=a.call(this,e,r)||this).ResizeObserver=t.ResizeObserver||_.ResizeObserver,i.loadListener_=null,i.resizeObserver_=null,i.debouncedHandler_=Ye(function(){i.resizeHandler()},100,!1,yt(i)),n?(i.resizeObserver_=new i.ResizeObserver(i.debouncedHandler_),i.resizeObserver_.observe(e.el())):(i.loadListener_=function(){var e,t;i.el_&&i.el_.contentWindow&&(e=i.debouncedHandler_,t=i.unloadListener_=function(){Ve(this,"resize",e),Ve(this,"unload",t),t=null},qe(i.el_.contentWindow,"unload",t),qe(i.el_.contentWindow,"resize",e))},i.one("load",i.loadListener_)),i}vt(e,a);var t=e.prototype;return t.createEl=function(){return a.prototype.createEl.call(this,"iframe",{className:"vjs-resize-manager",tabIndex:-1},{"aria-hidden":"true"})},t.resizeHandler=function(){this.player_&&this.player_.trigger&&this.player_.trigger("playerresize")},t.dispose=function(){this.debouncedHandler_&&this.debouncedHandler_.cancel(),this.resizeObserver_&&(this.player_.el()&&this.resizeObserver_.unobserve(this.player_.el()),this.resizeObserver_.disconnect()),this.loadListener_&&this.off("load",this.loadListener_),this.el_&&this.el_.contentWindow&&this.unloadListener_&&this.unloadListener_.call(this.el_.contentWindow),this.ResizeObserver=null,this.resizeObserver=null,this.debouncedHandler_=null,this.loadListener_=null,a.prototype.dispose.call(this)},e}(gt));var Cn={trackingThreshold:30,liveTolerance:15};gt.registerComponent("LiveTracker",function(n){function e(e,t){var t=pt(Cn,t,{createEl:!1}),i=n.call(this,e,t)||this;return i.handleVisibilityChange_=function(e){return i.handleVisibilityChange(e)},i.trackLiveHandler_=function(){return i.trackLive_()},i.handlePlay_=function(e){return i.handlePlay(e)},i.handleFirstTimeupdate_=function(e){return i.handleFirstTimeupdate(e)},i.handleSeeked_=function(e){return i.handleSeeked(e)},i.seekToLiveEdge_=function(e){return i.seekToLiveEdge(e)},i.reset_(),i.on(i.player_,"durationchange",function(e){return i.handleDurationchange(e)}),i.one(i.player_,"canplay",function(){return i.toggleTracking()}),j&&"hidden"in d&&"visibilityState"in d&&i.on(d,"visibilitychange",i.handleVisibilityChange_),i}vt(e,n);var t=e.prototype;return t.handleVisibilityChange=function(){this.player_.duration()===1/0&&(d.hidden?this.stopTracking():this.startTracking())},t.trackLive_=function(){var e,t=this.player_.seekable();t&&t.length&&(e=Number(_.performance.now().toFixed(4)),t=-1===this.lastTime_?0:(e-this.lastTime_)/1e3,this.lastTime_=e,this.pastSeekEnd_=this.pastSeekEnd()+t,e=this.liveCurrentTime(),t=this.player_.currentTime(),t=this.player_.paused()||this.seekedBehindLive_||Math.abs(e-t)>this.options_.liveTolerance,(t=!this.timeupdateSeen_||e===1/0?!1:t)!==this.behindLiveEdge_&&(this.behindLiveEdge_=t,this.trigger("liveedgechange")))},t.handleDurationchange=function(){this.toggleTracking()},t.toggleTracking=function(){this.player_.duration()===1/0&&this.liveWindow()>=this.options_.trackingThreshold?(this.player_.options_.liveui&&this.player_.addClass("vjs-liveui"),this.startTracking()):(this.player_.removeClass("vjs-liveui"),this.stopTracking())},t.startTracking=function(){this.isTracking()||(this.timeupdateSeen_||(this.timeupdateSeen_=this.player_.hasStarted()),this.trackingInterval_=this.setInterval(this.trackLiveHandler_,30),this.trackLive_(),this.on(this.player_,["play","pause"],this.trackLiveHandler_),this.timeupdateSeen_?this.on(this.player_,"seeked",this.handleSeeked_):(this.one(this.player_,"play",this.handlePlay_),this.one(this.player_,"timeupdate",this.handleFirstTimeupdate_)))},t.handleFirstTimeupdate=function(){this.timeupdateSeen_=!0,this.on(this.player_,"seeked",this.handleSeeked_)},t.handleSeeked=function(){var e=Math.abs(this.liveCurrentTime()-this.player_.currentTime());this.seekedBehindLive_=this.nextSeekedFromUser_&&2<e,this.nextSeekedFromUser_=!1,this.trackLive_()},t.handlePlay=function(){this.one(this.player_,"timeupdate",this.seekToLiveEdge_)},t.reset_=function(){this.lastTime_=-1,this.pastSeekEnd_=0,this.lastSeekEnd_=-1,this.behindLiveEdge_=!0,this.timeupdateSeen_=!1,this.seekedBehindLive_=!1,this.nextSeekedFromUser_=!1,this.clearInterval(this.trackingInterval_),this.trackingInterval_=null,this.off(this.player_,["play","pause"],this.trackLiveHandler_),this.off(this.player_,"seeked",this.handleSeeked_),this.off(this.player_,"play",this.handlePlay_),this.off(this.player_,"timeupdate",this.handleFirstTimeupdate_),this.off(this.player_,"timeupdate",this.seekToLiveEdge_)},t.nextSeekedFromUser=function(){this.nextSeekedFromUser_=!0},t.stopTracking=function(){this.isTracking()&&(this.reset_(),this.trigger("liveedgechange"))},t.seekableEnd=function(){for(var e=this.player_.seekable(),t=[],i=e?e.length:0;i--;)t.push(e.end(i));return t.length?t.sort()[t.length-1]:1/0},t.seekableStart=function(){for(var e=this.player_.seekable(),t=[],i=e?e.length:0;i--;)t.push(e.start(i));return t.length?t.sort()[0]:0},t.liveWindow=function(){var e=this.liveCurrentTime();return e===1/0?0:e-this.seekableStart()},t.isLive=function(){return this.isTracking()},t.atLiveEdge=function(){return!this.behindLiveEdge()},t.liveCurrentTime=function(){return this.pastSeekEnd()+this.seekableEnd()},t.pastSeekEnd=function(){var e=this.seekableEnd();return-1!==this.lastSeekEnd_&&e!==this.lastSeekEnd_&&(this.pastSeekEnd_=0),this.lastSeekEnd_=e,this.pastSeekEnd_},t.behindLiveEdge=function(){return this.behindLiveEdge_},t.isTracking=function(){return"number"==typeof this.trackingInterval_},t.seekToLiveEdge=function(){this.seekedBehindLive_=!1,this.atLiveEdge()||(this.nextSeekedFromUser_=!1,this.player_.currentTime(this.liveCurrentTime()))},t.dispose=function(){this.off(d,"visibilitychange",this.handleVisibilityChange_),this.stopTracking(),n.prototype.dispose.call(this)},e}(gt));function wn(e){if((n=e.el()).hasAttribute("src"))return e.triggerSourceset(n.src),1;var t=e.$$("source"),i=[],n="";if(t.length){for(var r=0;r<t.length;r++){var a=t[r].src;a&&-1===i.indexOf(a)&&i.push(a)}return!!i.length&&(1===i.length&&(n=i[0]),e.triggerSourceset(n),!0)}}function In(e,t){for(var i={},n=0;n<e.length&&!((i=Object.getOwnPropertyDescriptor(e[n],t))&&i.set&&i.get);n++);return i.enumerable=!0,i.configurable=!0,i}function xn(a){var t,e,i,s=a.el();s.resetSourceWatch_||(t={},e=In([a.el(),_.HTMLMediaElement.prototype,_.Element.prototype,Dn],"innerHTML"),i=function(r){return function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var n=r.apply(s,t);return wn(a),n}},["append","appendChild","insertAdjacentHTML"].forEach(function(e){s[e]&&(t[e]=s[e],s[e]=i(t[e]))}),Object.defineProperty(s,"innerHTML",pt(e,{set:i(e.set)})),s.resetSourceWatch_=function(){s.resetSourceWatch_=null,Object.keys(t).forEach(function(e){s[e]=t[e]}),Object.defineProperty(s,"innerHTML",e)},a.one("sourceset",s.resetSourceWatch_))}function An(i){var n,t,r,a;i.featuresSourceset&&((n=i.el()).resetSourceset_||(t=In([i.el(),_.HTMLMediaElement.prototype,On],"src"),r=n.setAttribute,a=n.load,Object.defineProperty(n,"src",pt(t,{set:function(e){e=t.set.call(n,e);return i.triggerSourceset(n.src),e}})),n.setAttribute=function(e,t){t=r.call(n,e,t);return/src/i.test(e)&&i.triggerSourceset(n.src),t},n.load=function(){var e=a.call(n);return wn(i)||(i.triggerSourceset(""),xn(i)),e},n.currentSrc?i.triggerSourceset(n.currentSrc):wn(i)||xn(i),n.resetSourceset_=function(){n.resetSourceset_=null,n.load=a,n.setAttribute=r,Object.defineProperty(n,"src",t),n.resetSourceWatch_&&n.resetSourceWatch_()}))}function Pn(t,i,n,e){function r(e){return Object.defineProperty(t,i,{value:e,enumerable:!0,writable:!0})}var a={configurable:!0,enumerable:!0,get:function(){var e=n();return r(e),e}};return(e=void 0===e?!0:e)&&(a.set=r),Object.defineProperty(t,i,a)}var Ln,Dn=Object.defineProperty({},"innerHTML",{get:function(){return this.cloneNode(!0).innerHTML},set:function(e){var t=d.createElement(this.nodeName.toLowerCase());t.innerHTML=e;for(var i=d.createDocumentFragment();t.childNodes.length;)i.appendChild(t.childNodes[0]);return this.innerText="",_.Element.prototype.appendChild.call(this,i),this.innerHTML}}),On=Object.defineProperty({},"src",{get:function(){return this.hasAttribute("src")?Ft(_.Element.prototype.getAttribute.call(this,"src")):""},set:function(e){return _.Element.prototype.setAttribute.call(this,"src",e),e}}),Rn=function(l){function s(e,t){var i=l.call(this,e,t)||this,t=e.source,n=!1;if(t&&(i.el_.currentSrc!==t.src||e.tag&&3===e.tag.initNetworkState_)?i.setSource(t):i.handleLateInit_(i.el_),e.enableSourceset&&i.setupSourcesetHandling_(),i.isScrubbing_=!1,i.el_.hasChildNodes()){for(var r=i.el_.childNodes,a=r.length,s=[];a--;){var o=r[a];"track"===o.nodeName.toLowerCase()&&(i.featuresNativeTextTracks?(i.remoteTextTrackEls().addTrackElement_(o),i.remoteTextTracks().addTrack(o.track),i.textTracks().addTrack(o.track),n||i.el_.hasAttribute("crossorigin")||!Ht(o.src)||(n=!0)):s.push(o))}for(var u=0;u<s.length;u++)i.el_.removeChild(s[u])}return i.proxyNativeTracks_(),i.featuresNativeTextTracks&&n&&y.warn("Text Tracks are being loaded from another origin but the crossorigin attribute isn't used.\nThis may prevent text tracks from loading."),i.restoreMetadataTracksInIOSNativePlayer_(),(V||z||M)&&!0===e.nativeControlsForTouch&&i.setControls(!0),i.proxyWebkitFullscreen_(),i.triggerReady(),i}vt(s,l);var e=s.prototype;return e.dispose=function(){this.el_&&this.el_.resetSourceset_&&this.el_.resetSourceset_(),s.disposeMediaElement(this.el_),this.options_=null,l.prototype.dispose.call(this)},e.setupSourcesetHandling_=function(){An(this)},e.restoreMetadataTracksInIOSNativePlayer_=function(){function e(){i=[];for(var e=0;e<n.length;e++){var t=n[e];"metadata"===t.kind&&i.push({track:t,storedMode:t.mode})}}var i,n=this.textTracks();e(),n.addEventListener("change",e),this.on("dispose",function(){return n.removeEventListener("change",e)});function r(){for(var e=0;e<i.length;e++){var t=i[e];"disabled"===t.track.mode&&t.track.mode!==t.storedMode&&(t.track.mode=t.storedMode)}n.removeEventListener("change",r)}this.on("webkitbeginfullscreen",function(){n.removeEventListener("change",e),n.removeEventListener("change",r),n.addEventListener("change",r)}),this.on("webkitendfullscreen",function(){n.removeEventListener("change",e),n.addEventListener("change",e),n.removeEventListener("change",r)})},e.overrideNative_=function(e,t){var i,n=this;t===this["featuresNative"+e+"Tracks"]&&(this[(i=e.toLowerCase())+"TracksListeners_"]&&Object.keys(this[i+"TracksListeners_"]).forEach(function(e){n.el()[i+"Tracks"].removeEventListener(e,n[i+"TracksListeners_"][e])}),this["featuresNative"+e+"Tracks"]=!t,this[i+"TracksListeners_"]=null,this.proxyNativeTracksForType_(i))},e.overrideNativeAudioTracks=function(e){this.overrideNative_("Audio",e)},e.overrideNativeVideoTracks=function(e){this.overrideNative_("Video",e)},e.proxyNativeTracksForType_=function(i){var e,t,n=this,r=oi[i],a=this.el()[r.getterName],s=this[r.getterName]();this["featuresNative"+r.capitalName+"Tracks"]&&a&&a.addEventListener&&(t=function(){for(var e=[],t=0;t<s.length;t++){for(var i=!1,n=0;n<a.length;n++)if(a[n]===s[t]){i=!0;break}i||e.push(s[t])}for(;e.length;)s.removeTrack(e.shift())},this[r.getterName+"Listeners_"]=e={change:function(e){var t={type:"change",target:s,currentTarget:s,srcElement:s};s.trigger(t),"text"===i&&n[ui.remoteText.getterName]().trigger(t)},addtrack:function(e){s.addTrack(e.track)},removetrack:function(e){s.removeTrack(e.track)}},Object.keys(e).forEach(function(t){var i=e[t];a.addEventListener(t,i),n.on("dispose",function(e){return a.removeEventListener(t,i)})}),this.on("loadstart",t),this.on("dispose",function(e){return n.off("loadstart",t)}))},e.proxyNativeTracks_=function(){var t=this;oi.names.forEach(function(e){t.proxyNativeTracksForType_(e)})},e.createEl=function(){var e,t=this.options_.tag;t&&(this.options_.playerElIngest||this.movingMediaElementInDOM)||(t?(e=t.cloneNode(!0),t.parentNode&&t.parentNode.insertBefore(e,t),s.disposeMediaElement(t),t=e):(t=d.createElement("video"),e=pt({},this.options_.tag&&le(this.options_.tag)),V&&!0===this.options_.nativeControlsForTouch||delete e.controls,ue(t,k(e,{id:this.options_.techId,class:"vjs-tech"}))),t.playerId=this.options_.playerId),"undefined"!=typeof this.options_.preload&&de(t,"preload",this.options_.preload),void 0!==this.options_.disablePictureInPicture&&(t.disablePictureInPicture=this.options_.disablePictureInPicture);for(var i=["loop","muted","playsinline","autoplay"],n=0;n<i.length;n++){var r=i[n],a=this.options_[r];"undefined"!=typeof a&&(a?de(t,r,r):he(t,r),t[r]=a)}return t},e.handleLateInit_=function(e){if(0!==e.networkState&&3!==e.networkState){if(0===e.readyState){var t=!1,i=function(){t=!0};this.on("loadstart",i);var n=function(){t||this.trigger("loadstart")};return this.on("loadedmetadata",n),void this.ready(function(){this.off("loadstart",i),this.off("loadedmetadata",n),t||this.trigger("loadstart")})}var r=["loadstart"];r.push("loadedmetadata"),2<=e.readyState&&r.push("loadeddata"),3<=e.readyState&&r.push("canplay"),4<=e.readyState&&r.push("canplaythrough"),this.ready(function(){r.forEach(function(e){this.trigger(e)},this)})}},e.setScrubbing=function(e){this.isScrubbing_=e},e.scrubbing=function(){return this.isScrubbing_},e.setCurrentTime=function(e){try{this.isScrubbing_&&this.el_.fastSeek&&X?this.el_.fastSeek(e):this.el_.currentTime=e}catch(e){y(e,"Video is not ready. (Video.js)")}},e.duration=function(){var t=this;return this.el_.duration===1/0&&O&&B&&0===this.el_.currentTime?(this.on("timeupdate",function e(){0<t.el_.currentTime&&(t.el_.duration===1/0&&t.trigger("durationchange"),t.off("timeupdate",e))}),NaN):this.el_.duration||NaN},e.width=function(){return this.el_.offsetWidth},e.height=function(){return this.el_.offsetHeight},e.proxyWebkitFullscreen_=function(){var e,t,i=this;"webkitDisplayingFullscreen"in this.el_&&(e=function(){this.trigger("fullscreenchange",{isFullscreen:!1})},t=function(){"webkitPresentationMode"in this.el_&&"picture-in-picture"!==this.el_.webkitPresentationMode&&(this.one("webkitendfullscreen",e),this.trigger("fullscreenchange",{isFullscreen:!0,nativeIOSFullscreen:!0}))},this.on("webkitbeginfullscreen",t),this.on("dispose",function(){i.off("webkitbeginfullscreen",t),i.off("webkitendfullscreen",e)}))},e.supportsFullScreen=function(){if("function"==typeof this.el_.webkitEnterFullScreen){var e=_.navigator&&_.navigator.userAgent||"";if(/Android/.test(e)||!/Chrome|Mac OS X 10.5/.test(e))return!0}return!1},e.enterFullScreen=function(){var e=this.el_;if(e.paused&&e.networkState<=e.HAVE_METADATA)It(this.el_.play()),this.setTimeout(function(){e.pause();try{e.webkitEnterFullScreen()}catch(e){this.trigger("fullscreenerror",e)}},0);else try{e.webkitEnterFullScreen()}catch(e){this.trigger("fullscreenerror",e)}},e.exitFullScreen=function(){this.el_.webkitDisplayingFullscreen?this.el_.webkitExitFullScreen():this.trigger("fullscreenerror",new Error("The video is not fullscreen"))},e.requestPictureInPicture=function(){return this.el_.requestPictureInPicture()},e.src=function(e){if(void 0===e)return this.el_.src;this.setSrc(e)},e.reset=function(){s.resetMediaElement(this.el_)},e.currentSrc=function(){return this.currentSource_?this.currentSource_.src:this.el_.currentSrc},e.setControls=function(e){this.el_.controls=!!e},e.addTextTrack=function(e,t,i){return this.featuresNativeTextTracks?this.el_.addTextTrack(e,t,i):l.prototype.addTextTrack.call(this,e,t,i)},e.createRemoteTextTrack=function(e){if(!this.featuresNativeTextTracks)return l.prototype.createRemoteTextTrack.call(this,e);var t=d.createElement("track");return e.kind&&(t.kind=e.kind),e.label&&(t.label=e.label),(e.language||e.srclang)&&(t.srclang=e.language||e.srclang),e.default&&(t.default=e.default),e.id&&(t.id=e.id),e.src&&(t.src=e.src),t},e.addRemoteTextTrack=function(e,t){t=l.prototype.addRemoteTextTrack.call(this,e,t);return this.featuresNativeTextTracks&&this.el().appendChild(t),t},e.removeRemoteTextTrack=function(e){if(l.prototype.removeRemoteTextTrack.call(this,e),this.featuresNativeTextTracks)for(var t=this.$$("track"),i=t.length;i--;)e!==t[i]&&e!==t[i].track||this.el().removeChild(t[i])},e.getVideoPlaybackQuality=function(){if("function"==typeof this.el().getVideoPlaybackQuality)return this.el().getVideoPlaybackQuality();var e={};return"undefined"!=typeof this.el().webkitDroppedFrameCount&&"undefined"!=typeof this.el().webkitDecodedFrameCount&&(e.droppedVideoFrames=this.el().webkitDroppedFrameCount,e.totalVideoFrames=this.el().webkitDecodedFrameCount),_.performance&&"function"==typeof _.performance.now?e.creationTime=_.performance.now():_.performance&&_.performance.timing&&"number"==typeof _.performance.timing.navigationStart&&(e.creationTime=_.Date.now()-_.performance.timing.navigationStart),e},s}(ji);Pn(Rn,"TEST_VID",function(){if($()){var e=d.createElement("video"),t=d.createElement("track");return t.kind="captions",t.srclang="en",t.label="English",e.appendChild(t),e}}),Rn.isSupported=function(){try{Rn.TEST_VID.volume=.5}catch(e){return!1}return!(!Rn.TEST_VID||!Rn.TEST_VID.canPlayType)},Rn.canPlayType=function(e){return Rn.TEST_VID.canPlayType(e)},Rn.canPlaySource=function(e,t){return Rn.canPlayType(e.type)},Rn.canControlVolume=function(){try{var e=Rn.TEST_VID.volume;return Rn.TEST_VID.volume=e/2+.1,e!==Rn.TEST_VID.volume}catch(e){return!1}},Rn.canMuteVolume=function(){try{var e=Rn.TEST_VID.muted;return Rn.TEST_VID.muted=!e,Rn.TEST_VID.muted?de(Rn.TEST_VID,"muted","muted"):he(Rn.TEST_VID,"muted"),e!==Rn.TEST_VID.muted}catch(e){return!1}},Rn.canControlPlaybackRate=function(){if(O&&B&&F<58)return!1;try{var e=Rn.TEST_VID.playbackRate;return Rn.TEST_VID.playbackRate=e/2+.1,e!==Rn.TEST_VID.playbackRate}catch(e){return!1}},Rn.canOverrideAttributes=function(){try{var e=function(){};Object.defineProperty(d.createElement("video"),"src",{get:e,set:e}),Object.defineProperty(d.createElement("audio"),"src",{get:e,set:e}),Object.defineProperty(d.createElement("video"),"innerHTML",{get:e,set:e}),Object.defineProperty(d.createElement("audio"),"innerHTML",{get:e,set:e})}catch(e){return!1}return!0},Rn.supportsNativeTextTracks=function(){return X||G&&B},Rn.supportsNativeVideoTracks=function(){return!(!Rn.TEST_VID||!Rn.TEST_VID.videoTracks)},Rn.supportsNativeAudioTracks=function(){return!(!Rn.TEST_VID||!Rn.TEST_VID.audioTracks)},Rn.Events=["loadstart","suspend","abort","error","emptied","stalled","loadedmetadata","loadeddata","canplay","canplaythrough","playing","waiting","seeking","seeked","ended","durationchange","timeupdate","progress","play","pause","ratechange","resize","volumechange"],[["featuresVolumeControl","canControlVolume"],["featuresMuteControl","canMuteVolume"],["featuresPlaybackRate","canControlPlaybackRate"],["featuresSourceset","canOverrideAttributes"],["featuresNativeTextTracks","supportsNativeTextTracks"],["featuresNativeVideoTracks","supportsNativeVideoTracks"],["featuresNativeAudioTracks","supportsNativeAudioTracks"]].forEach(function(e){var t=e[0],i=e[1];Pn(Rn.prototype,t,function(){return Rn[i]()},!0)}),Rn.prototype.movingMediaElementInDOM=!G,Rn.prototype.featuresFullscreenResize=!0,Rn.prototype.featuresProgressEvents=!0,Rn.prototype.featuresTimeupdateEvents=!0,Rn.patchCanPlayType=function(){4<=R&&!N&&!B&&(Ln=Rn.TEST_VID&&Rn.TEST_VID.constructor.prototype.canPlayType,Rn.TEST_VID.constructor.prototype.canPlayType=function(e){return e&&/^application\/(?:x-|vnd\.apple\.)mpegurl/i.test(e)?"maybe":Ln.call(this,e)})},Rn.unpatchCanPlayType=function(){var e=Rn.TEST_VID.constructor.prototype.canPlayType;return Ln&&(Rn.TEST_VID.constructor.prototype.canPlayType=Ln),e},Rn.patchCanPlayType(),Rn.disposeMediaElement=function(e){if(e){for(e.parentNode&&e.parentNode.removeChild(e);e.hasChildNodes();)e.removeChild(e.firstChild);e.removeAttribute("src"),"function"==typeof e.load&&function(){try{e.load()}catch(e){}}()}},Rn.resetMediaElement=function(e){if(e){for(var t=e.querySelectorAll("source"),i=t.length;i--;)e.removeChild(t[i]);e.removeAttribute("src"),"function"==typeof e.load&&function(){try{e.load()}catch(e){}}()}},["muted","defaultMuted","autoplay","controls","loop","playsinline"].forEach(function(e){Rn.prototype[e]=function(){return this.el_[e]||this.el_.hasAttribute(e)}}),["muted","defaultMuted","autoplay","loop","playsinline"].forEach(function(t){Rn.prototype["set"+ht(t)]=function(e){(this.el_[t]=e)?this.el_.setAttribute(t,t):this.el_.removeAttribute(t)}}),["paused","currentTime","buffered","volume","poster","preload","error","seeking","seekable","ended","playbackRate","defaultPlaybackRate","disablePictureInPicture","played","networkState","readyState","videoWidth","videoHeight","crossOrigin"].forEach(function(e){Rn.prototype[e]=function(){return this.el_[e]}}),["volume","src","poster","preload","playbackRate","defaultPlaybackRate","disablePictureInPicture","crossOrigin"].forEach(function(t){Rn.prototype["set"+ht(t)]=function(e){this.el_[t]=e}}),["pause","load","play"].forEach(function(e){Rn.prototype[e]=function(){return this.el_[e]()}}),ji.withSourceHandlers(Rn),Rn.nativeSourceHandler={},Rn.nativeSourceHandler.canPlayType=function(e){try{return Rn.TEST_VID.canPlayType(e)}catch(e){return""}},Rn.nativeSourceHandler.canHandleSource=function(e,t){if(e.type)return Rn.nativeSourceHandler.canPlayType(e.type);if(e.src){e=jt(e.src);return Rn.nativeSourceHandler.canPlayType("video/"+e)}return""},Rn.nativeSourceHandler.handleSource=function(e,t,i){t.setSrc(e.src)},Rn.nativeSourceHandler.dispose=function(){},Rn.registerSourceHandler(Rn.nativeSourceHandler),ji.registerTech("Html5",Rn);var Mn=["progress","abort","suspend","emptied","stalled","loadedmetadata","loadeddata","timeupdate","resize","volumechange","texttrackchange"],Nn={canplay:"CanPlay",canplaythrough:"CanPlayThrough",playing:"Playing",seeked:"Seeked"},Un=["tiny","xsmall","small","medium","large","xlarge","huge"],Bn={};Un.forEach(function(e){var t="x"===e.charAt(0)?"x-"+e.substring(1):e;Bn[e]="vjs-layout-"+t});var Fn={tiny:210,xsmall:320,small:425,medium:768,large:1440,xlarge:2560,huge:1/0},jn=function(c){function o(e,t,i){var n,r;if(e.id=e.id||t.id||"vjs_video_"+Re++,(t=k(o.getTagSettings(e),t)).initChildren=!1,t.createEl=!1,t.evented=!1,t.reportTouchActivity=!1,!t.language)if("function"==typeof e.closest){var a=e.closest("[lang]");a&&a.getAttribute&&(t.language=a.getAttribute("lang"))}else for(var s=e;s&&1===s.nodeType;){if(le(s).hasOwnProperty("lang")){t.language=s.getAttribute("lang");break}s=s.parentNode}if((n=c.call(this,null,t,i)||this).boundDocumentFullscreenChange_=function(e){return n.documentFullscreenChange_(e)},n.boundFullWindowOnEscKey_=function(e){return n.fullWindowOnEscKey(e)},n.boundUpdateStyleEl_=function(e){return n.updateStyleEl_(e)},n.boundApplyInitTime_=function(e){return n.applyInitTime_(e)},n.boundUpdateCurrentBreakpoint_=function(e){return n.updateCurrentBreakpoint_(e)},n.boundHandleTechClick_=function(e){return n.handleTechClick_(e)},n.boundHandleTechDoubleClick_=function(e){return n.handleTechDoubleClick_(e)},n.boundHandleTechTouchStart_=function(e){return n.handleTechTouchStart_(e)},n.boundHandleTechTouchMove_=function(e){return n.handleTechTouchMove_(e)},n.boundHandleTechTouchEnd_=function(e){return n.handleTechTouchEnd_(e)},n.boundHandleTechTap_=function(e){return n.handleTechTap_(e)},n.isFullscreen_=!1,n.log=v(n.id_),n.fsApi_=l,n.isPosterFromTech_=!1,n.queuedCallbacks_=[],n.isReady_=!1,n.hasStarted_=!1,n.userActive_=!1,n.debugEnabled_=!1,!n.options_||!n.options_.techOrder||!n.options_.techOrder.length)throw new Error("No techOrder specified. Did you overwrite videojs.options instead of just changing the properties you want to override?");n.tag=e,n.tagAttributes=e&&le(e),n.language(n.options_.language),t.languages?(r={},Object.getOwnPropertyNames(t.languages).forEach(function(e){r[e.toLowerCase()]=t.languages[e]}),n.languages_=r):n.languages_=o.prototype.options_.languages,n.resetCache_(),n.poster_=t.poster||"",n.controls_=!!t.controls,e.controls=!1,e.removeAttribute("controls"),n.changingSrc_=!1,n.playCallbacks_=[],n.playTerminatedQueue_=[],e.hasAttribute("autoplay")?n.autoplay(!0):n.autoplay(n.options_.autoplay),t.plugins&&Object.keys(t.plugins).forEach(function(e){if("function"!=typeof n[e])throw new Error('plugin "'+e+'" does not exist')}),n.scrubbing_=!1,n.el_=n.createEl(),ut(yt(n),{eventBusKey:"el_"}),n.fsApi_.requestFullscreen&&(qe(d,n.fsApi_.fullscreenchange,n.boundDocumentFullscreenChange_),n.on(n.fsApi_.fullscreenchange,n.boundDocumentFullscreenChange_)),n.fluid_&&n.on(["playerreset","resize"],n.boundUpdateStyleEl_);i=pt(n.options_);t.plugins&&Object.keys(t.plugins).forEach(function(e){n[e](t.plugins[e])}),t.debug&&n.debug(!0),n.options_.playerOptions=i,n.middleware_=[],n.playbackRates(t.playbackRates),n.initChildren(),n.isAudio("audio"===e.nodeName.toLowerCase()),n.controls()?n.addClass("vjs-controls-enabled"):n.addClass("vjs-controls-disabled"),n.el_.setAttribute("role","region"),n.isAudio()?n.el_.setAttribute("aria-label",n.localize("Audio Player")):n.el_.setAttribute("aria-label",n.localize("Video Player")),n.isAudio()&&n.addClass("vjs-audio"),n.flexNotSupported_()&&n.addClass("vjs-no-flex"),V&&n.addClass("vjs-touch-enabled"),G||n.addClass("vjs-workinghover"),o.players[n.id_]=yt(n);e=u.split(".")[0];return n.addClass("vjs-v"+e),n.userActive(!0),n.reportUserActivity(),n.one("play",function(e){return n.listenForUserActivity_(e)}),n.on("stageclick",function(e){return n.handleStageClick_(e)}),n.on("keydown",function(e){return n.handleKeyDown(e)}),n.on("languagechange",function(e){return n.handleLanguagechange(e)}),n.breakpoints(n.options_.breakpoints),n.responsive(n.options_.responsive),n}vt(o,c);var e=o.prototype;return e.dispose=function(){var t=this;this.trigger("dispose"),this.off("dispose"),Ve(d,this.fsApi_.fullscreenchange,this.boundDocumentFullscreenChange_),Ve(d,"keydown",this.boundFullWindowOnEscKey_),this.styleEl_&&this.styleEl_.parentNode&&(this.styleEl_.parentNode.removeChild(this.styleEl_),this.styleEl_=null),o.players[this.id_]=null,this.tag&&this.tag.player&&(this.tag.player=null),this.el_&&this.el_.player&&(this.el_.player=null),this.tech_&&(this.tech_.dispose(),this.isPosterFromTech_=!1,this.poster_=""),this.playerElIngest_&&(this.playerElIngest_=null),this.tag&&(this.tag=null),qi[this.id()]=null,li.names.forEach(function(e){e=li[e],e=t[e.getterName]();e&&e.off&&e.off()}),c.prototype.dispose.call(this)},e.createEl=function(){var t,i=this.tag,e=this.playerElIngest_=i.parentNode&&i.parentNode.hasAttribute&&i.parentNode.hasAttribute("data-vjs-player"),n="video-js"===this.tag.tagName.toLowerCase();e?t=this.el_=i.parentNode:n||(t=this.el_=c.prototype.createEl.call(this,"div"));var r,a,s=le(i);if(n){for(t=this.el_=i,i=this.tag=d.createElement("video");t.children.length;)i.appendChild(t.firstChild);re(t,"video-js")||ae(t,"video-js"),t.appendChild(i),e=this.playerElIngest_=t,Object.keys(t).forEach(function(e){try{i[e]=t[e]}catch(e){}})}i.setAttribute("tabindex","-1"),s.tabindex="-1",(j||B&&q)&&(i.setAttribute("role","application"),s.role="application"),i.removeAttribute("width"),i.removeAttribute("height"),"width"in s&&delete s.width,"height"in s&&delete s.height,Object.getOwnPropertyNames(s).forEach(function(e){n&&"class"===e||t.setAttribute(e,s[e]),n&&i.setAttribute(e,s[e])}),i.playerId=i.id,i.id+="_html5_api",i.className="vjs-tech",(i.player=t.player=this).addClass("vjs-paused"),!0!==_.VIDEOJS_NO_DYNAMIC_STYLE&&(this.styleEl_=De("vjs-styles-dimensions"),r=Ce(".vjs-styles-defaults"),(a=Ce("head")).insertBefore(this.styleEl_,r?r.nextSibling:a.firstChild)),this.fill_=!1,this.fluid_=!1,this.width(this.options_.width),this.height(this.options_.height),this.fill(this.options_.fill),this.fluid(this.options_.fluid),this.aspectRatio(this.options_.aspectRatio),this.crossOrigin(this.options_.crossOrigin||this.options_.crossorigin);for(var o=i.getElementsByTagName("a"),u=0;u<o.length;u++){var l=o.item(u);ae(l,"vjs-hidden"),l.setAttribute("hidden","hidden")}return i.initNetworkState_=i.networkState,i.parentNode&&!e&&i.parentNode.insertBefore(t,i),ne(i,t),this.children_.unshift(i),this.el_.setAttribute("lang",this.language_),this.el_=t},e.crossOrigin=function(e){if(!e)return this.techGet_("crossOrigin");"anonymous"===e||"use-credentials"===e?this.techCall_("setCrossOrigin",e):y.warn('crossOrigin must be "anonymous" or "use-credentials", given "'+e+'"')},e.width=function(e){return this.dimension("width",e)},e.height=function(e){return this.dimension("height",e)},e.dimension=function(e,t){var i=e+"_";if(void 0===t)return this[i]||0;if(""===t||"auto"===t)return this[i]=void 0,void this.updateStyleEl_();var n=parseFloat(t);isNaN(n)?y.error('Improper value "'+t+'" supplied for for '+e):(this[i]=n,this.updateStyleEl_())},e.fluid=function(e){var t,i=this;if(void 0===e)return!!this.fluid_;this.fluid_=!!e,st(this)&&this.off(["playerreset","resize"],this.boundUpdateStyleEl_),e?(this.addClass("vjs-fluid"),this.fill(!1),t=function(){i.on(["playerreset","resize"],i.boundUpdateStyleEl_)},st(e=this)?t():(e.eventedCallbacks||(e.eventedCallbacks=[]),e.eventedCallbacks.push(t))):this.removeClass("vjs-fluid"),this.updateStyleEl_()},e.fill=function(e){if(void 0===e)return!!this.fill_;this.fill_=!!e,e?(this.addClass("vjs-fill"),this.fluid(!1)):this.removeClass("vjs-fill")},e.aspectRatio=function(e){if(void 0===e)return this.aspectRatio_;if(!/^\d+\:\d+$/.test(e))throw new Error("Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.");this.aspectRatio_=e,this.fluid(!0),this.updateStyleEl_()},e.updateStyleEl_=function(){var e,t,i,n;!0!==_.VIDEOJS_NO_DYNAMIC_STYLE?(n=(i=(void 0!==this.aspectRatio_&&"auto"!==this.aspectRatio_?this.aspectRatio_:0<this.videoWidth()?this.videoWidth()+":"+this.videoHeight():"16:9").split(":"))[1]/i[0],e=void 0!==this.width_?this.width_:void 0!==this.height_?this.height_/n:this.videoWidth()||300,t=void 0!==this.height_?this.height_:e*n,i=/^[^a-zA-Z]/.test(this.id())?"dimensions-"+this.id():this.id()+"-dimensions",this.addClass(i),Oe(this.styleEl_,"\n ."+i+" {\n width: "+e+"px;\n height: "+t+"px;\n }\n\n ."+i+".vjs-fluid {\n padding-top: "+100*n+"%;\n }\n ")):(t="number"==typeof this.width_?this.width_:this.options_.width,i="number"==typeof this.height_?this.height_:this.options_.height,(n=this.tech_&&this.tech_.el())&&(0<=t&&(n.width=t),0<=i&&(n.height=i)))},e.loadTech_=function(e,t){var i=this;this.tech_&&this.unloadTech_();var n=ht(e),r=e.charAt(0).toLowerCase()+e.slice(1);"Html5"!==n&&this.tag&&(ji.getTech("Html5").disposeMediaElement(this.tag),this.tag.player=null,this.tag=null),this.techName_=n,this.isReady_=!1;var a=this.autoplay(),s={source:t,autoplay:a="string"==typeof this.autoplay()||!0===this.autoplay()&&this.options_.normalizeAutoplay?!1:a,nativeControlsForTouch:this.options_.nativeControlsForTouch,playerId:this.id(),techId:this.id()+"_"+r+"_api",playsinline:this.options_.playsinline,preload:this.options_.preload,loop:this.options_.loop,disablePictureInPicture:this.options_.disablePictureInPicture,muted:this.options_.muted,poster:this.poster(),language:this.language(),playerElIngest:this.playerElIngest_||!1,"vtt.js":this.options_["vtt.js"],canOverridePoster:!!this.options_.techCanOverridePoster,enableSourceset:this.options_.enableSourceset,Promise:this.options_.Promise};li.names.forEach(function(e){e=li[e];s[e.getterName]=i[e.privateName]}),k(s,this.options_[n]),k(s,this.options_[r]),k(s,this.options_[e.toLowerCase()]),this.tag&&(s.tag=this.tag),t&&t.src===this.cache_.src&&0<this.cache_.currentTime&&(s.startTime=this.cache_.currentTime);e=ji.getTech(e);if(!e)throw new Error("No Tech named '"+n+"' exists! '"+n+"' should be registered using videojs.registerTech()'");this.tech_=new e(s),this.tech_.ready(Xe(this,this.handleTechReady_),!0),Pt(this.textTracksJson_||[],this.tech_),Mn.forEach(function(t){i.on(i.tech_,t,function(e){return i["handleTech"+ht(t)+"_"](e)})}),Object.keys(Nn).forEach(function(t){i.on(i.tech_,t,function(e){0===i.tech_.playbackRate()&&i.tech_.seeking()?i.queuedCallbacks_.push({callback:i["handleTech"+Nn[t]+"_"].bind(i),event:e}):i["handleTech"+Nn[t]+"_"](e)})}),this.on(this.tech_,"loadstart",function(e){return i.handleTechLoadStart_(e)}),this.on(this.tech_,"sourceset",function(e){return i.handleTechSourceset_(e)}),this.on(this.tech_,"waiting",function(e){return i.handleTechWaiting_(e)}),this.on(this.tech_,"ended",function(e){return i.handleTechEnded_(e)}),this.on(this.tech_,"seeking",function(e){return i.handleTechSeeking_(e)}),this.on(this.tech_,"play",function(e){return i.handleTechPlay_(e)}),this.on(this.tech_,"firstplay",function(e){return i.handleTechFirstPlay_(e)}),this.on(this.tech_,"pause",function(e){return i.handleTechPause_(e)}),this.on(this.tech_,"durationchange",function(e){return i.handleTechDurationChange_(e)}),this.on(this.tech_,"fullscreenchange",function(e,t){return i.handleTechFullscreenChange_(e,t)}),this.on(this.tech_,"fullscreenerror",function(e,t){return i.handleTechFullscreenError_(e,t)}),this.on(this.tech_,"enterpictureinpicture",function(e){return i.handleTechEnterPictureInPicture_(e)}),this.on(this.tech_,"leavepictureinpicture",function(e){return i.handleTechLeavePictureInPicture_(e)}),this.on(this.tech_,"error",function(e){return i.handleTechError_(e)}),this.on(this.tech_,"posterchange",function(e){return i.handleTechPosterChange_(e)}),this.on(this.tech_,"textdata",function(e){return i.handleTechTextData_(e)}),this.on(this.tech_,"ratechange",function(e){return i.handleTechRateChange_(e)}),this.on(this.tech_,"loadedmetadata",this.boundUpdateStyleEl_),this.usingNativeControls(this.techGet_("controls")),this.controls()&&!this.usingNativeControls()&&this.addTechControlsListeners_(),this.tech_.el().parentNode===this.el()||"Html5"===n&&this.tag||ne(this.tech_.el(),this.el()),this.tag&&(this.tag.player=null,this.tag=null)},e.unloadTech_=function(){var t=this;li.names.forEach(function(e){e=li[e];t[e.privateName]=t[e.getterName]()}),this.textTracksJson_=At(this.tech_),this.isReady_=!1,this.tech_.dispose(),this.tech_=!1,this.isPosterFromTech_&&(this.poster_="",this.trigger("posterchange")),this.isPosterFromTech_=!1},e.tech=function(e){return void 0===e&&y.warn("Using the tech directly can be dangerous. I hope you know what you're doing.\nSee https://github.com/videojs/video.js/issues/2617 for more info.\n"),this.tech_},e.addTechControlsListeners_=function(){this.removeTechControlsListeners_(),this.on(this.tech_,"click",this.boundHandleTechClick_),this.on(this.tech_,"dblclick",this.boundHandleTechDoubleClick_),this.on(this.tech_,"touchstart",this.boundHandleTechTouchStart_),this.on(this.tech_,"touchmove",this.boundHandleTechTouchMove_),this.on(this.tech_,"touchend",this.boundHandleTechTouchEnd_),this.on(this.tech_,"tap",this.boundHandleTechTap_)},e.removeTechControlsListeners_=function(){this.off(this.tech_,"tap",this.boundHandleTechTap_),this.off(this.tech_,"touchstart",this.boundHandleTechTouchStart_),this.off(this.tech_,"touchmove",this.boundHandleTechTouchMove_),this.off(this.tech_,"touchend",this.boundHandleTechTouchEnd_),this.off(this.tech_,"click",this.boundHandleTechClick_),this.off(this.tech_,"dblclick",this.boundHandleTechDoubleClick_)},e.handleTechReady_=function(){this.triggerReady(),this.cache_.volume&&this.techCall_("setVolume",this.cache_.volume),this.handleTechPosterChange_(),this.handleTechDurationChange_()},e.handleTechLoadStart_=function(){this.removeClass("vjs-ended"),this.removeClass("vjs-seeking"),this.error(null),this.handleTechDurationChange_(),this.paused()?(this.hasStarted(!1),this.trigger("loadstart")):(this.trigger("loadstart"),this.trigger("firstplay")),this.manualAutoplay_(!0===this.autoplay()&&this.options_.normalizeAutoplay?"play":this.autoplay())},e.manualAutoplay_=function(e){var n=this;if(this.tech_&&"string"==typeof e){var t,i=function(){var e=n.muted();n.muted(!0);function t(){n.muted(e)}n.playTerminatedQueue_.push(t);var i=n.play();if(wt(i))return i.catch(function(e){throw t(),new Error("Rejection at manualAutoplay. Restoring muted value. "+(e||""))})};if("any"!==e||this.muted()?t="muted"!==e||this.muted()?this.play():i():wt(t=this.play())&&(t=t.catch(i)),wt(t))return t.then(function(){n.trigger({type:"autoplay-success",autoplay:e})}).catch(function(){n.trigger({type:"autoplay-failure",autoplay:e})})}},e.updateSourceCaches_=function(e){var t=e=void 0===e?"":e,i="";"string"!=typeof t&&(t=e.src,i=e.type),this.cache_.source=this.cache_.source||{},this.cache_.sources=this.cache_.sources||[],t&&!i&&(i=function(e,t){if(!t)return"";if(e.cache_.source.src===t&&e.cache_.source.type)return e.cache_.source.type;var i=e.cache_.sources.filter(function(e){return e.src===t});if(i.length)return i[0].type;for(var n=e.$$("source"),r=0;r<n.length;r++){var a=n[r];if(a.type&&a.src&&a.src===t)return a.type}return $i(t)}(this,t)),this.cache_.source=pt({},e,{src:t,type:i});for(var i=this.cache_.sources.filter(function(e){return e.src&&e.src===t}),n=[],r=this.$$("source"),a=[],s=0;s<r.length;s++){var o=le(r[s]);n.push(o),o.src&&o.src===t&&a.push(o.src)}a.length&&!i.length?this.cache_.sources=n:i.length||(this.cache_.sources=[this.cache_.source]),this.cache_.src=t},e.handleTechSourceset_=function(e){var t,i,n,r=this;this.changingSrc_||(t=function(e){return r.updateSourceCaches_(e)},i=this.currentSource().src,n=e.src,i&&!/^blob:/.test(i)&&/^blob:/.test(n)&&(this.lastSource_&&(this.lastSource_.tech===n||this.lastSource_.player===i)||(t=function(){})),t(n),e.src||this.tech_.any(["sourceset","loadstart"],function(e){"sourceset"!==e.type&&(e=r.techGet("currentSrc"),r.lastSource_.tech=e,r.updateSourceCaches_(e))})),this.lastSource_={player:this.currentSource().src,tech:e.src},this.trigger({src:e.src,type:"sourceset"})},e.hasStarted=function(e){if(void 0===e)return this.hasStarted_;e!==this.hasStarted_&&(this.hasStarted_=e,this.hasStarted_?(this.addClass("vjs-has-started"),this.trigger("firstplay")):this.removeClass("vjs-has-started"))},e.handleTechPlay_=function(){this.removeClass("vjs-ended"),this.removeClass("vjs-paused"),this.addClass("vjs-playing"),this.hasStarted(!0),this.trigger("play")},e.handleTechRateChange_=function(){0<this.tech_.playbackRate()&&0===this.cache_.lastPlaybackRate&&(this.queuedCallbacks_.forEach(function(e){return e.callback(e.event)}),this.queuedCallbacks_=[]),this.cache_.lastPlaybackRate=this.tech_.playbackRate(),this.trigger("ratechange")},e.handleTechWaiting_=function(){var t=this;this.addClass("vjs-waiting"),this.trigger("waiting");var i=this.currentTime();this.on("timeupdate",function e(){i!==t.currentTime()&&(t.removeClass("vjs-waiting"),t.off("timeupdate",e))})},e.handleTechCanPlay_=function(){this.removeClass("vjs-waiting"),this.trigger("canplay")},e.handleTechCanPlayThrough_=function(){this.removeClass("vjs-waiting"),this.trigger("canplaythrough")},e.handleTechPlaying_=function(){this.removeClass("vjs-waiting"),this.trigger("playing")},e.handleTechSeeking_=function(){this.addClass("vjs-seeking"),this.trigger("seeking")},e.handleTechSeeked_=function(){this.removeClass("vjs-seeking"),this.removeClass("vjs-ended"),this.trigger("seeked")},e.handleTechFirstPlay_=function(){this.options_.starttime&&(y.warn("Passing the `starttime` option to the player will be deprecated in 6.0"),this.currentTime(this.options_.starttime)),this.addClass("vjs-has-started"),this.trigger("firstplay")},e.handleTechPause_=function(){this.removeClass("vjs-playing"),this.addClass("vjs-paused"),this.trigger("pause")},e.handleTechEnded_=function(){this.addClass("vjs-ended"),this.removeClass("vjs-waiting"),this.options_.loop?(this.currentTime(0),this.play()):this.paused()||this.pause(),this.trigger("ended")},e.handleTechDurationChange_=function(){this.duration(this.techGet_("duration"))},e.handleTechClick_=function(e){this.controls_&&(this.paused()?It(this.play()):this.pause())},e.handleTechDoubleClick_=function(t){this.controls_&&(Array.prototype.some.call(this.$$(".vjs-control-bar, .vjs-modal-dialog"),function(e){return e.contains(t.target)})||void 0!==this.options_&&void 0!==this.options_.userActions&&void 0!==this.options_.userActions.doubleClick&&!1===this.options_.userActions.doubleClick||(void 0!==this.options_&&void 0!==this.options_.userActions&&"function"==typeof this.options_.userActions.doubleClick?this.options_.userActions.doubleClick.call(this,t):this.isFullscreen()?this.exitFullscreen():this.requestFullscreen()))},e.handleTechTap_=function(){this.userActive(!this.userActive())},e.handleTechTouchStart_=function(){this.userWasActive=this.userActive()},e.handleTechTouchMove_=function(){this.userWasActive&&this.reportUserActivity()},e.handleTechTouchEnd_=function(e){e.cancelable&&e.preventDefault()},e.handleStageClick_=function(){this.reportUserActivity()},e.toggleFullscreenClass_=function(){this.isFullscreen()?this.addClass("vjs-fullscreen"):this.removeClass("vjs-fullscreen")},e.documentFullscreenChange_=function(e){var t=e.target.player;t&&t!==this||(e=this.el(),!(t=d[this.fsApi_.fullscreenElement]===e)&&e.matches?t=e.matches(":"+this.fsApi_.fullscreen):!t&&e.msMatchesSelector&&(t=e.msMatchesSelector(":"+this.fsApi_.fullscreen)),this.isFullscreen(t))},e.handleTechFullscreenChange_=function(e,t){t&&(t.nativeIOSFullscreen&&this.toggleClass("vjs-ios-native-fs"),this.isFullscreen(t.isFullscreen))},e.handleTechFullscreenError_=function(e,t){this.trigger("fullscreenerror",t)},e.togglePictureInPictureClass_=function(){this.isInPictureInPicture()?this.addClass("vjs-picture-in-picture"):this.removeClass("vjs-picture-in-picture")},e.handleTechEnterPictureInPicture_=function(e){this.isInPictureInPicture(!0)},e.handleTechLeavePictureInPicture_=function(e){this.isInPictureInPicture(!1)},e.handleTechError_=function(){var e=this.tech_.error();this.error(e)},e.handleTechTextData_=function(){this.trigger("textdata",1<arguments.length?arguments[1]:null)},e.getCache=function(){return this.cache_},e.resetCache_=function(){this.cache_={currentTime:0,initTime:0,inactivityTimeout:this.options_.inactivityTimeout,duration:NaN,lastVolume:1,lastPlaybackRate:this.defaultPlaybackRate(),media:null,src:"",source:{},sources:[],playbackRates:[],volume:1}},e.techCall_=function(n,r){this.ready(function(){if(n in Xi)return e=this.middleware_,t=this.tech_,i=r,t[t=n](e.reduce(Yi(t),i));if(n in Ki)return zi(this.middleware_,this.tech_,n,r);var e,t,i;try{this.tech_&&this.tech_[n](r)}catch(e){throw y(e),e}},!0)},e.techGet_=function(t){if(this.tech_&&this.tech_.isReady_){if(t in Gi)return e=this.middleware_,i=this.tech_,n=t,e.reduceRight(Yi(n),i[n]());if(t in Ki)return zi(this.middleware_,this.tech_,t);var e,i,n;try{return this.tech_[t]()}catch(e){if(void 0===this.tech_[t])throw y("Video.js: "+t+" method not defined for "+this.techName_+" playback technology.",e),e;if("TypeError"===e.name)throw y("Video.js: "+t+" unavailable on "+this.techName_+" playback technology element.",e),this.tech_.isReady_=!1,e;throw y(e),e}}},e.play=function(){var t=this,e=this.options_.Promise||_.Promise;return e?new e(function(e){t.play_(e)}):this.play_()},e.play_=function(e){var t=this;this.playCallbacks_.push(e=void 0===e?It:e);e=Boolean(!this.changingSrc_&&(this.src()||this.currentSrc()));if(this.waitToPlay_&&(this.off(["ready","loadstart"],this.waitToPlay_),this.waitToPlay_=null),!this.isReady_||!e)return this.waitToPlay_=function(e){t.play_()},this.one(["ready","loadstart"],this.waitToPlay_),void(e||!X&&!G||this.load());e=this.techGet_("play");null===e?this.runPlayTerminatedQueue_():this.runPlayCallbacks_(e)},e.runPlayTerminatedQueue_=function(){var e=this.playTerminatedQueue_.slice(0);this.playTerminatedQueue_=[],e.forEach(function(e){e()})},e.runPlayCallbacks_=function(t){var e=this.playCallbacks_.slice(0);this.playCallbacks_=[],this.playTerminatedQueue_=[],e.forEach(function(e){e(t)})},e.pause=function(){this.techCall_("pause")},e.paused=function(){return!1!==this.techGet_("paused")},e.played=function(){return this.techGet_("played")||Tt(0,0)},e.scrubbing=function(e){if("undefined"==typeof e)return this.scrubbing_;this.scrubbing_=!!e,this.techCall_("setScrubbing",this.scrubbing_),e?this.addClass("vjs-scrubbing"):this.removeClass("vjs-scrubbing")},e.currentTime=function(e){return"undefined"!=typeof e?(e<0&&(e=0),this.isReady_&&!this.changingSrc_&&this.tech_&&this.tech_.isReady_?(this.techCall_("setCurrentTime",e),void(this.cache_.initTime=0)):(this.cache_.initTime=e,this.off("canplay",this.boundApplyInitTime_),void this.one("canplay",this.boundApplyInitTime_))):(this.cache_.currentTime=this.techGet_("currentTime")||0,this.cache_.currentTime)},e.applyInitTime_=function(){this.currentTime(this.cache_.initTime)},e.duration=function(e){if(void 0===e)return void 0!==this.cache_.duration?this.cache_.duration:NaN;(e=(e=parseFloat(e))<0?1/0:e)!==this.cache_.duration&&((this.cache_.duration=e)===1/0?this.addClass("vjs-live"):this.removeClass("vjs-live"),isNaN(e)||this.trigger("durationchange"))},e.remainingTime=function(){return this.duration()-this.currentTime()},e.remainingTimeDisplay=function(){return Math.floor(this.duration())-Math.floor(this.currentTime())},e.buffered=function(){var e;return e=!(e=this.techGet_("buffered"))||!e.length?Tt(0,0):e},e.bufferedPercent=function(){return St(this.buffered(),this.duration())},e.bufferedEnd=function(){var e=this.buffered(),t=this.duration(),e=e.end(e.length-1);return e=t<e?t:e},e.volume=function(e){var t;return void 0!==e?(t=Math.max(0,Math.min(1,parseFloat(e))),this.cache_.volume=t,this.techCall_("setVolume",t),void(0<t&&this.lastVolume_(t))):(t=parseFloat(this.techGet_("volume")),isNaN(t)?1:t)},e.muted=function(e){if(void 0===e)return this.techGet_("muted")||!1;this.techCall_("setMuted",e)},e.defaultMuted=function(e){return void 0!==e?this.techCall_("setDefaultMuted",e):this.techGet_("defaultMuted")||!1},e.lastVolume_=function(e){if(void 0===e||0===e)return this.cache_.lastVolume;this.cache_.lastVolume=e},e.supportsFullScreen=function(){return this.techGet_("supportsFullScreen")||!1},e.isFullscreen=function(e){if(void 0===e)return this.isFullscreen_;var t=this.isFullscreen_;this.isFullscreen_=Boolean(e),this.isFullscreen_!==t&&this.fsApi_.prefixed&&this.trigger("fullscreenchange"),this.toggleFullscreenClass_()},e.requestFullscreen=function(s){var e=this.options_.Promise||_.Promise;if(e){var o=this;return new e(function(e,i){function n(){o.off("fullscreenerror",r),o.off("fullscreenchange",t)}function t(){n(),e()}function r(e,t){n(),i(t)}o.one("fullscreenchange",t),o.one("fullscreenerror",r);var a=o.requestFullscreenHelper_(s);a&&(a.then(n,n),a.then(e,i))})}return this.requestFullscreenHelper_()},e.requestFullscreenHelper_=function(e){var t=this;if(this.fsApi_.prefixed||(i=this.options_.fullscreen&&this.options_.fullscreen.options||{},void 0!==e&&(i=e)),this.fsApi_.requestFullscreen){var i=this.el_[this.fsApi_.requestFullscreen](i);return i&&i.then(function(){return t.isFullscreen(!0)},function(){return t.isFullscreen(!1)}),i}this.tech_.supportsFullScreen()&&!0==!this.options_.preferFullWindow?this.techCall_("enterFullScreen"):this.enterFullWindow()},e.exitFullscreen=function(){var e=this.options_.Promise||_.Promise;if(e){var s=this;return new e(function(e,i){function n(){s.off("fullscreenerror",r),s.off("fullscreenchange",t)}function t(){n(),e()}function r(e,t){n(),i(t)}s.one("fullscreenchange",t),s.one("fullscreenerror",r);var a=s.exitFullscreenHelper_();a&&(a.then(n,n),a.then(e,i))})}return this.exitFullscreenHelper_()},e.exitFullscreenHelper_=function(){var e=this;if(this.fsApi_.requestFullscreen){var t=d[this.fsApi_.exitFullscreen]();return t&&It(t.then(function(){return e.isFullscreen(!1)})),t}this.tech_.supportsFullScreen()&&!0==!this.options_.preferFullWindow?this.techCall_("exitFullScreen"):this.exitFullWindow()},e.enterFullWindow=function(){this.isFullscreen(!0),this.isFullWindow=!0,this.docOrigOverflow=d.documentElement.style.overflow,qe(d,"keydown",this.boundFullWindowOnEscKey_),d.documentElement.style.overflow="hidden",ae(d.body,"vjs-full-window"),this.trigger("enterFullWindow")},e.fullWindowOnEscKey=function(e){Lt.isEventKey(e,"Esc")&&!0===this.isFullscreen()&&(this.isFullWindow?this.exitFullWindow():this.exitFullscreen())},e.exitFullWindow=function(){this.isFullscreen(!1),this.isFullWindow=!1,Ve(d,"keydown",this.boundFullWindowOnEscKey_),d.documentElement.style.overflow=this.docOrigOverflow,se(d.body,"vjs-full-window"),this.trigger("exitFullWindow")},e.disablePictureInPicture=function(e){if(void 0===e)return this.techGet_("disablePictureInPicture");this.techCall_("setDisablePictureInPicture",e),this.options_.disablePictureInPicture=e,this.trigger("disablepictureinpicturechanged")},e.isInPictureInPicture=function(e){return void 0!==e?(this.isInPictureInPicture_=!!e,void this.togglePictureInPictureClass_()):!!this.isInPictureInPicture_},e.requestPictureInPicture=function(){if("pictureInPictureEnabled"in d&&!1===this.disablePictureInPicture())return this.techGet_("requestPictureInPicture")},e.exitPictureInPicture=function(){if("pictureInPictureEnabled"in d)return d.exitPictureInPicture()},e.handleKeyDown=function(e){var t=this.options_.userActions;t&&t.hotkeys&&(function(e){var t=e.tagName.toLowerCase();if(e.isContentEditable)return!0;if("input"===t)return-1===["button","checkbox","hidden","radio","reset","submit"].indexOf(e.type);return-1!==["textarea"].indexOf(t)}(this.el_.ownerDocument.activeElement)||("function"==typeof t.hotkeys?t.hotkeys.call(this,e):this.handleHotkeys(e)))},e.handleHotkeys=function(e){var t=this.options_.userActions?this.options_.userActions.hotkeys:{},i=t.fullscreenKey,n=t.muteKey,n=void 0===n?function(e){return Lt.isEventKey(e,"m")}:n,t=t.playPauseKey,t=void 0===t?function(e){return Lt.isEventKey(e,"k")||Lt.isEventKey(e,"Space")}:t;(void 0===i?function(e){return Lt.isEventKey(e,"f")}:i).call(this,e)?(e.preventDefault(),e.stopPropagation(),i=gt.getComponent("FullscreenToggle"),!1!==d[this.fsApi_.fullscreenEnabled]&&i.prototype.handleClick.call(this,e)):n.call(this,e)?(e.preventDefault(),e.stopPropagation(),gt.getComponent("MuteToggle").prototype.handleClick.call(this,e)):t.call(this,e)&&(e.preventDefault(),e.stopPropagation(),gt.getComponent("PlayToggle").prototype.handleClick.call(this,e))},e.canPlayType=function(e){for(var t,i=0,n=this.options_.techOrder;i<n.length;i++){var r=n[i],a=ji.getTech(r);if(a=a||gt.getComponent(r)){if(a.isSupported()&&(t=a.canPlayType(e)))return t}else y.error('The "'+r+'" tech is undefined. Skipped browser support check for that tech.')}return""},e.selectSource=function(e){function t(e,i,n){var r;return e.some(function(t){return i.some(function(e){if(r=n(t,e))return!0})}),r}var i,n=this,r=this.options_.techOrder.map(function(e){return[e,ji.getTech(e)]}).filter(function(e){var t=e[0],e=e[1];return e?e.isSupported():(y.error('The "'+t+'" tech is undefined. Skipped browser support check for that tech.'),!1)}),a=function(e,t){var i=e[0];if(e[1].canPlaySource(t,n.options_[i.toLowerCase()]))return{source:t,tech:i}},a=this.options_.sourceOrder?t(e,r,(i=a,function(e,t){return i(t,e)})):t(r,e,a);return a||!1},e.handleSrc_=function(e,n){var r=this;if("undefined"==typeof e)return this.cache_.src||"";this.resetRetryOnError_&&this.resetRetryOnError_();var t,i,a=Ji(e);a.length?(this.changingSrc_=!0,n||(this.cache_.sources=a),this.updateSourceCaches_(a[0]),Wi(this,a[0],function(e,t){var i;return r.middleware_=t,n||(r.cache_.sources=a),r.updateSourceCaches_(e),r.src_(e)?1<a.length?r.handleSrc_(a.slice(1)):(r.changingSrc_=!1,r.setTimeout(function(){this.error({code:4,message:this.localize(this.options_.notSupportedMessage)})},0),void r.triggerReady()):(t=t,i=r.tech_,void t.forEach(function(e){return e.setTech&&e.setTech(i)}))}),this.options_.retryOnError&&1<a.length&&(i=function(){r.off("error",t)},this.one("error",t=function(){r.error(null),r.handleSrc_(a.slice(1),!0)}),this.one("playing",i),this.resetRetryOnError_=function(){r.off("error",t),r.off("playing",i)})):this.setTimeout(function(){this.error({code:4,message:this.localize(this.options_.notSupportedMessage)})},0)},e.src=function(e){return this.handleSrc_(e,!1)},e.src_=function(e){var t,i,n=this,r=this.selectSource([e]);return!r||(t=r.tech,i=this.techName_,ht(t)!==ht(i)?(this.changingSrc_=!0,this.loadTech_(r.tech,r.source),this.tech_.ready(function(){n.changingSrc_=!1})):this.ready(function(){this.tech_.constructor.prototype.hasOwnProperty("setSource")?this.techCall_("setSource",e):this.techCall_("src",e.src),this.changingSrc_=!1},!0),!1)},e.load=function(){this.techCall_("load")},e.reset=function(){var e=this,t=this.options_.Promise||_.Promise;this.paused()||!t?this.doReset_():It(this.play().then(function(){return e.doReset_()}))},e.doReset_=function(){this.tech_&&this.tech_.clearTracks("text"),this.resetCache_(),this.poster(""),this.loadTech_(this.options_.techOrder[0],null),this.techCall_("reset"),this.resetControlBarUI_(),st(this)&&this.trigger("playerreset")},e.resetControlBarUI_=function(){this.resetProgressBar_(),this.resetPlaybackRate_(),this.resetVolumeBar_()},e.resetProgressBar_=function(){this.currentTime(0);var e=this.controlBar,t=e.durationDisplay,e=e.remainingTimeDisplay;t&&t.updateContent(),e&&e.updateContent()},e.resetPlaybackRate_=function(){this.playbackRate(this.defaultPlaybackRate()),this.handleTechRateChange_()},e.resetVolumeBar_=function(){this.volume(1),this.trigger("volumechange")},e.currentSources=function(){var e=this.currentSource(),t=[];return 0!==Object.keys(e).length&&t.push(e),this.cache_.sources||t},e.currentSource=function(){return this.cache_.source||{}},e.currentSrc=function(){return this.currentSource()&&this.currentSource().src||""},e.currentType=function(){return this.currentSource()&&this.currentSource().type||""},e.preload=function(e){return void 0!==e?(this.techCall_("setPreload",e),void(this.options_.preload=e)):this.techGet_("preload")},e.autoplay=function(e){if(void 0===e)return this.options_.autoplay||!1;var t;"string"==typeof e&&/(any|play|muted)/.test(e)||!0===e&&this.options_.normalizeAutoplay?(this.options_.autoplay=e,this.manualAutoplay_("string"==typeof e?e:"play"),t=!1):this.options_.autoplay=!!e,t="undefined"==typeof t?this.options_.autoplay:t,this.tech_&&this.techCall_("setAutoplay",t)},e.playsinline=function(e){return void 0!==e?(this.techCall_("setPlaysinline",e),this.options_.playsinline=e,this):this.techGet_("playsinline")},e.loop=function(e){return void 0!==e?(this.techCall_("setLoop",e),void(this.options_.loop=e)):this.techGet_("loop")},e.poster=function(e){if(void 0===e)return this.poster_;(e=e||"")!==this.poster_&&(this.poster_=e,this.techCall_("setPoster",e),this.isPosterFromTech_=!1,this.trigger("posterchange"))},e.handleTechPosterChange_=function(){var e;this.poster_&&!this.options_.techCanOverridePoster||!this.tech_||!this.tech_.poster||(e=this.tech_.poster()||"")!==this.poster_&&(this.poster_=e,this.isPosterFromTech_=!0,this.trigger("posterchange"))},e.controls=function(e){if(void 0===e)return!!this.controls_;this.controls_!==(e=!!e)&&(this.controls_=e,this.usingNativeControls()&&this.techCall_("setControls",e),this.controls_?(this.removeClass("vjs-controls-disabled"),this.addClass("vjs-controls-enabled"),this.trigger("controlsenabled"),this.usingNativeControls()||this.addTechControlsListeners_()):(this.removeClass("vjs-controls-enabled"),this.addClass("vjs-controls-disabled"),this.trigger("controlsdisabled"),this.usingNativeControls()||this.removeTechControlsListeners_()))},e.usingNativeControls=function(e){if(void 0===e)return!!this.usingNativeControls_;this.usingNativeControls_!==(e=!!e)&&(this.usingNativeControls_=e,this.usingNativeControls_?(this.addClass("vjs-using-native-controls"),this.trigger("usingnativecontrols")):(this.removeClass("vjs-using-native-controls"),this.trigger("usingcustomcontrols")))},e.error=function(t){var i=this;if(void 0===t)return this.error_||null;if(a("beforeerror").forEach(function(e){e=e(i,t);C(e)&&!Array.isArray(e)||"string"==typeof e||"number"==typeof e||null===e?t=e:i.log.error("please return a value that MediaError expects in beforeerror hooks")}),this.options_.suppressNotSupportedError&&t&&4===t.code){var e=function(){this.error(t)};return this.options_.suppressNotSupportedError=!1,this.any(["click","touchstart"],e),void this.one("loadstart",function(){this.off(["click","touchstart"],e)})}if(null===t)return this.error_=t,this.removeClass("vjs-error"),void(this.errorDisplay&&this.errorDisplay.close());this.error_=new Et(t),this.addClass("vjs-error"),y.error("(CODE:"+this.error_.code+" "+Et.errorTypes[this.error_.code]+")",this.error_.message,this.error_),this.trigger("error"),a("error").forEach(function(e){return e(i,i.error_)})},e.reportUserActivity=function(e){this.userActivity_=!0},e.userActive=function(e){if(void 0===e)return this.userActive_;if((e=!!e)!==this.userActive_){if(this.userActive_=e,this.userActive_)return this.userActivity_=!0,this.removeClass("vjs-user-inactive"),this.addClass("vjs-user-active"),void this.trigger("useractive");this.tech_&&this.tech_.one("mousemove",function(e){e.stopPropagation(),e.preventDefault()}),this.userActivity_=!1,this.removeClass("vjs-user-active"),this.addClass("vjs-user-inactive"),this.trigger("userinactive")}},e.listenForUserActivity_=function(){var t,i,n,r=Xe(this,this.reportUserActivity),e=function(e){r(),this.clearInterval(t)};this.on("mousedown",function(){r(),this.clearInterval(t),t=this.setInterval(r,250)}),this.on("mousemove",function(e){e.screenX===i&&e.screenY===n||(i=e.screenX,n=e.screenY,r())}),this.on("mouseup",e),this.on("mouseleave",e);var a,e=this.getChild("controlBar");!e||G||O||(e.on("mouseenter",function(e){0!==this.player().options_.inactivityTimeout&&(this.player().cache_.inactivityTimeout=this.player().options_.inactivityTimeout),this.player().options_.inactivityTimeout=0}),e.on("mouseleave",function(e){this.player().options_.inactivityTimeout=this.player().cache_.inactivityTimeout})),this.on("keydown",r),this.on("keyup",r),this.setInterval(function(){var e;this.userActivity_&&(this.userActivity_=!1,this.userActive(!0),this.clearTimeout(a),(e=this.options_.inactivityTimeout)<=0||(a=this.setTimeout(function(){this.userActivity_||this.userActive(!1)},e)))},250)},e.playbackRate=function(e){if(void 0===e)return this.tech_&&this.tech_.featuresPlaybackRate?this.cache_.lastPlaybackRate||this.techGet_("playbackRate"):1;this.techCall_("setPlaybackRate",e)},e.defaultPlaybackRate=function(e){return void 0!==e?this.techCall_("setDefaultPlaybackRate",e):this.tech_&&this.tech_.featuresPlaybackRate?this.techGet_("defaultPlaybackRate"):1},e.isAudio=function(e){if(void 0===e)return!!this.isAudio_;this.isAudio_=!!e},e.addTextTrack=function(e,t,i){if(this.tech_)return this.tech_.addTextTrack(e,t,i)},e.addRemoteTextTrack=function(e,t){if(this.tech_)return this.tech_.addRemoteTextTrack(e,t)},e.removeRemoteTextTrack=function(e){var t=(t=(e=void 0===e?{}:e).track)||e;if(this.tech_)return this.tech_.removeRemoteTextTrack(t)},e.getVideoPlaybackQuality=function(){return this.techGet_("getVideoPlaybackQuality")},e.videoWidth=function(){return this.tech_&&this.tech_.videoWidth&&this.tech_.videoWidth()||0},e.videoHeight=function(){return this.tech_&&this.tech_.videoHeight&&this.tech_.videoHeight()||0},e.language=function(e){if(void 0===e)return this.language_;this.language_!==String(e).toLowerCase()&&(this.language_=String(e).toLowerCase(),st(this)&&this.trigger("languagechange"))},e.languages=function(){return pt(o.prototype.options_.languages,this.languages_)},e.toJSON=function(){var e=pt(this.options_),t=e.tracks;e.tracks=[];for(var i=0;i<t.length;i++){var n=t[i];(n=pt(n)).player=void 0,e.tracks[i]=n}return e},e.createModal=function(e,t){var i=this;(t=t||{}).content=e||"";var n=new Ot(this,t);return this.addChild(n),n.on("dispose",function(){i.removeChild(n)}),n.open(),n},e.updateCurrentBreakpoint_=function(){if(this.responsive())for(var e=this.currentBreakpoint(),t=this.currentWidth(),i=0;i<Un.length;i++){var n=Un[i];if(t<=this.breakpoints_[n]){if(e===n)return;e&&this.removeClass(Bn[e]),this.addClass(Bn[n]),this.breakpoint_=n;break}}},e.removeCurrentBreakpoint_=function(){var e=this.currentBreakpointClass();this.breakpoint_="",e&&this.removeClass(e)},e.breakpoints=function(e){return void 0===e||(this.breakpoint_="",this.breakpoints_=k({},Fn,e),this.updateCurrentBreakpoint_()),k(this.breakpoints_)},e.responsive=function(e){return void 0===e?this.responsive_:(e=Boolean(e))!==this.responsive_?((this.responsive_=e)?(this.on("playerresize",this.boundUpdateCurrentBreakpoint_),this.updateCurrentBreakpoint_()):(this.off("playerresize",this.boundUpdateCurrentBreakpoint_),this.removeCurrentBreakpoint_()),e):void 0},e.currentBreakpoint=function(){return this.breakpoint_},e.currentBreakpointClass=function(){return Bn[this.breakpoint_]||""},e.loadMedia=function(e,t){var i,n,r,a=this;e&&"object"==typeof e&&(this.reset(),this.cache_.media=pt(e),i=(r=this.cache_.media).artwork,n=r.poster,e=r.src,r=r.textTracks,!i&&n&&(this.cache_.media.artwork=[{src:n,type:$i(n)}]),e&&this.src(e),n&&this.poster(n),Array.isArray(r)&&r.forEach(function(e){return a.addRemoteTextTrack(e,!1)}),this.ready(t))},e.getMedia=function(){if(this.cache_.media)return pt(this.cache_.media);var e=this.poster(),t={src:this.currentSources(),textTracks:Array.prototype.map.call(this.remoteTextTracks(),function(e){return{kind:e.kind,label:e.label,language:e.language,src:e.src}})};return e&&(t.poster=e,t.artwork=[{src:t.poster,type:$i(t.poster)}]),t},o.getTagSettings=function(e){var t,i={sources:[],tracks:[]},n=le(e),r=n["data-setup"];if(re(e,"vjs-fill")&&(n.fill=!0),re(e,"vjs-fluid")&&(n.fluid=!0),null!==r&&(r=(t=Ct(r||"{}"))[0],t=t[1],r&&y.error(r),k(n,t)),k(i,n),e.hasChildNodes())for(var a=e.childNodes,s=0,o=a.length;s<o;s++){var u=a[s],l=u.nodeName.toLowerCase();"source"===l?i.sources.push(le(u)):"track"===l&&i.tracks.push(le(u))}return i},e.flexNotSupported_=function(){var e=d.createElement("i");return!("flexBasis"in e.style||"webkitFlexBasis"in e.style||"mozFlexBasis"in e.style||"msFlexBasis"in e.style||"msFlexOrder"in e.style)},e.debug=function(e){if(void 0===e)return this.debugEnabled_;e?(this.trigger("debugon"),this.previousLogLevel_=this.log.level,this.log.level("debug"),this.debugEnabled_=!0):(this.trigger("debugoff"),this.log.level(this.previousLogLevel_),this.previousLogLevel_=void 0,this.debugEnabled_=!1)},e.playbackRates=function(e){if(void 0===e)return this.cache_.playbackRates;Array.isArray(e)&&e.every(function(e){return"number"==typeof e})&&(this.cache_.playbackRates=e,this.trigger("playbackrateschange"))},o}(gt);li.names.forEach(function(e){var t=li[e];jn.prototype[t.getterName]=function(){return this.tech_?this.tech_[t.getterName]():(this[t.privateName]=this[t.privateName]||new t.ListClass,this[t.privateName])}}),jn.prototype.crossorigin=jn.prototype.crossOrigin,jn.players={};P=_.navigator;jn.prototype.options_={techOrder:ji.defaultTechOrder_,html5:{},inactivityTimeout:2e3,playbackRates:[],liveui:!1,children:["mediaLoader","posterImage","textTrackDisplay","loadingSpinner","bigPlayButton","liveTracker","controlBar","errorDisplay","textTrackSettings","resizeManager"],language:P&&(P.languages&&P.languages[0]||P.userLanguage||P.language)||"en",languages:{},notSupportedMessage:"No compatible source was found for this media.",normalizeAutoplay:!1,fullscreen:{options:{navigationUI:"hide"}},breakpoints:{},responsive:!1},["ended","seeking","seekable","networkState","readyState"].forEach(function(e){jn.prototype[e]=function(){return this.techGet_(e)}}),Mn.forEach(function(e){jn.prototype["handleTech"+ht(e)+"_"]=function(){return this.trigger(e)}}),gt.registerComponent("Player",jn);var Hn=t(function(i){function n(e,t){return i.exports=n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},n(e,t)}i.exports=n});function qn(e){return $n.hasOwnProperty(e)}function Vn(e){return qn(e)?$n[e]:void 0}function Wn(e,t,i){i=(i?"before":"")+"pluginsetup",e.trigger(i,t),e.trigger(i+":"+t.name,t)}function zn(t,i){function n(){Wn(this,{name:t,plugin:i,instance:null},!0);var e=i.apply(this,arguments);return Jn(this,t),Wn(this,{name:t,plugin:i,instance:e}),e}return Object.keys(i).forEach(function(e){n[e]=i[e]}),n}function Gn(r,a){return a.prototype.name=r,function(){Wn(this,{name:r,plugin:a,instance:null},!0);for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var n=Kn(a,[this].concat(t));return this[r]=function(){return n},Wn(this,n.getEventHash()),n}}var Xn=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}},Kn=t(function(n){function r(e,t,i){return Xn()?n.exports=r=Reflect.construct:n.exports=r=function(e,t,i){var n=[null];n.push.apply(n,t);n=new(Function.bind.apply(e,n));return i&&Hn(n,i.prototype),n},r.apply(null,arguments)}n.exports=r}),Yn="plugin",Qn="activePlugins_",$n={},Jn=function(e,t){e[Qn]=e[Qn]||{},e[Qn][t]=!0},Zn=function(){function i(e){if(this.constructor===i)throw new Error("Plugin must be sub-classed; not directly instantiated.");this.player=e,this.log||(this.log=this.player.log.createLogger(this.name)),ut(this),delete this.trigger,ct(this,this.constructor.defaultState),Jn(e,this.name),this.dispose=this.dispose.bind(this),e.on("dispose",this.dispose)}var e=i.prototype;return e.version=function(){return this.constructor.VERSION},e.getEventHash=function(e){return(e=void 0===e?{}:e).name=this.name,e.plugin=this.constructor,e.instance=this,e},e.trigger=function(e,t){return We(this.eventBusEl_,e,this.getEventHash(t=void 0===t?{}:t))},e.handleStateChanged=function(e){},e.dispose=function(){var e=this.name,t=this.player;this.trigger("dispose"),this.off(),t.off("dispose",this.dispose),t[Qn][e]=!1,this.player=this.state=null,t[e]=Gn(e,$n[e])},i.isBasic=function(e){e="string"==typeof e?Vn(e):e;return"function"==typeof e&&!i.prototype.isPrototypeOf(e.prototype)},i.registerPlugin=function(e,t){if("string"!=typeof e)throw new Error('Illegal plugin name, "'+e+'", must be a string, was '+typeof e+".");if(qn(e))y.warn('A plugin named "'+e+'" already exists. You may want to avoid re-registering plugins!');else if(jn.prototype.hasOwnProperty(e))throw new Error('Illegal plugin name, "'+e+'", cannot share a name with an existing player method!');if("function"!=typeof t)throw new Error('Illegal plugin for "'+e+'", must be a function, was '+typeof t+".");return $n[e]=t,e!==Yn&&(i.isBasic(t)?jn.prototype[e]=zn(e,t):jn.prototype[e]=Gn(e,t)),t},i.deregisterPlugin=function(e){if(e===Yn)throw new Error("Cannot de-register base plugin.");qn(e)&&(delete $n[e],delete jn.prototype[e])},i.getPlugins=function(e){var i;return(e=void 0===e?Object.keys($n):e).forEach(function(e){var t=Vn(e);t&&((i=i||{})[e]=t)}),i},i.getPluginVersion=function(e){e=Vn(e);return e&&e.VERSION||""},i}();Zn.getPlugin=Vn,Zn.BASE_PLUGIN_NAME=Yn,Zn.registerPlugin(Yn,Zn),jn.prototype.usingPlugin=function(e){return!!this[Qn]&&!0===this[Qn][e]},jn.prototype.hasPlugin=function(e){return!!qn(e)};var er=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&Hn(e,t)},tr=function(e){return 0===e.indexOf("#")?e.slice(1):e};function ir(e,t,i){if(r=ir.getPlayer(e))return t&&y.warn('Player "'+e+'" is already initialised. Options will not be applied.'),i&&r.ready(i),r;var n="string"==typeof e?Ce("#"+tr(e)):e;if(!J(n))throw new TypeError("The element or ID supplied is not valid. (videojs)");n.ownerDocument.defaultView&&n.ownerDocument.body.contains(n)||y.warn("The element supplied is not included in the DOM"),t=t||{},a("beforesetup").forEach(function(e){e=e(n,pt(t));C(e)&&!Array.isArray(e)?t=pt(t,e):y.error("please return an object in beforesetup hooks")});var r=new(gt.getComponent("Player"))(n,t,i);return a("setup").forEach(function(e){return e(r)}),r}ir.hooks_=n,ir.hooks=a,ir.hook=function(e,t){a(e,t)},ir.hookOnce=function(i,e){a(i,[].concat(e).map(function(t){return function e(){return r(i,e),t.apply(void 0,arguments)}}))},ir.removeHook=r,!0!==_.VIDEOJS_NO_DYNAMIC_STYLE&&$()&&((sr=Ce(".vjs-styles-defaults"))||(sr=De("vjs-styles-defaults"),(P=Ce("head"))&&P.insertBefore(sr,P.firstChild),Oe(sr,"\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n "))),Pe(1,ir),ir.VERSION=u,ir.options=jn.prototype.options_,ir.getPlayers=function(){return jn.players},ir.getPlayer=function(e){var t=jn.players;if("string"==typeof e){var i=tr(e),n=t[i];if(n)return n;i=Ce("#"+i)}else i=e;if(J(i)){e=i.player,i=i.playerId;if(e||t[i])return e||t[i]}},ir.getAllPlayers=function(){return Object.keys(jn.players).map(function(e){return jn.players[e]}).filter(Boolean)},ir.players=jn.players,ir.getComponent=gt.getComponent,ir.registerComponent=function(e,t){ji.isTech(t)&&y.warn("The "+e+" tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)"),gt.registerComponent.call(gt,e,t)},ir.getTech=ji.getTech,ir.registerTech=ji.registerTech,ir.use=function(e,t){Hi[e]=Hi[e]||[],Hi[e].push(t)},Object.defineProperty(ir,"middleware",{value:{},writeable:!1,enumerable:!0}),Object.defineProperty(ir.middleware,"TERMINATOR",{value:Vi,writeable:!1,enumerable:!0}),ir.browser=K,ir.TOUCH_ENABLED=V,ir.extend=function(e,t){var i,n=function(){e.apply(this,arguments)},r={};for(i in"object"==typeof(t=void 0===t?{}:t)?(t.constructor!==Object.prototype.constructor&&(n=t.constructor),r=t):"function"==typeof t&&(n=t),er(n,e),e&&(n.super_=e),r)r.hasOwnProperty(i)&&(n.prototype[i]=r[i]);return n},ir.mergeOptions=pt,ir.bind=Xe,ir.registerPlugin=Zn.registerPlugin,ir.deregisterPlugin=Zn.deregisterPlugin,ir.plugin=function(e,t){return y.warn("videojs.plugin() is deprecated; use videojs.registerPlugin() instead"),Zn.registerPlugin(e,t)},ir.getPlugins=Zn.getPlugins,ir.getPlugin=Zn.getPlugin,ir.getPluginVersion=Zn.getPluginVersion,ir.addLanguage=function(e,t){var i;return e=(""+e).toLowerCase(),ir.options.languages=pt(ir.options.languages,((i={})[e]=t,i)),ir.options.languages[e]},ir.log=y,ir.createLogger=v,ir.createTimeRange=ir.createTimeRanges=Tt,ir.formatTime=cn,ir.setFormatTime=function(e){ln=e},ir.resetFormatTime=function(){ln=un},ir.parseUrl=Bt,ir.isCrossOrigin=Ht,ir.EventTarget=Qe,ir.on=qe,ir.one=ze,ir.off=Ve,ir.trigger=We,ir.xhr=Jt,ir.TextTrack=ri,ir.AudioTrack=ai,ir.VideoTrack=si,["isEl","isTextNode","createEl","hasClass","addClass","removeClass","toggleClass","setAttributes","getAttributes","emptyEl","appendContent","insertContent"].forEach(function(e){ir[e]=function(){return y.warn("videojs."+e+"() is deprecated; use videojs.dom."+e+"() instead"),Ie[e].apply(null,arguments)}}),ir.computedStyle=I,ir.dom=Ie,ir.url=Kt,ir.defineLazyProperty=Pn,ir.addLanguage("en",{"Non-Fullscreen":"Exit Fullscreen"});function nr(e,t){if(/^[a-z]+:/i.test(t))return t;/^data:/.test(e)&&(e=_.location&&_.location.href||"");var i="function"==typeof _.URL,n=/^\/\//.test(e),r=!_.location&&!/\/\//i.test(e);if(i?e=new _.URL(e,_.location||ar):/\/\//i.test(e)||(e=rr.buildAbsoluteURL(_.location&&_.location.href||"",e)),i){i=new URL(t,e);return r?i.href.slice(ar.length):n?i.href.slice(i.protocol.length):i.href}return rr.buildAbsoluteURL(e,t)}var rr=t(function(e,t){var i,a,n,r,s;i=/^((?:[a-zA-Z0-9+\-.]+:)?)(\/\/[^\/?#]*)?((?:[^\/?#]*\/)*[^;?#]*)?(;[^?#]*)?(\?[^#]*)?(#[^]*)?$/,a=/^([^\/?#]*)([^]*)$/,n=/(?:\/|^)\.(?=\/)/g,r=/(?:\/|^)\.\.\/(?!\.\.\/)[^\/]*(?=\/)/g,s={buildAbsoluteURL:function(e,t,i){if(i=i||{},e=e.trim(),!(t=t.trim())){if(!i.alwaysNormalize)return e;var n=s.parseURL(e);if(!n)throw new Error("Error trying to parse base URL.");return n.path=s.normalizePath(n.path),s.buildURLFromParts(n)}n=s.parseURL(t);if(!n)throw new Error("Error trying to parse relative URL.");if(n.scheme)return i.alwaysNormalize?(n.path=s.normalizePath(n.path),s.buildURLFromParts(n)):t;t=s.parseURL(e);if(!t)throw new Error("Error trying to parse base URL.");!t.netLoc&&t.path&&"/"!==t.path[0]&&(r=a.exec(t.path),t.netLoc=r[1],t.path=r[2]),t.netLoc&&!t.path&&(t.path="/");var r,e={scheme:t.scheme,netLoc:n.netLoc,path:null,params:n.params,query:n.query,fragment:n.fragment};return n.netLoc||(e.netLoc=t.netLoc,"/"!==n.path[0]&&(n.path?(r=(r=t.path).substring(0,r.lastIndexOf("/")+1)+n.path,e.path=s.normalizePath(r)):(e.path=t.path,n.params||(e.params=t.params,n.query||(e.query=t.query))))),null===e.path&&(e.path=i.alwaysNormalize?s.normalizePath(n.path):n.path),s.buildURLFromParts(e)},parseURL:function(e){e=i.exec(e);return e?{scheme:e[1]||"",netLoc:e[2]||"",path:e[3]||"",params:e[4]||"",query:e[5]||"",fragment:e[6]||""}:null},normalizePath:function(e){for(e=e.split("").reverse().join("").replace(n,"");e.length!==(e=e.replace(r,"")).length;);return e.split("").reverse().join("")},buildURLFromParts:function(e){return e.scheme+e.netLoc+e.path+e.params+e.query+e.fragment}},e.exports=s}),ar="http://example.com",sr=function(){function e(){this.listeners={}}var t=e.prototype;return t.on=function(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)},t.off=function(e,t){if(!this.listeners[e])return!1;t=this.listeners[e].indexOf(t);return this.listeners[e]=this.listeners[e].slice(0),this.listeners[e].splice(t,1),-1<t},t.trigger=function(e){var t=this.listeners[e];if(t)if(2===arguments.length)for(var i=t.length,n=0;n<i;++n)t[n].call(this,arguments[1]);else for(var r=Array.prototype.slice.call(arguments,1),a=t.length,s=0;s<a;++s)t[s].apply(this,r)},t.dispose=function(){this.listeners={}},t.pipe=function(t){this.on("data",function(e){t.push(e)})},e}(),or=function(e){return _.atob?_.atob(e):Buffer.from(e,"base64").toString("binary")};function ur(e){for(var t=or(e),i=new Uint8Array(t.length),n=0;n<t.length;n++)i[n]=t.charCodeAt(n);return i}
+/*! @name m3u8-parser @version 4.7.0 @license Apache-2.0 */function lr(e){var t=/([0-9.]*)?@?([0-9.]*)?/.exec(e||""),e={};return t[1]&&(e.length=parseInt(t[1],10)),t[2]&&(e.offset=parseInt(t[2],10)),e}function cr(e){for(var t,i=e.split(new RegExp('(?:^|,)((?:[^=]*)=(?:"[^"]*"|[^,]*))')),n={},r=i.length;r--;)""!==i[r]&&((t=/([^=]*)=(.*)/.exec(i[r]).slice(1))[0]=t[0].replace(/^\s+|\s+$/g,""),t[1]=t[1].replace(/^\s+|\s+$/g,""),t[1]=t[1].replace(/^['"](.*)['"]$/g,"$1"),n[t[0]]=t[1]);return n}function dr(t){var i={};return Object.keys(t).forEach(function(e){i[e.toLowerCase().replace(/-(\w)/g,function(e){return e[1].toUpperCase()})]=t[e]}),i}function hr(e){var t,i,n,r,a=e.serverControl,s=e.targetDuration,o=e.partTargetDuration;a&&(t="#EXT-X-SERVER-CONTROL",i="holdBack",n="partHoldBack",r=s&&3*s,e=o&&2*o,s&&!a.hasOwnProperty(i)&&(a[i]=r,this.trigger("info",{message:t+" defaulting HOLD-BACK to targetDuration * 3 ("+r+")."})),r&&a[i]<r&&(this.trigger("warn",{message:t+" clamping HOLD-BACK ("+a[i]+") to targetDuration * 3 ("+r+")"}),a[i]=r),o&&!a.hasOwnProperty(n)&&(a[n]=3*o,this.trigger("info",{message:t+" defaulting PART-HOLD-BACK to partTargetDuration * 3 ("+a[n]+")."})),o&&a[n]<e&&(this.trigger("warn",{message:t+" clamping PART-HOLD-BACK ("+a[n]+") to partTargetDuration * 2 ("+e+")."}),a[n]=e))}function pr(e){return e&&e.replace(/avc1\.(\d+)\.(\d+)/i,function(e,t,i){return"avc1."+("00"+Number(t).toString(16)).slice(-2)+"00"+("00"+Number(i).toString(16)).slice(-2)})}function fr(e){var e=(e=void 0===e?"":e).split(","),a=[];return e.forEach(function(n){var r;n=n.trim(),Cr.forEach(function(e){var t,i=kr[e].exec(n.toLowerCase());!i||i.length<=1||(r=e,t=n.substring(0,i[1].length),i=n.replace(t,""),a.push({type:t,details:i,mediaType:e}))}),r||a.push({type:n,details:"",mediaType:"unknown"})}),a}function mr(e){return kr.audio.test((e=void 0===e?"":e).trim().toLowerCase())}function gr(e){if(e&&"string"==typeof e){var t=e.toLowerCase().split(",").map(function(e){return pr(e.trim())}),i="video";1===t.length&&mr(t[0])?i="audio":1===t.length&&(n=t[0],kr.text.test((n=void 0===n?"":n).trim().toLowerCase()))&&(i="application");var n="mp4";return t.every(function(e){return kr.mp4.test(e)})?n="mp4":t.every(function(e){return kr.webm.test(e)})?n="webm":t.every(function(e){return kr.ogg.test(e)})&&(n="ogg"),i+"/"+n+';codecs="'+e+'"'}}function yr(e){return void 0===e&&(e=""),_.MediaSource&&_.MediaSource.isTypeSupported&&_.MediaSource.isTypeSupported(gr(e))||!1}function vr(e){return(e=void 0===e?"":e).toLowerCase().split(",").every(function(e){e=e.trim();for(var t=0;t<wr.length;t++)if(kr["muxer"+wr[t]].test(e))return!0;return!1})}function _r(e){return xr.test(e)?"hls":Ar.test(e)?"dash":"application/vnd.videojs.vhs+json"===e?"vhs-json":null}var br=function(t){function e(){var e=t.call(this)||this;return e.buffer="",e}return vt(e,t),e.prototype.push=function(e){var t;for(this.buffer+=e,t=this.buffer.indexOf("\n");-1<t;t=this.buffer.indexOf("\n"))this.trigger("data",this.buffer.substring(0,t)),this.buffer=this.buffer.substring(t+1)},e}(sr),Tr=String.fromCharCode(9),Sr=function(t){function e(){var e=t.call(this)||this;return e.customParsers=[],e.tagMappers=[],e}vt(e,t);var i=e.prototype;return i.push=function(i){var r,a,s=this;0!==(i=i.trim()).length&&("#"===i[0]?this.tagMappers.reduce(function(e,t){t=t(i);return t===i?e:e.concat([t])},[i]).forEach(function(e){for(var t,i,n=0;n<s.customParsers.length;n++)if(s.customParsers[n].call(s,e))return;if(0===e.indexOf("#EXT"))if(e=e.replace("\r",""),r=/^#EXTM3U/.exec(e))s.trigger("data",{type:"tag",tagType:"m3u"});else{if(r=/^#EXTINF:?([0-9\.]*)?,?(.*)?$/.exec(e))return a={type:"tag",tagType:"inf"},r[1]&&(a.duration=parseFloat(r[1])),r[2]&&(a.title=r[2]),void s.trigger("data",a);if(r=/^#EXT-X-TARGETDURATION:?([0-9.]*)?/.exec(e))return a={type:"tag",tagType:"targetduration"},r[1]&&(a.duration=parseInt(r[1],10)),void s.trigger("data",a);if(r=/^#EXT-X-VERSION:?([0-9.]*)?/.exec(e))return a={type:"tag",tagType:"version"},r[1]&&(a.version=parseInt(r[1],10)),void s.trigger("data",a);if(r=/^#EXT-X-MEDIA-SEQUENCE:?(\-?[0-9.]*)?/.exec(e))return a={type:"tag",tagType:"media-sequence"},r[1]&&(a.number=parseInt(r[1],10)),void s.trigger("data",a);if(r=/^#EXT-X-DISCONTINUITY-SEQUENCE:?(\-?[0-9.]*)?/.exec(e))return a={type:"tag",tagType:"discontinuity-sequence"},r[1]&&(a.number=parseInt(r[1],10)),void s.trigger("data",a);if(r=/^#EXT-X-PLAYLIST-TYPE:?(.*)?$/.exec(e))return a={type:"tag",tagType:"playlist-type"},r[1]&&(a.playlistType=r[1]),void s.trigger("data",a);if(r=/^#EXT-X-BYTERANGE:?(.*)?$/.exec(e))return a=b(lr(r[1]),{type:"tag",tagType:"byterange"}),void s.trigger("data",a);if(r=/^#EXT-X-ALLOW-CACHE:?(YES|NO)?/.exec(e))return a={type:"tag",tagType:"allow-cache"},r[1]&&(a.allowed=!/NO/.test(r[1])),void s.trigger("data",a);if(r=/^#EXT-X-MAP:?(.*)$/.exec(e))return a={type:"tag",tagType:"map"},r[1]&&((t=cr(r[1])).URI&&(a.uri=t.URI),t.BYTERANGE&&(a.byterange=lr(t.BYTERANGE))),void s.trigger("data",a);if(r=/^#EXT-X-STREAM-INF:?(.*)$/.exec(e))return a={type:"tag",tagType:"stream-inf"},r[1]&&(a.attributes=cr(r[1]),a.attributes.RESOLUTION&&(i={},(t=a.attributes.RESOLUTION.split("x"))[0]&&(i.width=parseInt(t[0],10)),t[1]&&(i.height=parseInt(t[1],10)),a.attributes.RESOLUTION=i),a.attributes.BANDWIDTH&&(a.attributes.BANDWIDTH=parseInt(a.attributes.BANDWIDTH,10)),a.attributes["PROGRAM-ID"]&&(a.attributes["PROGRAM-ID"]=parseInt(a.attributes["PROGRAM-ID"],10))),void s.trigger("data",a);if(r=/^#EXT-X-MEDIA:?(.*)$/.exec(e))return a={type:"tag",tagType:"media"},r[1]&&(a.attributes=cr(r[1])),void s.trigger("data",a);if(r=/^#EXT-X-ENDLIST/.exec(e))s.trigger("data",{type:"tag",tagType:"endlist"});else{if(!(r=/^#EXT-X-DISCONTINUITY/.exec(e)))return(r=/^#EXT-X-PROGRAM-DATE-TIME:?(.*)$/.exec(e))?(a={type:"tag",tagType:"program-date-time"},r[1]&&(a.dateTimeString=r[1],a.dateTimeObject=new Date(r[1])),void s.trigger("data",a)):(r=/^#EXT-X-KEY:?(.*)$/.exec(e))?(a={type:"tag",tagType:"key"},r[1]&&(a.attributes=cr(r[1]),a.attributes.IV&&("0x"===a.attributes.IV.substring(0,2).toLowerCase()&&(a.attributes.IV=a.attributes.IV.substring(2)),a.attributes.IV=a.attributes.IV.match(/.{8}/g),a.attributes.IV[0]=parseInt(a.attributes.IV[0],16),a.attributes.IV[1]=parseInt(a.attributes.IV[1],16),a.attributes.IV[2]=parseInt(a.attributes.IV[2],16),a.attributes.IV[3]=parseInt(a.attributes.IV[3],16),a.attributes.IV=new Uint32Array(a.attributes.IV))),void s.trigger("data",a)):(r=/^#EXT-X-START:?(.*)$/.exec(e))?(a={type:"tag",tagType:"start"},r[1]&&(a.attributes=cr(r[1]),a.attributes["TIME-OFFSET"]=parseFloat(a.attributes["TIME-OFFSET"]),a.attributes.PRECISE=/YES/.test(a.attributes.PRECISE)),void s.trigger("data",a)):(r=/^#EXT-X-CUE-OUT-CONT:?(.*)?$/.exec(e))?(a={type:"tag",tagType:"cue-out-cont"},r[1]?a.data=r[1]:a.data="",void s.trigger("data",a)):(r=/^#EXT-X-CUE-OUT:?(.*)?$/.exec(e))?(a={type:"tag",tagType:"cue-out"},r[1]?a.data=r[1]:a.data="",void s.trigger("data",a)):(r=/^#EXT-X-CUE-IN:?(.*)?$/.exec(e))?(a={type:"tag",tagType:"cue-in"},r[1]?a.data=r[1]:a.data="",void s.trigger("data",a)):(r=/^#EXT-X-SKIP:(.*)$/.exec(e))&&r[1]?((a={type:"tag",tagType:"skip"}).attributes=cr(r[1]),a.attributes.hasOwnProperty("SKIPPED-SEGMENTS")&&(a.attributes["SKIPPED-SEGMENTS"]=parseInt(a.attributes["SKIPPED-SEGMENTS"],10)),a.attributes.hasOwnProperty("RECENTLY-REMOVED-DATERANGES")&&(a.attributes["RECENTLY-REMOVED-DATERANGES"]=a.attributes["RECENTLY-REMOVED-DATERANGES"].split(Tr)),void s.trigger("data",a)):(r=/^#EXT-X-PART:(.*)$/.exec(e))&&r[1]?((a={type:"tag",tagType:"part"}).attributes=cr(r[1]),["DURATION"].forEach(function(e){a.attributes.hasOwnProperty(e)&&(a.attributes[e]=parseFloat(a.attributes[e]))}),["INDEPENDENT","GAP"].forEach(function(e){a.attributes.hasOwnProperty(e)&&(a.attributes[e]=/YES/.test(a.attributes[e]))}),a.attributes.hasOwnProperty("BYTERANGE")&&(a.attributes.byterange=lr(a.attributes.BYTERANGE)),void s.trigger("data",a)):(r=/^#EXT-X-SERVER-CONTROL:(.*)$/.exec(e))&&r[1]?((a={type:"tag",tagType:"server-control"}).attributes=cr(r[1]),["CAN-SKIP-UNTIL","PART-HOLD-BACK","HOLD-BACK"].forEach(function(e){a.attributes.hasOwnProperty(e)&&(a.attributes[e]=parseFloat(a.attributes[e]))}),["CAN-SKIP-DATERANGES","CAN-BLOCK-RELOAD"].forEach(function(e){a.attributes.hasOwnProperty(e)&&(a.attributes[e]=/YES/.test(a.attributes[e]))}),void s.trigger("data",a)):(r=/^#EXT-X-PART-INF:(.*)$/.exec(e))&&r[1]?((a={type:"tag",tagType:"part-inf"}).attributes=cr(r[1]),["PART-TARGET"].forEach(function(e){a.attributes.hasOwnProperty(e)&&(a.attributes[e]=parseFloat(a.attributes[e]))}),void s.trigger("data",a)):(r=/^#EXT-X-PRELOAD-HINT:(.*)$/.exec(e))&&r[1]?((a={type:"tag",tagType:"preload-hint"}).attributes=cr(r[1]),["BYTERANGE-START","BYTERANGE-LENGTH"].forEach(function(e){var t;a.attributes.hasOwnProperty(e)&&(a.attributes[e]=parseInt(a.attributes[e],10),t="BYTERANGE-LENGTH"===e?"length":"offset",a.attributes.byterange=a.attributes.byterange||{},a.attributes.byterange[t]=a.attributes[e],delete a.attributes[e])}),void s.trigger("data",a)):(r=/^#EXT-X-RENDITION-REPORT:(.*)$/.exec(e))&&r[1]?((a={type:"tag",tagType:"rendition-report"}).attributes=cr(r[1]),["LAST-MSN","LAST-PART"].forEach(function(e){a.attributes.hasOwnProperty(e)&&(a.attributes[e]=parseInt(a.attributes[e],10))}),void s.trigger("data",a)):void s.trigger("data",{type:"tag",data:e.slice(4)});s.trigger("data",{type:"tag",tagType:"discontinuity"})}}else s.trigger("data",{type:"comment",text:e.slice(1)})}):this.trigger("data",{type:"uri",uri:i}))},i.addParser=function(e){var t=this,i=e.expression,n=e.customType,r=e.dataParser,a=e.segment;"function"!=typeof r&&(r=function(e){return e}),this.customParsers.push(function(e){if(i.exec(e))return t.trigger("data",{type:"custom",data:r(e),customType:n,segment:a}),!0})},i.addTagMapper=function(e){var t=e.expression,i=e.map;this.tagMappers.push(function(e){return t.test(e)?i(e):e})},e}(sr),Er=function(t){function e(){var e=t.call(this)||this;e.lineStream=new br,e.parseStream=new Sr,e.lineStream.pipe(e.parseStream);var n,r,a=yt(e),o=[],u={},l=!1,c={AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},d=0;e.manifest={allowCache:!0,discontinuityStarts:[],segments:[]};var h=0,p=0;return e.on("end",function(){u.uri||!u.parts&&!u.preloadHints||(!u.map&&n&&(u.map=n),!u.key&&r&&(u.key=r),u.timeline||"number"!=typeof d||(u.timeline=d),e.manifest.preloadSegment=u)}),e.parseStream.on("data",function(s){var t,i;({tag:function(){({version:function(){s.version&&(this.manifest.version=s.version)},"allow-cache":function(){this.manifest.allowCache=s.allowed,"allowed"in s||(this.trigger("info",{message:"defaulting allowCache to YES"}),this.manifest.allowCache=!0)},byterange:function(){var e={};"length"in s&&((u.byterange=e).length=s.length,"offset"in s||(s.offset=h)),"offset"in s&&((u.byterange=e).offset=s.offset),h=e.offset+e.length},endlist:function(){this.manifest.endList=!0},inf:function(){"mediaSequence"in this.manifest||(this.manifest.mediaSequence=0,this.trigger("info",{message:"defaulting media sequence to zero"})),"discontinuitySequence"in this.manifest||(this.manifest.discontinuitySequence=0,this.trigger("info",{message:"defaulting discontinuity sequence to zero"})),0<s.duration&&(u.duration=s.duration),0===s.duration&&(u.duration=.01,this.trigger("info",{message:"updating zero segment duration to a small value"})),this.manifest.segments=o},key:function(){if(s.attributes)if("NONE"!==s.attributes.METHOD)if(s.attributes.URI){if("com.apple.streamingkeydelivery"===s.attributes.KEYFORMAT)return this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.apple.fps.1_0"]={attributes:s.attributes});if("urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"===s.attributes.KEYFORMAT)return-1===["SAMPLE-AES","SAMPLE-AES-CTR","SAMPLE-AES-CENC"].indexOf(s.attributes.METHOD)?void this.trigger("warn",{message:"invalid key method provided for Widevine"}):("SAMPLE-AES-CENC"===s.attributes.METHOD&&this.trigger("warn",{message:"SAMPLE-AES-CENC is deprecated, please use SAMPLE-AES-CTR instead"}),"data:text/plain;base64,"!==s.attributes.URI.substring(0,23)?void this.trigger("warn",{message:"invalid key URI provided for Widevine"}):s.attributes.KEYID&&"0x"===s.attributes.KEYID.substring(0,2)?(this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.widevine.alpha"]={attributes:{schemeIdUri:s.attributes.KEYFORMAT,keyId:s.attributes.KEYID.substring(2)},pssh:ur(s.attributes.URI.split(",")[1])})):void this.trigger("warn",{message:"invalid key ID provided for Widevine"}));s.attributes.METHOD||this.trigger("warn",{message:"defaulting key method to AES-128"}),r={method:s.attributes.METHOD||"AES-128",uri:s.attributes.URI},"undefined"!=typeof s.attributes.IV&&(r.iv=s.attributes.IV)}else this.trigger("warn",{message:"ignoring key declaration without URI"});else r=null;else this.trigger("warn",{message:"ignoring key declaration without attribute list"})},"media-sequence":function(){isFinite(s.number)?this.manifest.mediaSequence=s.number:this.trigger("warn",{message:"ignoring invalid media sequence: "+s.number})},"discontinuity-sequence":function(){isFinite(s.number)?(this.manifest.discontinuitySequence=s.number,d=s.number):this.trigger("warn",{message:"ignoring invalid discontinuity sequence: "+s.number})},"playlist-type":function(){/VOD|EVENT/.test(s.playlistType)?this.manifest.playlistType=s.playlistType:this.trigger("warn",{message:"ignoring unknown playlist type: "+s.playlist})},map:function(){n={},s.uri&&(n.uri=s.uri),s.byterange&&(n.byterange=s.byterange),r&&(n.key=r)},"stream-inf":function(){this.manifest.playlists=o,this.manifest.mediaGroups=this.manifest.mediaGroups||c,s.attributes?(u.attributes||(u.attributes={}),b(u.attributes,s.attributes)):this.trigger("warn",{message:"ignoring empty stream-inf attributes"})},media:function(){var e;this.manifest.mediaGroups=this.manifest.mediaGroups||c,s.attributes&&s.attributes.TYPE&&s.attributes["GROUP-ID"]&&s.attributes.NAME?((e=this.manifest.mediaGroups[s.attributes.TYPE])[s.attributes["GROUP-ID"]]=e[s.attributes["GROUP-ID"]]||{},t=e[s.attributes["GROUP-ID"]],(i={default:/yes/i.test(s.attributes.DEFAULT)}).default?i.autoselect=!0:i.autoselect=/yes/i.test(s.attributes.AUTOSELECT),s.attributes.LANGUAGE&&(i.language=s.attributes.LANGUAGE),s.attributes.URI&&(i.uri=s.attributes.URI),s.attributes["INSTREAM-ID"]&&(i.instreamId=s.attributes["INSTREAM-ID"]),s.attributes.CHARACTERISTICS&&(i.characteristics=s.attributes.CHARACTERISTICS),s.attributes.FORCED&&(i.forced=/yes/i.test(s.attributes.FORCED)),t[s.attributes.NAME]=i):this.trigger("warn",{message:"ignoring incomplete or missing media group"})},discontinuity:function(){d+=1,u.discontinuity=!0,this.manifest.discontinuityStarts.push(o.length)},"program-date-time":function(){"undefined"==typeof this.manifest.dateTimeString&&(this.manifest.dateTimeString=s.dateTimeString,this.manifest.dateTimeObject=s.dateTimeObject),u.dateTimeString=s.dateTimeString,u.dateTimeObject=s.dateTimeObject},targetduration:function(){!isFinite(s.duration)||s.duration<0?this.trigger("warn",{message:"ignoring invalid target duration: "+s.duration}):(this.manifest.targetDuration=s.duration,hr.call(this,this.manifest))},start:function(){s.attributes&&!isNaN(s.attributes["TIME-OFFSET"])?this.manifest.start={timeOffset:s.attributes["TIME-OFFSET"],precise:s.attributes.PRECISE}:this.trigger("warn",{message:"ignoring start declaration without appropriate attribute list"})},"cue-out":function(){u.cueOut=s.data},"cue-out-cont":function(){u.cueOutCont=s.data},"cue-in":function(){u.cueIn=s.data},skip:function(){this.manifest.skip=dr(s.attributes),this.warnOnMissingAttributes_("#EXT-X-SKIP",s.attributes,["SKIPPED-SEGMENTS"])},part:function(){var i=this;l=!0;var e=this.manifest.segments.length,t=dr(s.attributes);u.parts=u.parts||[],u.parts.push(t),t.byterange&&(t.byterange.hasOwnProperty("offset")||(t.byterange.offset=p),p=t.byterange.offset+t.byterange.length);var n=u.parts.length-1;this.warnOnMissingAttributes_("#EXT-X-PART #"+n+" for segment #"+e,s.attributes,["URI","DURATION"]),this.manifest.renditionReports&&this.manifest.renditionReports.forEach(function(e,t){e.hasOwnProperty("lastPart")||i.trigger("warn",{message:"#EXT-X-RENDITION-REPORT #"+t+" lacks required attribute(s): LAST-PART"})})},"server-control":function(){var e=this.manifest.serverControl=dr(s.attributes);e.hasOwnProperty("canBlockReload")||(e.canBlockReload=!1,this.trigger("info",{message:"#EXT-X-SERVER-CONTROL defaulting CAN-BLOCK-RELOAD to false"})),hr.call(this,this.manifest),e.canSkipDateranges&&!e.hasOwnProperty("canSkipUntil")&&this.trigger("warn",{message:"#EXT-X-SERVER-CONTROL lacks required attribute CAN-SKIP-UNTIL which is required when CAN-SKIP-DATERANGES is set"})},"preload-hint":function(){var e=this.manifest.segments.length,t=dr(s.attributes),i=t.type&&"PART"===t.type;u.preloadHints=u.preloadHints||[],u.preloadHints.push(t),t.byterange&&(t.byterange.hasOwnProperty("offset")||(t.byterange.offset=i?p:0,i&&(p=t.byterange.offset+t.byterange.length)));var n=u.preloadHints.length-1;if(this.warnOnMissingAttributes_("#EXT-X-PRELOAD-HINT #"+n+" for segment #"+e,s.attributes,["TYPE","URI"]),t.type)for(var r=0;r<u.preloadHints.length-1;r++){var a=u.preloadHints[r];a.type&&a.type===t.type&&this.trigger("warn",{message:"#EXT-X-PRELOAD-HINT #"+n+" for segment #"+e+" has the same TYPE "+t.type+" as preload hint #"+r})}},"rendition-report":function(){var e=dr(s.attributes);this.manifest.renditionReports=this.manifest.renditionReports||[],this.manifest.renditionReports.push(e);var t=this.manifest.renditionReports.length-1,e=["LAST-MSN","URI"];l&&e.push("LAST-PART"),this.warnOnMissingAttributes_("#EXT-X-RENDITION-REPORT #"+t,s.attributes,e)},"part-inf":function(){this.manifest.partInf=dr(s.attributes),this.warnOnMissingAttributes_("#EXT-X-PART-INF",s.attributes,["PART-TARGET"]),this.manifest.partInf.partTarget&&(this.manifest.partTargetDuration=this.manifest.partInf.partTarget),hr.call(this,this.manifest)}}[s.tagType]||function(){}).call(a)},uri:function(){u.uri=s.uri,o.push(u),!this.manifest.targetDuration||"duration"in u||(this.trigger("warn",{message:"defaulting segment duration to the target duration"}),u.duration=this.manifest.targetDuration),r&&(u.key=r),u.timeline=d,n&&(u.map=n),p=0,u={}},comment:function(){},custom:function(){s.segment?(u.custom=u.custom||{},u.custom[s.customType]=s.data):(this.manifest.custom=this.manifest.custom||{},this.manifest.custom[s.customType]=s.data)}})[s.type].call(a)}),e}vt(e,t);var i=e.prototype;return i.warnOnMissingAttributes_=function(e,t,i){var n=[];i.forEach(function(e){t.hasOwnProperty(e)||n.push(e)}),n.length&&this.trigger("warn",{message:e+" lacks required attribute(s): "+n.join(", ")})},i.push=function(e){this.lineStream.push(e)},i.end=function(){this.lineStream.push("\n"),this.trigger("end")},i.addParser=function(e){this.parseStream.addParser(e)},i.addTagMapper=function(e){this.parseStream.addTagMapper(e)},e}(sr),kr={mp4:/^(av0?1|avc0?[1234]|vp0?9|flac|opus|mp3|mp4a|mp4v|stpp.ttml.im1t)/,webm:/^(vp0?[89]|av0?1|opus|vorbis)/,ogg:/^(vp0?[89]|theora|flac|opus|vorbis)/,video:/^(av0?1|avc0?[1234]|vp0?[89]|hvc1|hev1|theora|mp4v)/,audio:/^(mp4a|flac|vorbis|opus|ac-[34]|ec-3|alac|mp3|speex|aac)/,text:/^(stpp.ttml.im1t)/,muxerVideo:/^(avc0?1)/,muxerAudio:/^(mp4a)/,muxerText:/a^/},Cr=["video","audio","text"],wr=["Video","Audio","Text"],Ir="mp4a.40.2",xr=/^(audio|video|application)\/(x-|vnd\.apple\.)?mpegurl/i,Ar=/^application\/dash\+xml/i;function Pr(e,t){return(t=void 0===t?Object:t)&&"function"==typeof t.freeze?t.freeze(e):e}var Lr=Pr({HTML:"text/html",isHTML:function(e){return e===Lr.HTML},XML_APPLICATION:"application/xml",XML_TEXT:"text/xml",XML_XHTML_APPLICATION:"application/xhtml+xml",XML_SVG_IMAGE:"image/svg+xml"}),Dr=Pr({HTML:"http://www.w3.org/1999/xhtml",isHTML:function(e){return e===Dr.HTML},SVG:"http://www.w3.org/2000/svg",XML:"http://www.w3.org/XML/1998/namespace",XMLNS:"http://www.w3.org/2000/xmlns/"}),Or={freeze:Pr,MIME_TYPE:Lr,NAMESPACE:Dr},Rr=t(function(e,t){var i=Or.freeze;t.XML_ENTITIES=i({amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}),t.HTML_ENTITIES=i({lt:"<",gt:">",amp:"&",quot:'"',apos:"'",Agrave:"À",Aacute:"Á",Acirc:"Â",Atilde:"Ã",Auml:"Ä",Aring:"Å",AElig:"Æ",Ccedil:"Ç",Egrave:"È",Eacute:"É",Ecirc:"Ê",Euml:"Ë",Igrave:"Ì",Iacute:"Í",Icirc:"Î",Iuml:"Ï",ETH:"Ð",Ntilde:"Ñ",Ograve:"Ò",Oacute:"Ó",Ocirc:"Ô",Otilde:"Õ",Ouml:"Ö",Oslash:"Ø",Ugrave:"Ù",Uacute:"Ú",Ucirc:"Û",Uuml:"Ü",Yacute:"Ý",THORN:"Þ",szlig:"ß",agrave:"à",aacute:"á",acirc:"â",atilde:"ã",auml:"ä",aring:"å",aelig:"æ",ccedil:"ç",egrave:"è",eacute:"é",ecirc:"ê",euml:"ë",igrave:"ì",iacute:"í",icirc:"î",iuml:"ï",eth:"ð",ntilde:"ñ",ograve:"ò",oacute:"ó",ocirc:"ô",otilde:"õ",ouml:"ö",oslash:"ø",ugrave:"ù",uacute:"ú",ucirc:"û",uuml:"ü",yacute:"ý",thorn:"þ",yuml:"ÿ",nbsp:" ",iexcl:"¡",cent:"¢",pound:"£",curren:"¤",yen:"¥",brvbar:"¦",sect:"§",uml:"¨",copy:"©",ordf:"ª",laquo:"«",not:"¬",shy:"",reg:"®",macr:"¯",deg:"°",plusmn:"±",sup2:"²",sup3:"³",acute:"´",micro:"µ",para:"¶",middot:"·",cedil:"¸",sup1:"¹",ordm:"º",raquo:"»",frac14:"¼",frac12:"½",frac34:"¾",iquest:"¿",times:"×",divide:"÷",forall:"∀",part:"∂",exist:"∃",empty:"∅",nabla:"∇",isin:"∈",notin:"∉",ni:"∋",prod:"∏",sum:"∑",minus:"−",lowast:"∗",radic:"√",prop:"∝",infin:"∞",ang:"∠",and:"∧",or:"∨",cap:"∩",cup:"∪",int:"∫",there4:"∴",sim:"∼",cong:"≅",asymp:"≈",ne:"≠",equiv:"≡",le:"≤",ge:"≥",sub:"⊂",sup:"⊃",nsub:"⊄",sube:"⊆",supe:"⊇",oplus:"⊕",otimes:"⊗",perp:"⊥",sdot:"⋅",Alpha:"Α",Beta:"Β",Gamma:"Γ",Delta:"Δ",Epsilon:"Ε",Zeta:"Ζ",Eta:"Η",Theta:"Θ",Iota:"Ι",Kappa:"Κ",Lambda:"Λ",Mu:"Μ",Nu:"Ν",Xi:"Ξ",Omicron:"Ο",Pi:"Π",Rho:"Ρ",Sigma:"Σ",Tau:"Τ",Upsilon:"Υ",Phi:"Φ",Chi:"Χ",Psi:"Ψ",Omega:"Ω",alpha:"α",beta:"β",gamma:"γ",delta:"δ",epsilon:"ε",zeta:"ζ",eta:"η",theta:"θ",iota:"ι",kappa:"κ",lambda:"λ",mu:"μ",nu:"ν",xi:"ξ",omicron:"ο",pi:"π",rho:"ρ",sigmaf:"ς",sigma:"σ",tau:"τ",upsilon:"υ",phi:"φ",chi:"χ",psi:"ψ",omega:"ω",thetasym:"ϑ",upsih:"ϒ",piv:"ϖ",OElig:"Œ",oelig:"œ",Scaron:"Š",scaron:"š",Yuml:"Ÿ",fnof:"ƒ",circ:"ˆ",tilde:"˜",ensp:" ",emsp:" ",thinsp:" ",zwnj:"",zwj:"",lrm:"",rlm:"",ndash:"–",mdash:"—",lsquo:"‘",rsquo:"’",sbquo:"‚",ldquo:"“",rdquo:"”",bdquo:"„",dagger:"†",Dagger:"‡",bull:"•",hellip:"…",permil:"‰",prime:"′",Prime:"″",lsaquo:"‹",rsaquo:"›",oline:"‾",euro:"€",trade:"™",larr:"←",uarr:"↑",rarr:"→",darr:"↓",harr:"↔",crarr:"↵",lceil:"⌈",rceil:"⌉",lfloor:"⌊",rfloor:"⌋",loz:"◊",spades:"♠",clubs:"♣",hearts:"♥",diams:"♦"}),t.entityMap=t.HTML_ENTITIES});Rr.XML_ENTITIES,Rr.HTML_ENTITIES,Rr.entityMap;var Mr=Or.NAMESPACE,K=/[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/,ai=new RegExp("[\\-\\.0-9"+K.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]"),Nr=new RegExp("^"+K.source+ai.source+"*(?::"+K.source+ai.source+"*)?$"),Ur=0,Br=1,Fr=2,jr=3,Hr=4,qr=5,Vr=6,Wr=7;function zr(e,t){this.message=e,this.locator=t,Error.captureStackTrace&&Error.captureStackTrace(this,zr)}function Gr(){}function Xr(e,t){return t.lineNumber=e.lineNumber,t.columnNumber=e.columnNumber,t}function Kr(e,t,i){for(var n=e.tagName,r=null,a=e.length;a--;){var s=e[a],o=s.qName,u=s.value,o=0<(c=o.indexOf(":"))?(l=s.prefix=o.slice(0,c),d=o.slice(c+1),"xmlns"===l&&d):(l=null,"xmlns"===(d=o)&&"");s.localName=d,!1!==o&&(null==r&&(r={},Yr(i,i={})),i[o]=r[o]=u,s.uri=Mr.XMLNS,t.startPrefixMapping(o,u))}for(var l,a=e.length;a--;)(l=(s=e[a]).prefix)&&("xml"===l&&(s.uri=Mr.XML),"xmlns"!==l&&(s.uri=i[l||""]));var c,d=0<(c=n.indexOf(":"))?(l=e.prefix=n.slice(0,c),e.localName=n.slice(c+1)):(l=null,e.localName=n),h=e.uri=i[l||""];if(t.startElement(h,d,n,e),!e.closed)return e.currentNSMap=i,e.localNSMap=r,1;if(t.endElement(h,d,n),r)for(l in r)t.endPrefixMapping(l)}function Yr(e,t){for(var i in e)t[i]=e[i]}function Qr(){this.attributeNames={}}(zr.prototype=new Error).name=zr.name,Gr.prototype={parse:function(e,t,i){var n=this.domBuilder;n.startDocument(),Yr(t,t={}),function(i,e,n,r,a){function s(e){var t=e.slice(1,-1);return t in n?n[t]:"#"===t.charAt(0)?65535<(t=parseInt(t.substr(1).replace("x","0x")))?(t-=65536,String.fromCharCode(55296+(t>>10),56320+(1023&t))):String.fromCharCode(t):(a.error("entity not found:"+e),e)}function t(e){var t;f<e&&(t=i.substring(f,e).replace(/&#?\w+;/g,s),d&&o(f),r.characters(t,0,e-f),f=e)}function o(e,t){for(;l<=e&&(t=c.exec(i));)u=t.index,l=u+t[0].length,d.lineNumber++;d.columnNumber=e-u+1}var u=0,l=0,c=/.*(?:\r\n?|\n)|.*$/g,d=r.locator,h=[{currentNSMap:e}],p={},f=0;for(;;){try{var m,g,y=i.indexOf("<",f);if(y<0)return i.substr(f).match(/^\s*$/)||(m=r.doc,g=m.createTextNode(i.substr(f)),m.appendChild(g),r.currentElement=g);switch(f<y&&t(y),i.charAt(y+1)){case"/":var v=i.indexOf(">",y+3),_=i.substring(y+2,v).replace(/[ \t\n\r]+$/g,""),b=h.pop();v<0?(_=i.substring(y+2).replace(/[\s<].*/,""),a.error("end tag name: "+_+" is not complete:"+b.tagName),v=y+1+_.length):_.match(/\s</)&&(_=_.replace(/[\s<].*/,""),a.error("end tag name: "+_+" maybe not complete"),v=y+1+_.length);var T=b.localNSMap,S=b.tagName==_;if(S||b.tagName&&b.tagName.toLowerCase()==_.toLowerCase()){if(r.endElement(b.uri,b.localName,_),T)for(var E in T)r.endPrefixMapping(E);S||a.fatalError("end tag name: "+_+" is not match the current start tagName:"+b.tagName)}else h.push(b);v++;break;case"?":d&&o(y),v=function(e,t,i){var n=e.indexOf("?>",t);if(n){t=e.substring(t,n).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);return t?(t[0].length,i.processingInstruction(t[1],t[2]),n+2):-1}return-1}(i,y,r);break;case"!":d&&o(y),v=function(e,t,i,n){{if("-"===e.charAt(t+2)){if("-"!==e.charAt(t+3))return-1;var r=e.indexOf("--\x3e",t+4);return t<r?(i.comment(e,t+4,r-t-4),r+3):(n.error("Unclosed comment"),-1)}if("CDATA["==e.substr(t+3,6)){r=e.indexOf("]]>",t+9);return i.startCDATA(),i.characters(e,t+9,r-t-9),i.endCDATA(),r+3}var a=function(e,t){var i,n=[],r=/'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;r.lastIndex=t,r.exec(e);for(;i=r.exec(e);)if(n.push(i),i[1])return n}(e,t),n=a.length;if(1<n&&/!doctype/i.test(a[0][0])){r=a[1][0],e=!1,t=!1;3<n&&(/^public$/i.test(a[2][0])?(e=a[3][0],t=4<n&&a[4][0]):/^system$/i.test(a[2][0])&&(t=a[3][0]));n=a[n-1];return i.startDTD(r,e,t),i.endDTD(),n.index+n[0].length}}return-1}(i,y,r,a);break;default:d&&o(y);var k=new Qr,C=h[h.length-1].currentNSMap,v=function(e,t,n,i,r,a){function s(e,t,i){e in n.attributeNames&&a.fatalError("Attribute "+e+" redefined"),n.addValue(e,t,i)}var o,u=++t,l=Ur;for(;;){var c=e.charAt(u);switch(c){case"=":if(l===Br)o=e.slice(t,u),l=jr;else{if(l!==Fr)throw new Error("attribute equal must after attrName");l=jr}break;case"'":case'"':if(l===jr||l===Br){if(l===Br&&(a.warning('attribute value must after "="'),o=e.slice(t,u)),t=u+1,!(0<(u=e.indexOf(c,t))))throw new Error("attribute value no end '"+c+"' match");d=e.slice(t,u).replace(/&#?\w+;/g,r),s(o,d,t-1),l=qr}else{if(l!=Hr)throw new Error('attribute value must after "="');d=e.slice(t,u).replace(/&#?\w+;/g,r),s(o,d,t),a.warning('attribute "'+o+'" missed start quot('+c+")!!"),t=u+1,l=qr}break;case"/":switch(l){case Ur:n.setTagName(e.slice(t,u));case qr:case Vr:case Wr:l=Wr,n.closed=!0;case Hr:case Br:case Fr:break;default:throw new Error("attribute invalid close char('/')")}break;case"":return a.error("unexpected end of input"),l==Ur&&n.setTagName(e.slice(t,u)),u;case">":switch(l){case Ur:n.setTagName(e.slice(t,u));case qr:case Vr:case Wr:break;case Hr:case Br:"/"===(d=e.slice(t,u)).slice(-1)&&(n.closed=!0,d=d.slice(0,-1));case Fr:l===Fr&&(d=o),l==Hr?(a.warning('attribute "'+d+'" missed quot(")!'),s(o,d.replace(/&#?\w+;/g,r),t)):(Mr.isHTML(i[""])&&d.match(/^(?:disabled|checked|selected)$/i)||a.warning('attribute "'+d+'" missed value!! "'+d+'" instead!!'),s(d,d,t));break;case jr:throw new Error("attribute value missed!!")}return u;case"\80":c=" ";default:if(c<=" ")switch(l){case Ur:n.setTagName(e.slice(t,u)),l=Vr;break;case Br:o=e.slice(t,u),l=Fr;break;case Hr:var d=e.slice(t,u).replace(/&#?\w+;/g,r);a.warning('attribute "'+d+'" missed quot(")!!'),s(o,d,t);case qr:l=Vr}else switch(l){case Fr:n.tagName,Mr.isHTML(i[""])&&o.match(/^(?:disabled|checked|selected)$/i)||a.warning('attribute "'+o+'" missed value!! "'+o+'" instead2!!'),s(o,o,t),t=u,l=Br;break;case qr:a.warning('attribute space is required"'+o+'"!!');case Vr:l=Br,t=u;break;case jr:l=Hr,t=u;break;case Wr:throw new Error("elements closed character '/' and '>' must be connected to")}}u++}}(i,y,k,C,s,a),w=k.length;if(!k.closed&&function(e,t,i,n){var r=n[i];null==r&&((r=e.lastIndexOf("</"+i+">"))<t&&(r=e.lastIndexOf("</"+i)),n[i]=r);return r<t}(i,v,k.tagName,p)&&(k.closed=!0,n.nbsp||a.warning("unclosed xml attribute")),d&&w){for(var I=Xr(d,{}),x=0;x<w;x++){var A=k[x];o(A.offset),A.locator=Xr(d,{})}r.locator=I,Kr(k,r,C)&&h.push(k),r.locator=d}else Kr(k,r,C)&&h.push(k);Mr.isHTML(k.uri)&&!k.closed?v=function(e,t,i,n,r){if(/^(?:script|textarea)$/i.test(i)){var a=e.indexOf("</"+i+">",t),e=e.substring(t+1,a);if(/[&<]/.test(e))return/^script$/i.test(i)||(e=e.replace(/&#?\w+;/g,n)),r.characters(e,0,e.length),a}return t+1}(i,v,k.tagName,s,r):v++}}catch(e){if(e instanceof zr)throw e;a.error("element parse error: "+e),v=-1}f<v?f=v:t(Math.max(y,f)+1)}}(e,t,i,n,this.errorHandler),n.endDocument()}},Qr.prototype={setTagName:function(e){if(!Nr.test(e))throw new Error("invalid tagName:"+e);this.tagName=e},addValue:function(e,t,i){if(!Nr.test(e))throw new Error("invalid attribute:"+e);this.attributeNames[e]=this.length,this[this.length++]={qName:e,value:t,offset:i}},length:0,getLocalName:function(e){return this[e].localName},getLocator:function(e){return this[e].locator},getQName:function(e){return this[e].qName},getURI:function(e){return this[e].uri},getValue:function(e){return this[e].value}};var $r={XMLReader:Gr,ParseError:zr},Jr=Or.NAMESPACE;function Zr(e){return""!==e}function ea(e,t){return e.hasOwnProperty(t)||(e[t]=!0),e}function ta(e){if(!e)return[];e=(e=e)?e.split(/[\t\n\f\r ]+/).filter(Zr):[];return Object.keys(e.reduce(ea,{}))}function ia(e,t){for(var i in e)t[i]=e[i]}function na(e,t){var i,n=e.prototype;n instanceof t||((i=function(){}).prototype=t.prototype,ia(n,i=new i),e.prototype=n=i),n.constructor!=e&&(n.constructor=e)}var si={},ra=si.ELEMENT_NODE=1,aa=si.ATTRIBUTE_NODE=2,sa=si.TEXT_NODE=3,oa=si.CDATA_SECTION_NODE=4,ua=si.ENTITY_REFERENCE_NODE=5,la=(si.ENTITY_NODE=6,si.PROCESSING_INSTRUCTION_NODE=7),ca=si.COMMENT_NODE=8,da=si.DOCUMENT_NODE=9,ha=si.DOCUMENT_TYPE_NODE=10,pa=si.DOCUMENT_FRAGMENT_NODE=11,Kt=(si.NOTATION_NODE=12,{}),fa={};Kt.INDEX_SIZE_ERR=(fa[1]="Index size error",1),Kt.DOMSTRING_SIZE_ERR=(fa[2]="DOMString size error",2);Kt.HIERARCHY_REQUEST_ERR=(fa[3]="Hierarchy request error",3);Kt.WRONG_DOCUMENT_ERR=(fa[4]="Wrong document",4),Kt.INVALID_CHARACTER_ERR=(fa[5]="Invalid character",5),Kt.NO_DATA_ALLOWED_ERR=(fa[6]="No data allowed",6),Kt.NO_MODIFICATION_ALLOWED_ERR=(fa[7]="No modification allowed",7);Kt.NOT_FOUND_ERR=(fa[8]="Not found",8);Kt.NOT_SUPPORTED_ERR=(fa[9]="Not supported",9);var ma;Kt.INUSE_ATTRIBUTE_ERR=(fa[10]="Attribute in use",10);function ga(e,t){var i;return t instanceof Error?i=t:(i=this,Error.call(this,fa[e]),this.message=fa[e],Error.captureStackTrace&&Error.captureStackTrace(this,ga)),i.code=e,t&&(this.message=this.message+": "+t),i}function ya(){}function va(e,t){this._node=e,this._refresh=t,_a(this)}function _a(e){var t,i=e._node._inc||e._node.ownerDocument._inc;e._inc!=i&&(t=e._refresh(e._node),Qa(e,"length",t.length),ia(t,e),e._inc=i)}function ba(){}function Ta(e,t){for(var i=e.length;i--;)if(e[i]===t)return i}function Sa(e,t,i,n){n?t[Ta(t,n)]=i:t[t.length++]=i,!e||(t=(i.ownerElement=e).ownerDocument)&&(n&&Aa(t,e,n),e=e,i=i,(t=t)&&t._inc++,i.namespaceURI===Jr.XMLNS&&(e._nsMap[i.prefix?i.localName:""]=i.value))}function Ea(e,t,i){var n=Ta(t,i);if(!(0<=n))throw ga(8,new Error(e.tagName+"@"+i));for(var r,a=t.length-1;n<a;)t[n]=t[++n];t.length=a,!e||(r=e.ownerDocument)&&(Aa(r,e,i),i.ownerElement=null)}function ka(){}function Ca(){}function wa(e){return("<"==e?"<":">"==e&&">")||"&"==e&&"&"||'"'==e&&"""||"&#"+e.charCodeAt()+";"}function Ia(e,t){if(t(e))return 1;if(e=e.firstChild)do{if(Ia(e,t))return 1}while(e=e.nextSibling)}function xa(){}function Aa(e,t,i){e&&e._inc++,i.namespaceURI===Jr.XMLNS&&delete t._nsMap[i.prefix?i.localName:""]}function Pa(e,t,i){if(e&&e._inc){e._inc++;var n=t.childNodes;if(i)n[n.length++]=i;else{for(var r=t.firstChild,a=0;r;)r=(n[a++]=r).nextSibling;n.length=a}}}function La(e,t){var i=t.previousSibling,n=t.nextSibling;return i?i.nextSibling=n:e.firstChild=n,n?n.previousSibling=i:e.lastChild=i,Pa(e.ownerDocument,e),t}function Da(e,t,i){var n=t.parentNode;if(n&&n.removeChild(t),t.nodeType===pa){var r=t.firstChild;if(null==r)return t;var a=t.lastChild}else r=a=t;n=i?i.previousSibling:e.lastChild;for(r.previousSibling=n,a.nextSibling=i,n?n.nextSibling=r:e.firstChild=r,null==i?e.lastChild=a:i.previousSibling=a;r.parentNode=e,r!==a&&(r=r.nextSibling););return Pa(e.ownerDocument||e,e),t.nodeType==pa&&(t.firstChild=t.lastChild=null),t}function Oa(){this._nsMap={}}function Ra(){}function Ma(){}function Na(){}function Ua(){}function Ba(){}function Fa(){}function ja(){}function Ha(){}function qa(){}function Va(){}function Wa(){}function za(){}function Ga(e,t){var i,n=[],r=9==this.nodeType&&this.documentElement||this,a=r.prefix,s=r.namespaceURI;return Ya(this,n,e,t,i=s&&null==a&&null==(a=r.lookupPrefix(s))?[{namespace:s,prefix:null}]:i),n.join("")}function Xa(e,t,i){var n=e.prefix||"",r=e.namespaceURI;if(r&&("xml"!==n||r!==Jr.XML)&&r!==Jr.XMLNS){for(var a=i.length;a--;){var s=i[a];if(s.prefix===n)return s.namespace!==r}return 1}}function Ka(e,t,i){e.push(" ",t,'="',i.replace(/[<&"]/g,wa),'"')}function Ya(e,t,i,n,r){if(r=r||[],n){if(!(e=n(e)))return;if("string"==typeof e)return void t.push(e)}switch(e.nodeType){case ra:var a=e.attributes,s=a.length,o=e.firstChild,u=e.tagName,l=u;if(!(i=Jr.isHTML(e.namespaceURI)||i)&&!e.prefix&&e.namespaceURI){for(var c,d=0;d<a.length;d++)if("xmlns"===a.item(d).name){c=a.item(d).value;break}if(c!==e.namespaceURI)for(var h=r.length-1;0<=h;h--){var p=r[h];if(p.namespace===e.namespaceURI){p.prefix&&(l=p.prefix+":"+u);break}}}t.push("<",l);for(var f=0;f<s;f++)"xmlns"==(m=a.item(f)).prefix?r.push({prefix:m.localName,namespace:m.value}):"xmlns"==m.nodeName&&r.push({prefix:"",namespace:m.value});for(var m,g,y,f=0;f<s;f++)Xa(m=a.item(f),0,r)&&(Ka(t,(g=m.prefix||"")?"xmlns:"+g:"xmlns",y=m.namespaceURI),r.push({prefix:g,namespace:y})),Ya(m,t,i,n,r);if(u===l&&Xa(e,0,r)&&(Ka(t,(g=e.prefix||"")?"xmlns:"+g:"xmlns",y=e.namespaceURI),r.push({prefix:g,namespace:y})),o||i&&!/^(?:meta|link|img|br|hr|input)$/i.test(u)){if(t.push(">"),i&&/^script$/i.test(u))for(;o;)o.data?t.push(o.data):Ya(o,t,i,n,r.slice()),o=o.nextSibling;else for(;o;)Ya(o,t,i,n,r.slice()),o=o.nextSibling;t.push("</",l,">")}else t.push("/>");return;case da:case pa:for(o=e.firstChild;o;)Ya(o,t,i,n,r.slice()),o=o.nextSibling;return;case aa:return Ka(t,e.name,e.value),0;case sa:return t.push(e.data.replace(/[<&]/g,wa).replace(/]]>/g,"]]>"));case oa:return t.push("<![CDATA[",e.data,"]]>");case ca:return t.push("\x3c!--",e.data,"--\x3e");case ha:var v=e.publicId,_=e.systemId;return t.push("<!DOCTYPE ",e.name),void(v?(t.push(" PUBLIC ",v),_&&"."!=_&&t.push(" ",_),t.push(">")):_&&"."!=_?t.push(" SYSTEM ",_,">"):((_=e.internalSubset)&&t.push(" [",_,"]"),t.push(">")));case la:return t.push("<?",e.target," ",e.data,"?>");case ua:return t.push("&",e.nodeName,";");default:t.push("??",e.nodeName)}}function Qa(e,t,i){e[t]=i}Kt.INVALID_STATE_ERR=(fa[11]="Invalid state",11),Kt.SYNTAX_ERR=(fa[12]="Syntax error",12),Kt.INVALID_MODIFICATION_ERR=(fa[13]="Invalid modification",13),Kt.NAMESPACE_ERR=(fa[14]="Invalid namespace",14),Kt.INVALID_ACCESS_ERR=(fa[15]="Invalid access",15),ga.prototype=Error.prototype,ia(Kt,ga),ya.prototype={length:0,item:function(e){return this[e]||null},toString:function(e,t){for(var i=[],n=0;n<this.length;n++)Ya(this[n],i,e,t);return i.join("")}},va.prototype.item=function(e){return _a(this),this[e]},na(va,ya),ba.prototype={length:0,item:ya.prototype.item,getNamedItem:function(e){for(var t=this.length;t--;){var i=this[t];if(i.nodeName==e)return i}},setNamedItem:function(e){var t=e.ownerElement;if(t&&t!=this._ownerElement)throw new ga(10);t=this.getNamedItem(e.nodeName);return Sa(this._ownerElement,this,e,t),t},setNamedItemNS:function(e){var t=e.ownerElement;if(t&&t!=this._ownerElement)throw new ga(10);return t=this.getNamedItemNS(e.namespaceURI,e.localName),Sa(this._ownerElement,this,e,t),t},removeNamedItem:function(e){e=this.getNamedItem(e);return Ea(this._ownerElement,this,e),e},removeNamedItemNS:function(e,t){t=this.getNamedItemNS(e,t);return Ea(this._ownerElement,this,t),t},getNamedItemNS:function(e,t){for(var i=this.length;i--;){var n=this[i];if(n.localName==t&&n.namespaceURI==e)return n}return null}},ka.prototype={hasFeature:function(e,t){return!0},createDocument:function(e,t,i){var n=new xa;return n.implementation=this,n.childNodes=new ya,n.doctype=i||null,i&&n.appendChild(i),t&&(t=n.createElementNS(e,t),n.appendChild(t)),n},createDocumentType:function(e,t,i){var n=new Fa;return n.name=e,n.nodeName=e,n.publicId=t||"",n.systemId=i||"",n}},Ca.prototype={firstChild:null,lastChild:null,previousSibling:null,nextSibling:null,attributes:null,parentNode:null,childNodes:null,ownerDocument:null,nodeValue:null,namespaceURI:null,prefix:null,localName:null,insertBefore:function(e,t){return Da(this,e,t)},replaceChild:function(e,t){this.insertBefore(e,t),t&&this.removeChild(t)},removeChild:function(e){return La(this,e)},appendChild:function(e){return this.insertBefore(e,null)},hasChildNodes:function(){return null!=this.firstChild},cloneNode:function(e){return function e(t,i,n){var r=new i.constructor;for(var a in i){var s=i[a];"object"!=typeof s&&s!=r[a]&&(r[a]=s)}i.childNodes&&(r.childNodes=new ya);r.ownerDocument=t;switch(r.nodeType){case ra:var o=i.attributes,u=r.attributes=new ba,l=o.length;u._ownerElement=r;for(var c=0;c<l;c++)r.setAttributeNode(e(t,o.item(c),!0));break;case aa:n=!0}if(n)for(var d=i.firstChild;d;)r.appendChild(e(t,d,n)),d=d.nextSibling;return r}(this.ownerDocument||this,this,e)},normalize:function(){for(var e=this.firstChild;e;){var t=e.nextSibling;t&&t.nodeType==sa&&e.nodeType==sa?(this.removeChild(t),e.appendData(t.data)):(e.normalize(),e=t)}},isSupported:function(e,t){return this.ownerDocument.implementation.hasFeature(e,t)},hasAttributes:function(){return 0<this.attributes.length},lookupPrefix:function(e){for(var t=this;t;){var i=t._nsMap;if(i)for(var n in i)if(i[n]==e)return n;t=t.nodeType==aa?t.ownerDocument:t.parentNode}return null},lookupNamespaceURI:function(e){for(var t=this;t;){var i=t._nsMap;if(i&&e in i)return i[e];t=t.nodeType==aa?t.ownerDocument:t.parentNode}return null},isDefaultNamespace:function(e){return null==this.lookupPrefix(e)}},ia(si,Ca),ia(si,Ca.prototype),xa.prototype={nodeName:"#document",nodeType:da,doctype:null,documentElement:null,_inc:1,insertBefore:function(e,t){if(e.nodeType!=pa)return null==this.documentElement&&e.nodeType==ra&&(this.documentElement=e),Da(this,e,t),e.ownerDocument=this,e;for(var i=e.firstChild;i;){var n=i.nextSibling;this.insertBefore(i,t),i=n}return e},removeChild:function(e){return this.documentElement==e&&(this.documentElement=null),La(this,e)},importNode:function(e,t){return function e(t,i,n){var r;switch(i.nodeType){case ra:(r=i.cloneNode(!1)).ownerDocument=t;case pa:break;case aa:n=!0}r=r||i.cloneNode(!1);r.ownerDocument=t;r.parentNode=null;if(n)for(var a=i.firstChild;a;)r.appendChild(e(t,a,n)),a=a.nextSibling;return r}(this,e,t)},getElementById:function(t){var i=null;return Ia(this.documentElement,function(e){if(e.nodeType==ra&&e.getAttribute("id")==t)return i=e,!0}),i},getElementsByClassName:function(s){var o=ta(s);return new va(this,function(r){var a=[];return 0<o.length&&Ia(r.documentElement,function(e){var t,i,n;e===r||e.nodeType!==ra||(t=e.getAttribute("class"))&&((i=s===t)||(t=ta(t),i=o.every((n=t,function(e){return n&&-1!==n.indexOf(e)}))),i&&a.push(e))}),a})},createElement:function(e){var t=new Oa;return t.ownerDocument=this,t.nodeName=e,t.tagName=e,t.localName=e,t.childNodes=new ya,(t.attributes=new ba)._ownerElement=t},createDocumentFragment:function(){var e=new Va;return e.ownerDocument=this,e.childNodes=new ya,e},createTextNode:function(e){var t=new Na;return t.ownerDocument=this,t.appendData(e),t},createComment:function(e){var t=new Ua;return t.ownerDocument=this,t.appendData(e),t},createCDATASection:function(e){var t=new Ba;return t.ownerDocument=this,t.appendData(e),t},createProcessingInstruction:function(e,t){var i=new Wa;return i.ownerDocument=this,i.tagName=i.target=e,i.nodeValue=i.data=t,i},createAttribute:function(e){var t=new Ra;return t.ownerDocument=this,t.name=e,t.nodeName=e,t.localName=e,t.specified=!0,t},createEntityReference:function(e){var t=new qa;return t.ownerDocument=this,t.nodeName=e,t},createElementNS:function(e,t){var i=new Oa,n=t.split(":"),r=i.attributes=new ba;return i.childNodes=new ya,i.ownerDocument=this,i.nodeName=t,i.tagName=t,i.namespaceURI=e,2==n.length?(i.prefix=n[0],i.localName=n[1]):i.localName=t,r._ownerElement=i},createAttributeNS:function(e,t){var i=new Ra,n=t.split(":");return i.ownerDocument=this,i.nodeName=t,i.name=t,i.namespaceURI=e,i.specified=!0,2==n.length?(i.prefix=n[0],i.localName=n[1]):i.localName=t,i}},na(xa,Ca),xa.prototype.getElementsByTagName=(Oa.prototype={nodeType:ra,hasAttribute:function(e){return null!=this.getAttributeNode(e)},getAttribute:function(e){e=this.getAttributeNode(e);return e&&e.value||""},getAttributeNode:function(e){return this.attributes.getNamedItem(e)},setAttribute:function(e,t){e=this.ownerDocument.createAttribute(e);e.value=e.nodeValue=""+t,this.setAttributeNode(e)},removeAttribute:function(e){e=this.getAttributeNode(e);e&&this.removeAttributeNode(e)},appendChild:function(e){return e.nodeType===pa?this.insertBefore(e,null):function(e,t){var i=t.parentNode;i&&(n=e.lastChild,i.removeChild(t),n=e.lastChild);var n=e.lastChild;return t.parentNode=e,t.previousSibling=n,t.nextSibling=null,n?n.nextSibling=t:e.firstChild=t,e.lastChild=t,Pa(e.ownerDocument,e,t),t}(this,e)},setAttributeNode:function(e){return this.attributes.setNamedItem(e)},setAttributeNodeNS:function(e){return this.attributes.setNamedItemNS(e)},removeAttributeNode:function(e){return this.attributes.removeNamedItem(e.nodeName)},removeAttributeNS:function(e,t){t=this.getAttributeNodeNS(e,t);t&&this.removeAttributeNode(t)},hasAttributeNS:function(e,t){return null!=this.getAttributeNodeNS(e,t)},getAttributeNS:function(e,t){t=this.getAttributeNodeNS(e,t);return t&&t.value||""},setAttributeNS:function(e,t,i){t=this.ownerDocument.createAttributeNS(e,t);t.value=t.nodeValue=""+i,this.setAttributeNode(t)},getAttributeNodeNS:function(e,t){return this.attributes.getNamedItemNS(e,t)},getElementsByTagName:function(n){return new va(this,function(t){var i=[];return Ia(t,function(e){e===t||e.nodeType!=ra||"*"!==n&&e.tagName!=n||i.push(e)}),i})},getElementsByTagNameNS:function(n,r){return new va(this,function(t){var i=[];return Ia(t,function(e){e===t||e.nodeType!==ra||"*"!==n&&e.namespaceURI!==n||"*"!==r&&e.localName!=r||i.push(e)}),i})}}).getElementsByTagName,xa.prototype.getElementsByTagNameNS=Oa.prototype.getElementsByTagNameNS,na(Oa,Ca),Ra.prototype.nodeType=aa,na(Ra,Ca),Ma.prototype={data:"",substringData:function(e,t){return this.data.substring(e,e+t)},appendData:function(e){e=this.data+e,this.nodeValue=this.data=e,this.length=e.length},insertData:function(e,t){this.replaceData(e,0,t)},appendChild:function(e){throw new Error(fa[3])},deleteData:function(e,t){this.replaceData(e,t,"")},replaceData:function(e,t,i){var n=this.data.substring(0,e),t=this.data.substring(e+t);this.nodeValue=this.data=i=n+i+t,this.length=i.length}},na(Ma,Ca),Na.prototype={nodeName:"#text",nodeType:sa,splitText:function(e){var t=(i=this.data).substring(e),i=i.substring(0,e);this.data=this.nodeValue=i,this.length=i.length;t=this.ownerDocument.createTextNode(t);return this.parentNode&&this.parentNode.insertBefore(t,this.nextSibling),t}},na(Na,Ma),Ua.prototype={nodeName:"#comment",nodeType:ca},na(Ua,Ma),Ba.prototype={nodeName:"#cdata-section",nodeType:oa},na(Ba,Ma),Fa.prototype.nodeType=ha,na(Fa,Ca),ja.prototype.nodeType=12,na(ja,Ca),Ha.prototype.nodeType=6,na(Ha,Ca),qa.prototype.nodeType=ua,na(qa,Ca),Va.prototype.nodeName="#document-fragment",Va.prototype.nodeType=pa,na(Va,Ca),Wa.prototype.nodeType=la,na(Wa,Ca),za.prototype.serializeToString=function(e,t,i){return Ga.call(e,t,i)},Ca.prototype.toString=Ga;try{Object.defineProperty&&(ma=function e(t){switch(t.nodeType){case ra:case pa:var i=[];for(t=t.firstChild;t;)7!==t.nodeType&&8!==t.nodeType&&i.push(e(t)),t=t.nextSibling;return i.join("");default:return t.nodeValue}},Object.defineProperty(va.prototype,"length",{get:function(){return _a(this),this.$$length}}),Object.defineProperty(Ca.prototype,"textContent",{get:function(){return ma(this)},set:function(e){switch(this.nodeType){case ra:case pa:for(;this.firstChild;)this.removeChild(this.firstChild);(e||String(e))&&this.appendChild(this.ownerDocument.createTextNode(e));break;default:this.data=e,this.value=e,this.nodeValue=e}}}),Qa=function(e,t,i){e["$$"+t]=i})}catch(e){}var $a={DocumentType:Fa,DOMException:ga,DOMImplementation:ka,Element:Oa,Node:Ca,NodeList:ya,XMLSerializer:za},sr=t(function(e,t){var l=Or.NAMESPACE;function i(e){this.options=e||{locator:{}}}function c(){this.cdata=!1}function d(e,t){t.lineNumber=e.lineNumber,t.columnNumber=e.columnNumber}function h(e){if(e)return"\n@"+(e.systemId||"")+"#[line:"+e.lineNumber+",col:"+e.columnNumber+"]"}function r(e,t,i){return"string"==typeof e?e.substr(t,i):e.length>=t+i||t?new java.lang.String(e,t,i)+"":e}function p(e,t){(e.currentElement||e.doc).appendChild(t)}i.prototype.parseFromString=function(e,t){var i=this.options,n=new f,r=i.domBuilder||new c,a=i.errorHandler,s=i.locator,o=i.xmlns||{},u=/\/x?html?$/.test(t),t=u?Rr.HTML_ENTITIES:Rr.XML_ENTITIES;return s&&r.setDocumentLocator(s),n.errorHandler=function(n,e,r){if(!n){if(e instanceof c)return e;n=e}var a={},s=n instanceof Function;function t(t){var i=n[t];!i&&s&&(i=2==n.length?function(e){n(t,e)}:n),a[t]=i?function(e){i("[xmldom "+t+"]\t"+e+h(r))}:function(){}}return r=r||{},t("warning"),t("error"),t("fatalError"),a}(a,r,s),n.domBuilder=i.domBuilder||r,u&&(o[""]=l.HTML),o.xml=o.xml||l.XML,e&&"string"==typeof e?n.parse(e,o,t):n.errorHandler.error("invalid doc source"),r.doc},c.prototype={startDocument:function(){this.doc=(new a).createDocument(null,null,null),this.locator&&(this.doc.documentURI=this.locator.systemId)},startElement:function(e,t,i,n){var r=this.doc,a=r.createElementNS(e,i||t),s=n.length;p(this,a),this.currentElement=a,this.locator&&d(this.locator,a);for(var o=0;o<s;o++){var e=n.getURI(o),u=n.getValue(o),i=n.getQName(o),l=r.createAttributeNS(e,i);this.locator&&d(n.getLocator(o),l),l.value=l.nodeValue=u,a.setAttributeNode(l)}},endElement:function(e,t,i){var n=this.currentElement;n.tagName,this.currentElement=n.parentNode},startPrefixMapping:function(e,t){},endPrefixMapping:function(e){},processingInstruction:function(e,t){t=this.doc.createProcessingInstruction(e,t);this.locator&&d(this.locator,t),p(this,t)},ignorableWhitespace:function(e,t,i){},characters:function(e,t,i){var n;(e=r.apply(this,arguments))&&(n=this.cdata?this.doc.createCDATASection(e):this.doc.createTextNode(e),this.currentElement?this.currentElement.appendChild(n):/^\s*$/.test(e)&&this.doc.appendChild(n),this.locator&&d(this.locator,n))},skippedEntity:function(e){},endDocument:function(){this.doc.normalize()},setDocumentLocator:function(e){(this.locator=e)&&(e.lineNumber=0)},comment:function(e,t,i){e=r.apply(this,arguments);e=this.doc.createComment(e);this.locator&&d(this.locator,e),p(this,e)},startCDATA:function(){this.cdata=!0},endCDATA:function(){this.cdata=!1},startDTD:function(e,t,i){var n=this.doc.implementation;n&&n.createDocumentType&&(i=n.createDocumentType(e,t,i),this.locator&&d(this.locator,i),p(this,i))},warning:function(e){},error:function(e){},fatalError:function(e){throw new n(e,this.locator)}},"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(e){c.prototype[e]=function(){return null}});var f=$r.XMLReader,n=$r.ParseError,a=t.DOMImplementation=$a.DOMImplementation;t.XMLSerializer=$a.XMLSerializer,t.DOMParser=i,t.__DOMHandler=c});sr.DOMImplementation,sr.XMLSerializer;var Ja=sr.DOMParser;sr.__DOMHandler;function Za(e){return!!e&&"object"==typeof e}function es(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];return t.reduce(function(t,i){return"object"!=typeof i||Object.keys(i).forEach(function(e){Array.isArray(t[e])&&Array.isArray(i[e])?t[e]=t[e].concat(i[e]):Za(t[e])&&Za(i[e])?t[e]=es(t[e],i[e]):t[e]=i[e]}),t},{})}function ts(e){return e.reduce(function(e,t){return e.concat(t)},[])}function is(e){if(!e.length)return[];for(var t=[],i=0;i<e.length;i++)t.push(e[i]);return t}function ns(e){var t=e.baseUrl,i=void 0===(n=e.source)?"":n,n=void 0===(n=e.range)?"":n,e=void 0===(e=e.indexRange)?"":e,i={uri:i,resolvedUri:nr((void 0===t?"":t)||"",i)};return(n||e)&&(n=(n||e).split("-"),e=parseInt(n[0],10),n=parseInt(n[1],10),i.byterange={length:n-e+1,offset:e}),i}function rs(e){return e&&"number"!=typeof e&&(e=parseInt(e,10)),isNaN(e)?null:e}function as(e){var s,t=e.type,i=e.duration,n=e.timescale,r=void 0===n?1:n,a=e.periodDuration,o=e.sourceDuration,e=function(e,t){for(var i=[],n=e;n<t;n++)i.push(n);return i}((n=$s[t](e)).start,n.end).map((s=e,function(e,t){var i=s.duration,n=s.timescale,r=s.periodIndex,a=s.startNumber;return{number:(void 0===a?1:a)+e,duration:i/(void 0===n?1:n),timeline:r,time:t*i}}));return"static"===t&&(e[t=e.length-1].duration=("number"==typeof a?a:o)-i/r*t),e}function ss(e){var t=e.baseUrl,i=void 0===(r=e.initialization)?{}:r,n=e.sourceDuration,r=void 0===(a=e.indexRange)?"":a,a=e.duration;if(!t)throw new Error(Ks);return i=ns({baseUrl:t,source:i.sourceURL,range:i.range}),(r=ns({baseUrl:t,source:t,indexRange:r})).map=i,a?(e=as(e)).length&&(r.duration=e[0].duration,r.timeline=e[0].timeline):n&&(r.duration=n,r.timeline=0),r.number=0,[r]}function os(e,t,i){for(var n=e.sidx.map||null,r=e.sidx.duration,a=e.timeline||0,s=(s=e.sidx.byterange).offset+s.length,o=t.timescale,u=t.references.filter(function(e){return 1!==e.referenceType}),l=[],c=e.endList?"static":"dynamic",d=s+t.firstOffset,h=0;h<u.length;h++){var p=t.references[h],f=p.referencedSize,p=p.subsegmentDuration,p=ss({baseUrl:i,timescale:o,timeline:a,periodIndex:a,duration:p,sourceDuration:r,indexRange:d+"-"+(d+f-1),type:c})[0];n&&(p.map=n),l.push(p),d+=f}return e.segments=l,e}function us(e){return e&&e.uri+"-"+(t=e.byterange,e=t.offset+t.length-1,t.offset+"-"+e);var t}function ls(e){var t;return(t=e.reduce(function(e,t){var i,n=t.attributes.id+(t.attributes.lang||"");return e[n]?(t.segments[0]&&(t.segments[0].discontinuity=!0),(i=e[n].segments).push.apply(i,t.segments),t.attributes.contentProtection&&(e[n].attributes.contentProtection=t.attributes.contentProtection)):e[n]=t,e},{}),Object.keys(t).map(function(e){return t[e]})).map(function(e){var t,n;return e.discontinuityStarts=(t=e.segments,n="discontinuity",t.reduce(function(e,t,i){return t[n]&&e.push(i),e},[])),e})}function cs(e,t){var i=us(e.sidx);return(i=i&&t[i]&&t[i].sidx)&&os(e,i,e.sidx.resolvedUri),e}function ds(e,l,c){var d;return void 0===l&&(l={}),void 0===c&&(c=!1),e=e.reduce(function(e,t){var i=t.attributes.role&&t.attributes.role.value||"",n=t.attributes.lang||"",r=t.attributes.label||"main";e[r=n&&!t.attributes.label?t.attributes.lang+(i?" ("+i+")":""):r]||(e[r]={language:n,autoselect:!0,default:"main"===i,playlists:[],uri:""});var a,s,o,u,u=cs((s=c,o=(a=t).attributes,u=a.segments,n=a.sidx,u={attributes:((a={NAME:o.id,BANDWIDTH:o.bandwidth,CODECS:o.codecs})["PROGRAM-ID"]=1,a),uri:"",endList:"static"===o.type,timeline:o.periodIndex,resolvedUri:"",targetDuration:o.duration,segments:u,mediaSequence:u.length?u[0].number:1},o.contentProtection&&(u.contentProtection=o.contentProtection),n&&(u.sidx=n),s&&(u.attributes.AUDIO="audio",u.attributes.SUBTITLES="subs"),u),l);return e[r].playlists.push(u),"undefined"==typeof d&&"main"===i&&((d=t).default=!0),e},{}),d||(e[Object.keys(e)[0]].default=!0),e}function hs(e){var t=e.attributes,i=e.segments,n=e.sidx,i={attributes:((e={NAME:t.id,AUDIO:"audio",SUBTITLES:"subs",RESOLUTION:{width:t.width,height:t.height},CODECS:t.codecs,BANDWIDTH:t.bandwidth})["PROGRAM-ID"]=1,e),uri:"",endList:"static"===t.type,timeline:t.periodIndex,resolvedUri:"",targetDuration:t.duration,segments:i,mediaSequence:i.length?i[0].number:1};return t.contentProtection&&(i.contentProtection=t.contentProtection),n&&(i.sidx=n),i}function ps(e){return"video/mp4"===(e=e.attributes).mimeType||"video/webm"===e.mimeType||"video"===e.contentType}function fs(e){return"audio/mp4"===(e=e.attributes).mimeType||"audio/webm"===e.mimeType||"audio"===e.contentType}function ms(e){return"text/vtt"===(e=e.attributes).mimeType||"text"===e.contentType}function gs(e,t,i){if(void 0===i&&(i={}),!e.length)return{};var n=(c=e[0].attributes).sourceDuration,r=c.type,a=c.suggestedPresentationDelay,s=c.minimumUpdatePeriod,o=ls(e.filter(ps)).map(hs),u=ls(e.filter(fs)),l=e.filter(ms),c=e.map(function(e){return e.attributes.captionServices}).filter(Boolean),o={allowCache:!0,discontinuityStarts:[],segments:[],endList:!0,mediaGroups:((e={AUDIO:{},VIDEO:{}})["CLOSED-CAPTIONS"]={},e.SUBTITLES={},e),uri:"",duration:n,playlists:function(e,t){if(void 0===t&&(t={}),!Object.keys(t).length)return e;for(var i in e)e[i]=cs(e[i],t);return e}(o,i)};0<=s&&(o.minimumUpdatePeriod=1e3*s),t&&(o.locations=t),"dynamic"===r&&(o.suggestedPresentationDelay=a);var d,a=0===o.playlists.length;return u.length&&(o.mediaGroups.AUDIO.audio=ds(u,i,a)),l.length&&(o.mediaGroups.SUBTITLES.subs=(void 0===(d=i)&&(d={}),l.reduce(function(e,t){var i=t.attributes.lang||"text";return e[i]||(e[i]={language:i,default:!1,autoselect:!1,playlists:[],uri:""}),e[i].playlists.push(cs(function(e){var t=e.attributes,i=e.segments;"undefined"==typeof i&&(i=[{uri:t.baseUrl,timeline:t.periodIndex,resolvedUri:t.baseUrl||"",duration:t.sourceDuration,number:0}],t.duration=t.sourceDuration);(e={NAME:t.id,BANDWIDTH:t.bandwidth})["PROGRAM-ID"]=1;return t.codecs&&(e.CODECS=t.codecs),{attributes:e,uri:"",endList:"static"===t.type,timeline:t.periodIndex,resolvedUri:t.baseUrl||"",targetDuration:t.duration,segments:i,mediaSequence:i.length?i[0].number:1}}(t),d)),e},{}))),c.length&&(o.mediaGroups["CLOSED-CAPTIONS"].cc=c.reduce(function(n,e){return e&&e.forEach(function(e){var t=e.channel,i=e.language;n[i]={autoselect:!1,default:!1,instreamId:t,language:i},e.hasOwnProperty("aspectRatio")&&(n[i].aspectRatio=e.aspectRatio),e.hasOwnProperty("easyReader")&&(n[i].easyReader=e.easyReader),e.hasOwnProperty("3D")&&(n[i]["3D"]=e["3D"])}),n},{})),o}function ys(e,t){for(var i,n,r,a,s,o,u=e.type,l=e.minimumUpdatePeriod,c=void 0===l?0:l,d=void 0===(l=e.media)?"":l,h=e.sourceDuration,p=void 0===(l=e.timescale)?1:l,f=void 0===(l=e.startNumber)?1:l,m=e.periodIndex,g=[],y=-1,v=0;v<t.length;v++){var _=t[v],b=_.d,T=_.r||0,S=_.t||0;y<0&&(y=S),S&&y<S&&(y=S);var E,k=void 0;k=T<0?(E=v+1)===t.length?"dynamic"===u&&0<c&&0<d.indexOf("$Number$")?(i=y,n=b,_=o=s=a=r=void 0,r=(S=e).NOW,a=S.clientOffset,s=S.availabilityStartTime,o=S.timescale,_=S.start,S=S.minimumUpdatePeriod,Math.ceil((((r+a)/1e3+(void 0===S?0:S)-(s+(void 0===_?0:_)))*(void 0===o?1:o)-i)/n)):(h*p-y)/b:(t[E].t-y)/b:T+1;for(var C=f+g.length+k,w=f+g.length;w<C;)g.push({number:w,duration:b/p,time:y,timeline:m}),y+=b,w++}return g}function vs(e,t){return e.replace(Js,(r=t,function(e,t,i,n){if("$$"===e)return"$";if("undefined"==typeof r[t])return e;e=""+r[t];return"RepresentationID"===t||(n=i?parseInt(n,10):1)<=e.length?e:new Array(n-e.length+1).join("0")+e}));var r}function _s(r,e){var a={RepresentationID:r.id,Bandwidth:r.bandwidth||0},t=void 0===(t=r.initialization)?{sourceURL:"",range:""}:t,s=ns({baseUrl:r.baseUrl,source:vs(t.sourceURL,a),range:t.range});return(t=e,(e=r).duration||t?e.duration?as(e):ys(e,t):[{number:e.startNumber||1,duration:e.sourceDuration,time:0,timeline:e.periodIndex}]).map(function(e){a.Number=e.number,a.Time=e.time;var t=vs(r.media||"",a),i=r.timescale||1,n=r.presentationTimeOffset||0,i=r.periodStart+(e.time-n)/i;return{uri:t,timeline:e.timeline,duration:e.duration,resolvedUri:nr(r.baseUrl||"",t),map:s,number:e.number,presentationTime:i}})}function bs(r,e){var t=r.duration,i=void 0===(i=r.segmentUrls)?[]:i,a=r.periodStart;if(!t&&!e||t&&e)throw new Error(Ys);var n,s=i.map(function(e){return i=e,e=(t=r).baseUrl,t=t.initialization,t=ns({baseUrl:e,source:(t=void 0===t?{}:t).sourceURL,range:t.range}),(i=ns({baseUrl:e,source:i.media,range:i.mediaRange})).map=t,i;var t,i});return t&&(n=as(r)),(n=e?ys(r,e):n).map(function(e,t){if(s[t]){var i=s[t],n=r.timescale||1,t=r.presentationTimeOffset||0;return i.timeline=e.timeline,i.duration=e.duration,i.number=e.number,i.presentationTime=a+(e.time-t)/n,i}}).filter(function(e){return e})}function Ts(e){var t,i=e.attributes,n=e.segmentInfo;n.template?(a=_s,t=es(i,n.template)):n.base?(a=ss,t=es(i,n.base)):n.list&&(a=bs,t=es(i,n.list));var r={attributes:i};if(!a)return r;var a,e=a(t,n.segmentTimeline);return t.duration?(i=t.duration,a=t.timescale,t.duration=i/(void 0===a?1:a)):e.length?t.duration=e.reduce(function(e,t){return Math.max(e,Math.ceil(t.duration))},0):t.duration=0,r.attributes=t,r.segments=e,n.base&&t.indexRange&&(r.sidx=e[0],r.segments=[]),r}function Ss(e,t){return is(e.childNodes).filter(function(e){return e.tagName===t})}function Es(e){return e.textContent.trim()}function ks(e){if(!(r=/P(?:(\d*)Y)?(?:(\d*)M)?(?:(\d*)D)?(?:T(?:(\d*)H)?(?:(\d*)M)?(?:([\d.]*)S)?)?/.exec(e)))return 0;var t=(a=r.slice(1))[0],i=a[1],n=a[2],e=a[3],r=a[4],a=a[5];return 31536e3*parseFloat(t||0)+2592e3*parseFloat(i||0)+86400*parseFloat(n||0)+3600*parseFloat(e||0)+60*parseFloat(r||0)+parseFloat(a||0)}function Cs(e){return e&&e.attributes?is(e.attributes).reduce(function(e,t){var i=Zs[t.name]||Zs.DEFAULT;return e[t.name]=i(t.value),e},{}):{}}function ws(e,i){return i.length?ts(e.map(function(t){return i.map(function(e){return nr(t,Es(e))})})):e}function Is(e){var t=Ss(e,"SegmentTemplate")[0],i=Ss(e,"SegmentList")[0],n=i&&Ss(i,"SegmentURL").map(function(e){return es({tag:"SegmentURL"},Cs(e))}),r=Ss(e,"SegmentBase")[0],e=(a=i||t)&&Ss(a,"SegmentTimeline")[0],a=(a=i||r||t)&&Ss(a,"Initialization")[0];(t=t&&Cs(t))&&a?t.initialization=a&&Cs(a):t&&t.initialization&&(t.initialization={sourceURL:t.initialization});var s={template:t,segmentTimeline:e&&Ss(e,"S").map(Cs),list:i&&es(Cs(i),{segmentUrls:n,initialization:Cs(a)}),base:r&&es(Cs(r),{initialization:Cs(a)})};return Object.keys(s).forEach(function(e){s[e]||delete s[e]}),s}function xs(u,l,c){return function(e){var t=Cs(e),i=ws(l,Ss(e,"BaseURL")),n=Ss(e,"Role")[0],n={role:Cs(n)},t=es(u,t,n),n=Ss(e,"Accessibility")[0],n="urn:scte:dash:cc:cea-608:2015"===(n=Cs(n)).schemeIdUri?n.value.split(";").map(function(e){var t,i,n;return/^CC\d=/.test(n=e)?(i=(t=e.split("="))[0],n=t[1]):/^CC\d$/.test(e)&&(i=e),{channel:i,language:n}}):"urn:scte:dash:cc:cea-708:2015"===n.schemeIdUri?n.value.split(";").map(function(e){var t,i,n={channel:void 0,language:void 0,aspectRatio:1,easyReader:0,"3D":0};return/=/.test(e)?(t=(i=e.split("="))[0],i=void 0===(i=i[1])?"":i,n.channel=t,n.language=e,i.split(",").forEach(function(e){var t=e.split(":"),e=t[0],t=t[1];"lang"===e?n.language=t:"er"===e?n.easyReader=Number(t):"war"===e?n.aspectRatio=Number(t):"3D"===e&&(n["3D"]=Number(t))})):n.language=e,n.channel&&(n.channel="SERVICE"+n.channel),n}):void 0;n&&(t=es(t,{captionServices:n}));n=Ss(e,"Label")[0];n&&n.childNodes.length&&(r=n.childNodes[0].nodeValue.trim(),t=es(t,{label:r}));var r=Ss(e,"ContentProtection").reduce(function(e,t){var i=Cs(t),n=eo[i.schemeIdUri];return n&&(e[n]={attributes:i},(t=Ss(t,"cenc:pssh")[0])&&(t=(t=Es(t))&&ur(t),e[n].pssh=t)),e},{});Object.keys(r).length&&(t=es(t,{contentProtection:r}));var a,s,o,r=Is(e),e=Ss(e,"Representation"),r=es(c,r);return ts(e.map((a=t,s=i,o=r,function(e){var t=Ss(e,"BaseURL"),t=ws(s,t),i=es(a,Cs(e)),n=Is(e);return t.map(function(e){return{segmentInfo:es(o,n),attributes:es(i,{baseUrl:e})}})})))}}function As(e,t){var i=t=void 0===t?{}:t,n=void 0===(a=i.manifestUri)?"":a,t=void 0===(r=i.NOW)?Date.now():r,r=void 0===(a=i.clientOffset)?0:a;if(!(i=Ss(e,"Period")).length)throw new Error(zs);var a=Ss(e,"Location"),s=Cs(e),e=ws([n],Ss(e,"BaseURL"));s.type=s.type||"static",s.sourceDuration=s.mediaPresentationDuration||0,s.NOW=t,s.clientOffset=r,a.length&&(s.locations=a.map(Es));var o,u,l=[];return i.forEach(function(e,t){var i,n=Cs(e),r=l[t-1];n.start=(i={attributes:n,priorPeriodAttributes:r?r.attributes:null,mpdType:s.type},t=i.attributes,r=i.priorPeriodAttributes,i=i.mpdType,"number"==typeof t.start?t.start:r&&"number"==typeof r.start&&"number"==typeof r.duration?r.start+r.duration:r||"static"!==i?null:0),l.push({node:e,attributes:n})}),{locations:s.locations,representationInfo:ts(l.map((o=s,u=e,function(e,t){var i=ws(u,Ss(e.node,"BaseURL")),n=parseInt(e.attributes.id,10),t=_.isNaN(n)?t:n,n=es(o,{periodIndex:t,periodStart:e.attributes.start});"number"==typeof e.attributes.duration&&(n.periodDuration=e.attributes.duration);t=Ss(e.node,"AdaptationSet"),e=Is(e.node);return ts(t.map(xs(n,i,e)))})))}}function Ps(e){if(""===e)throw new Error(Gs);var t,i,n=new Ja;try{i=(t=n.parseFromString(e,"application/xml"))&&"MPD"===t.documentElement.tagName?t.documentElement:null}catch(e){}if(!i||i&&0<i.getElementsByTagName("parsererror").length)throw new Error(Xs);return i}function Ls(e,t){void 0===t&&(t={});var i=As(Ps(e),t),e=i.representationInfo.map(Ts);return gs(e,i.locations,t.sidxMapping)}function Ds(e){return function(e){e=Ss(e,"UTCTiming")[0];if(!e)return null;var t=Cs(e);switch(t.schemeIdUri){case"urn:mpeg:dash:utc:http-head:2014":case"urn:mpeg:dash:utc:http-head:2012":t.method="HEAD";break;case"urn:mpeg:dash:utc:http-xsdate:2014":case"urn:mpeg:dash:utc:http-iso:2014":case"urn:mpeg:dash:utc:http-xsdate:2012":case"urn:mpeg:dash:utc:http-iso:2012":t.method="GET";break;case"urn:mpeg:dash:utc:direct:2014":case"urn:mpeg:dash:utc:direct:2012":t.method="DIRECT",t.value=Date.parse(t.value);break;case"urn:mpeg:dash:utc:http-ntp:2014":case"urn:mpeg:dash:utc:ntp:2014":case"urn:mpeg:dash:utc:sntp:2014":default:throw new Error(Qs)}return t}(Ps(e))}function Os(e){return e instanceof Uint8Array?e:(Array.isArray(e)||(t=e,ArrayBuffer.isView(t))||e instanceof ArrayBuffer||(e="number"!=typeof e||"number"==typeof e&&e!=e?0:[e]),new Uint8Array(e&&e.buffer||e,e&&e.byteOffset||0,e&&e.byteLength||0));var t}function Rs(e,t){var i=void 0!==(t=(void 0===t?{}:t).le)&&t;e=no(e="bigint"!=typeof e&&"number"!=typeof e||"number"==typeof e&&e!=e?0:e);for(var n=(t=e,Math.ceil(t.toString(2).length/8)),r=new Uint8Array(new ArrayBuffer(n)),a=0;a<n;a++){var s=i?a:Math.abs(a+1-r.length);r[s]=Number(e/ro[a]&no(255)),e<0&&(r[s]=Math.abs(~r[s]),r[s]-=0===a?1:2)}return r}function Ms(e,t){if("string"!=typeof(e="string"!=typeof e&&e&&"function"==typeof e.toString?e.toString():e))return new Uint8Array;t||(e=unescape(encodeURIComponent(e)));for(var i=new Uint8Array(e.length),n=0;n<e.length;n++)i[n]=e.charCodeAt(n);return i}function Ns(i,e,t){var n=void 0===t?{}:t,r=void 0===(t=n.offset)?0:t,a=void 0===(n=n.mask)?[]:n;return i=Os(i),n=(e=Os(e)).every||Array.prototype.every,e.length&&i.length-r>=e.length&&n.call(e,function(e,t){return e===(a[t]?a[t]&i[r+t]:i[r+t])})}function Us(e,t){return void 0===t&&(t=0),(e=Os(e)).length-t<10||!Ns(e,ao,{offset:t})?t:Us(e,t+=function(e,t){void 0===t&&(t=0);var i=(e=Os(e))[t+5],t=e[t+6]<<21|e[t+7]<<14|e[t+8]<<7|e[t+9];return(16&i)>>4?20+t:10+t}(e,t))}function Bs(e){return"string"==typeof e?Ms(e):e}function Fs(e,t,i){var n;void 0===i&&(i=!1),n=t,t=Array.isArray(n)?n.map(Bs):[Bs(n)],e=Os(e);var r=[];if(!t.length)return r;for(var a=0;a<e.length;){var s=(e[a]<<24|e[a+1]<<16|e[a+2]<<8|e[a+3])>>>0,o=e.subarray(a+4,a+8);if(0==s)break;var u=a+s;if(u>e.length){if(i)break;u=e.length}s=e.subarray(a+8,u);Ns(o,t[0])&&(1===t.length?r.push(s):r.push.apply(r,Fs(s,t.slice(1),i))),a=u}return r}function js(e,t,i,n){void 0===i&&(i=!0),void 0===n&&(n=!1);var r=function(e){for(var t=1,i=0;i<oo.length&&!(e&oo[i]);i++)t++;return t}(e[t]),a=e.subarray(t,t+r);return i&&((a=Array.prototype.slice.call(e,t,t+r))[0]^=oo[r-1]),{length:r,value:function(n,e){var t=void 0===e?{}:e,e=t.signed,e=void 0!==e&&e,t=t.le,r=void 0!==t&&t;n=Os(n);t=r?"reduce":"reduceRight",t=(n[t]||Array.prototype[t]).call(n,function(e,t,i){i=r?i:Math.abs(i+1-n.length);return e+no(t)*ro[i]},no(0));return!e||(e=ro[n.length]/no(2)-no(1))<(t=no(t))&&(t-=e,t-=e,t-=no(2)),Number(t)}(a,{signed:n}),bytes:a}}function Hs(e){return"string"==typeof e?e.match(/.{1,2}/g).map(Hs):"number"==typeof e?Rs(e):e}function qs(e,t,i){if(i>=t.length)return t.length;var n=js(t,i,!1);if(Ns(e.bytes,n.bytes))return i;var r=js(t,i+n.length);return qs(e,t,i+r.length+r.value+n.length)}function Vs(e,t){var i;i=t,t=Array.isArray(i)?i.map(Hs):[Hs(i)],e=Os(e);var n=[];if(!t.length)return n;for(var r=0;r<e.length;){var a=js(e,r,!1),s=js(e,r+a.length),o=r+a.length+s.length;127===s.value&&(s.value=qs(a,e,o),s.value!==e.length&&(s.value-=o));var u=o+s.value>e.length?e.length:o+s.value,u=e.subarray(o,u);Ns(t[0],a.bytes)&&(1===t.length?n.push(u):n=n.concat(Vs(u,t.slice(1)))),r+=a.length+s.length+u.length}return n}function Ws(e,t,i,n){void 0===n&&(n=1/0),e=Os(e),i=[].concat(i);for(var r,a=0,s=0;a<e.length&&(s<n||r);){var o=void 0;if(Ns(e.subarray(a),uo)?o=4:Ns(e.subarray(a),lo)&&(o=3),o){if(s++,r)return function(e){for(var t=[],i=1;i<e.length-2;)Ns(e.subarray(i,i+3),co)&&(t.push(i+2),i++),i++;if(0===t.length)return e;for(var n=e.length-t.length,r=new Uint8Array(n),a=0,i=0;i<n;a++,i++)a===t[0]&&(a++,t.shift()),r[i]=e[a];return r}(e.subarray(r,a));var u=void 0;"h264"===t?u=31&e[a+o]:"h265"===t&&(u=e[a+o]>>1&63),-1!==i.indexOf(u)&&(r=a+o),a+=o+("h264"===t?1:2)}else a++}return e.subarray(0,0)}
+/*! @name mpd-parser @version 0.19.0 @license Apache-2.0 */
+var zs="INVALID_NUMBER_OF_PERIOD",Gs="DASH_EMPTY_MANIFEST",Xs="DASH_INVALID_XML",Ks="NO_BASE_URL",Ys="SEGMENT_TIME_UNSPECIFIED",Qs="UNSUPPORTED_UTC_TIMING_SCHEME",$s={static:function(e){var t=e.duration,i=e.timescale,n=void 0===i?1:i,r=e.sourceDuration,i=e.periodDuration,e=rs(e.endNumber),n=t/n;return"number"==typeof e?{start:0,end:e}:"number"==typeof i?{start:0,end:i/n}:{start:0,end:r/n}},dynamic:function(e){var t=e.NOW,i=e.clientOffset,n=e.availabilityStartTime,r=e.timescale,a=void 0===r?1:r,s=e.duration,o=e.start,u=void 0===o?0:o,r=e.minimumUpdatePeriod,o=void 0===r?0:r,r=e.timeShiftBufferDepth,r=void 0===r?1/0:r,e=rs(e.endNumber),i=(t+i)/1e3,u=n+u,o=Math.ceil((i+o-u)*a/s),r=Math.floor((i-u-r)*a/s),s=Math.floor((i-u)*a/s);return{start:Math.max(0,r),end:"number"==typeof e?e:Math.min(o,s)}}},Js=/\$([A-z]*)(?:(%0)([0-9]+)d)?\$/g,Zs={mediaPresentationDuration:ks,availabilityStartTime:function(e){return/^\d+-\d+-\d+T\d+:\d+:\d+(\.\d+)?$/.test(e=e)&&(e+="Z"),Date.parse(e)/1e3},minimumUpdatePeriod:ks,suggestedPresentationDelay:ks,type:function(e){return e},timeShiftBufferDepth:ks,start:ks,width:function(e){return parseInt(e,10)},height:function(e){return parseInt(e,10)},bandwidth:function(e){return parseInt(e,10)},startNumber:function(e){return parseInt(e,10)},timescale:function(e){return parseInt(e,10)},presentationTimeOffset:function(e){return parseInt(e,10)},duration:function(e){var t=parseInt(e,10);return isNaN(t)?ks(e):t},d:function(e){return parseInt(e,10)},t:function(e){return parseInt(e,10)},r:function(e){return parseInt(e,10)},DEFAULT:function(e){return e}},eo={"urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b":"org.w3.clearkey","urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":"com.widevine.alpha","urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95":"com.microsoft.playready","urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb":"com.adobe.primetime"},to=Math.pow(2,32),io=function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i={version:e[0],flags:new Uint8Array(e.subarray(1,4)),references:[],referenceId:t.getUint32(4),timescale:t.getUint32(8)},n=12;0===i.version?(i.earliestPresentationTime=t.getUint32(n),i.firstOffset=t.getUint32(n+4),n+=8):(i.earliestPresentationTime=t.getUint32(n)*to+t.getUint32(n+4),i.firstOffset=t.getUint32(n+8)*to+t.getUint32(n+12),n+=16);var r=t.getUint16(n+=2);for(n+=2;0<r;n+=12,r--)i.references.push({referenceType:(128&e[n])>>>7,referencedSize:2147483647&t.getUint32(n),subsegmentDuration:t.getUint32(n+4),startsWithSap:!!(128&e[n+8]),sapType:(112&e[n+8])>>>4,sapDeltaTime:268435455&t.getUint32(n+8)});return i},no=_.BigInt||Number,ro=[no("0x1"),no("0x100"),no("0x10000"),no("0x1000000"),no("0x100000000"),no("0x10000000000"),no("0x1000000000000"),no("0x100000000000000"),no("0x10000000000000000")],ao=Os([73,68,51]),so={EBML:Os([26,69,223,163]),DocType:Os([66,130]),Segment:Os([24,83,128,103]),SegmentInfo:Os([21,73,169,102]),Tracks:Os([22,84,174,107]),Track:Os([174]),TrackNumber:Os([215]),DefaultDuration:Os([35,227,131]),TrackEntry:Os([174]),TrackType:Os([131]),FlagDefault:Os([136]),CodecID:Os([134]),CodecPrivate:Os([99,162]),VideoTrack:Os([224]),AudioTrack:Os([225]),Cluster:Os([31,67,182,117]),Timestamp:Os([231]),TimestampScale:Os([42,215,177]),BlockGroup:Os([160]),BlockDuration:Os([155]),Block:Os([161]),SimpleBlock:Os([163])},oo=[128,64,32,16,8,4,2,1],uo=Os([0,0,0,1]),lo=Os([0,0,1]),co=Os([0,0,3]),ho={webm:Os([119,101,98,109]),matroska:Os([109,97,116,114,111,115,107,97]),flac:Os([102,76,97,67]),ogg:Os([79,103,103,83]),ac3:Os([11,119]),riff:Os([82,73,70,70]),avi:Os([65,86,73]),wav:Os([87,65,86,69]),"3gp":Os([102,116,121,112,51,103]),mp4:Os([102,116,121,112]),fmp4:Os([115,116,121,112]),mov:Os([102,116,121,112,113,116]),moov:Os([109,111,111,118]),moof:Os([109,111,111,102])},po={aac:function(e){var t=Us(e);return Ns(e,[255,16],{offset:t,mask:[255,22]})},mp3:function(e){var t=Us(e);return Ns(e,[255,2],{offset:t,mask:[255,6]})},webm:function(e){e=Vs(e,[so.EBML,so.DocType])[0];return Ns(e,ho.webm)},mkv:function(e){e=Vs(e,[so.EBML,so.DocType])[0];return Ns(e,ho.matroska)},mp4:function(e){return!po["3gp"](e)&&!po.mov(e)&&(!(!Ns(e,ho.mp4,{offset:4})&&!Ns(e,ho.fmp4,{offset:4}))||(!(!Ns(e,ho.moof,{offset:4})&&!Ns(e,ho.moov,{offset:4}))||void 0))},mov:function(e){return Ns(e,ho.mov,{offset:4})},"3gp":function(e){return Ns(e,ho["3gp"],{offset:4})},ac3:function(e){var t=Us(e);return Ns(e,ho.ac3,{offset:t})},ts:function(e){if(e.length<189&&1<=e.length)return 71===e[0];for(var t=0;t+188<e.length&&t<188;){if(71===e[t]&&71===e[t+188])return!0;t+=1}return!1},flac:function(e){var t=Us(e);return Ns(e,ho.flac,{offset:t})},ogg:function(e){return Ns(e,ho.ogg)},avi:function(e){return Ns(e,ho.riff)&&Ns(e,ho.avi,{offset:8})},wav:function(e){return Ns(e,ho.riff)&&Ns(e,ho.wav,{offset:8})},h264:function(e){return Ws(e,"h264",7,3).length},h265:function(e){return Ws(e,"h265",[32,33],3).length}},fo=Object.keys(po).filter(function(e){return"ts"!==e&&"h264"!==e&&"h265"!==e}).concat(["ts","h264","h265"]);fo.forEach(function(e){var t=po[e];po[e]=function(e){return t(Os(e))}});function mo(e){e=Os(e);for(var t=0;t<fo.length;t++){var i=fo[t];if(zu[i](e))return i}return""}function go(e,t,i){return e&&i&&i.responseURL&&t!==i.responseURL?i.responseURL:t}function yo(e){return ir.log.debug?ir.log.debug.bind(ir,"VHS:",e+" >"):function(){}}function vo(e,t){var i,n=[];if(e&&e.length)for(i=0;i<e.length;i++)t(e.start(i),e.end(i))&&n.push([e.start(i),e.end(i)]);return ir.createTimeRanges(n)}function _o(e,i){return vo(e,function(e,t){return e-.1<=i&&i<=t+.1})}function bo(e,t){return vo(e,function(e){return t<=e-Ku})}function To(e){var t=[];if(!e||!e.length)return"";for(var i=0;i<e.length;i++)t.push(e.start(i)+" => "+e.end(i));return t.join(", ")}function So(e){for(var t=[],i=0;i<e.length;i++)t.push({start:e.start(i),end:e.end(i)});return t}function Eo(e){if(e&&e.length&&e.end)return e.end(e.length-1)}function ko(e){return(e.segments||[]).reduce(function(i,n,r){return n.parts?n.parts.forEach(function(e,t){i.push({duration:e.duration,segmentIndex:r,partIndex:t,part:e,segment:n})}):i.push({duration:n.duration,segmentIndex:r,partIndex:null,segment:n,part:null}),i},[])}function Co(e){return(e=e.segments&&e.segments.length&&e.segments[e.segments.length-1])&&e.parts||[]}function wo(e){var t=e.preloadSegment;if(t){e=t.parts,t=(t.preloadHints||[]).reduce(function(e,t){return e+("PART"===t.type?1:0)},0);return t+=e&&e.length?e.length:0}}function Io(e,t){return t.endList?0:e&&e.suggestedPresentationDelay?e.suggestedPresentationDelay:(e=0<Co(t).length)&&t.serverControl&&t.serverControl.partHoldBack?t.serverControl.partHoldBack:e&&t.partTargetDuration?3*t.partTargetDuration:t.serverControl&&t.serverControl.holdBack?t.serverControl.holdBack:t.targetDuration?3*t.targetDuration:0}function xo(e,t,i){if((t="undefined"==typeof t?e.mediaSequence+e.segments.length:t)<e.mediaSequence)return 0;var n=function(e,t){var i=0,n=t-e.mediaSequence,r=e.segments[n];if(r){if("undefined"!=typeof r.start)return{result:r.start,precise:!0};if("undefined"!=typeof r.end)return{result:r.end-r.duration,precise:!0}}for(;n--;){if("undefined"!=typeof(r=e.segments[n]).end)return{result:i+r.end,precise:!0};if(i+=r.duration,"undefined"!=typeof r.start)return{result:i+r.start,precise:!0}}return{result:i,precise:!1}}(e,t);return n.precise?n.result:(t=function(e,t){for(var i,n=0,r=t-e.mediaSequence;r<e.segments.length;r++){if("undefined"!=typeof(i=e.segments[r]).start)return{result:i.start-n,precise:!0};if(n+=i.duration,"undefined"!=typeof i.end)return{result:i.end-n,precise:!0}}return{result:-1,precise:!1}}(e,t)).precise?t.result:n.result+i}function Ao(e,t,i){if(!e)return 0;if("undefined"==typeof t){if(e.totalDuration)return e.totalDuration;if(!e.endList)return _.Infinity}return xo(e,t,i="number"!=typeof i?0:i)}function Po(e){var t=e.defaultDuration,i=e.durationList,n=e.startIndex,r=e.endIndex,a=0;if(r<n&&(n=(e=[r,n])[0],r=e[1]),n<0){for(var s=n;s<Math.min(0,r);s++)a+=t;n=0}for(var o=n;o<r;o++)a+=i[o].duration;return a}function Lo(e,t,i,n){return e&&e.segments?e.endList?Ao(e):null===t?null:(t=xo(e,e.mediaSequence+e.segments.length,t=t||0),i&&(t-=n="number"==typeof n?n:Io(null,e)),Math.max(0,t)):null}function Do(e){return e.excludeUntil&&e.excludeUntil>Date.now()}function Oo(e){return e.excludeUntil&&e.excludeUntil===1/0}function Ro(e){var t=Do(e);return!e.disabled&&!t}function Mo(e,t){return t.attributes&&t.attributes[e]}function No(e,t){if(1===e.playlists.length)return!0;var i=t.attributes.BANDWIDTH||Number.MAX_VALUE;return 0===e.playlists.filter(function(e){return!!Ro(e)&&(e.attributes.BANDWIDTH||0)<i}).length}function Uo(e,t){return!(!e&&!t||!e&&t||e&&!t)&&(e===t||(!(!e.id||!t.id||e.id!==t.id)||(!(!e.resolvedUri||!t.resolvedUri||e.resolvedUri!==t.resolvedUri)||!(!e.uri||!t.uri||e.uri!==t.uri))))}function Bo(e,t){var i,n=e&&e.mediaGroups&&e.mediaGroups.AUDIO||{},r=!1;for(i in n){for(var a in n[i])if(r=t(n[i][a]))break;if(r)break}return!!r}function Fo(i){if(!i||!i.playlists||!i.playlists.length)return Bo(i,function(e){return e.playlists&&e.playlists.length||e.uri});for(var e=0;e<i.playlists.length;e++){var t=function(e){var t=i.playlists[e],e=t.attributes&&t.attributes.CODECS;return e&&e.split(",").every(mr)||Bo(i,function(e){return Uo(t,e)})?"continue":{v:!1}}(e);if("continue"!==t&&"object"==typeof t)return t.v}return!0}function jo(e,t){return e+"-"+t}function Ho(r,a){r.mediaGroups&&["AUDIO","SUBTITLES"].forEach(function(e){if(r.mediaGroups[e])for(var t in r.mediaGroups[e])for(var i in r.mediaGroups[e][t]){var n=r.mediaGroups[e][t][i];a(n,e,t,i)}})}function qo(e){var t=e.playlist,i=e.uri,e=e.id;t.id=e,t.playlistErrors_=0,i&&(t.uri=i),t.attributes=t.attributes||{}}function Vo(o,e){o.uri=e;for(var t=0;t<o.playlists.length;t++)o.playlists[t].uri||(o.playlists[t].uri="placeholder-uri-"+t);var i,u=Fo(o);Ho(o,function(e,t,i,n){var r="placeholder-uri-"+t+"-"+i+"-"+n;if(!e.playlists||!e.playlists.length){if(u&&"AUDIO"===t&&!e.uri)for(var a=0;a<o.playlists.length;a++){var s=o.playlists[a];if(s.attributes&&s.attributes.AUDIO&&s.attributes.AUDIO===i)return}e.playlists=[b({},e)]}e.playlists.forEach(function(e,t){var i=jo(t,r);e.uri?e.resolvedUri=e.resolvedUri||Xu(o.uri,e.uri):(e.uri=0===t?r:i,e.resolvedUri=e.uri),e.id=e.id||i,e.attributes=e.attributes||{},o.playlists[e.id]=e,o.playlists[e.uri]=e})}),function(e){for(var t=e.playlists.length;t--;){var i=e.playlists[t];qo({playlist:i,id:jo(t,i.uri)}),i.resolvedUri=Xu(e.uri,i.uri),e.playlists[i.id]=i,(e.playlists[i.uri]=i).attributes.BANDWIDTH||$u.warn("Invalid playlist STREAM-INF detected. Missing BANDWIDTH attribute.")}}(o),Ho(i=o,function(e){e.uri&&(e.resolvedUri=Xu(i.uri,e.uri))})}function Wo(e,t,i){var n=e.slice(),r=t.slice();i=i||0;for(var a,s=[],o=0;o<r.length;o++){var u=n[o+i],l=r[o];u?(a=u.map||a,s.push(function(e,t){if(!e)return t;var i=Ju(e,t);if(e.preloadHints&&!t.preloadHints&&delete i.preloadHints,e.parts&&!t.parts)delete i.parts;else if(e.parts&&t.parts)for(var n=0;n<t.parts.length;n++)e.parts&&e.parts[n]&&(i.parts[n]=Ju(e.parts[n],t.parts[n]));return!e.skipped&&t.skipped&&(i.skipped=!1),e.preload&&!t.preload&&(i.preload=!1),i}(u,l))):(a&&!l.map&&(l.map=a),s.push(l))}return s}function zo(e,t){!e.resolvedUri&&e.uri&&(e.resolvedUri=Xu(t,e.uri)),e.key&&!e.key.resolvedUri&&(e.key.resolvedUri=Xu(t,e.key.uri)),e.map&&!e.map.resolvedUri&&(e.map.resolvedUri=Xu(t,e.map.uri)),e.map&&e.map.key&&!e.map.key.resolvedUri&&(e.map.key.resolvedUri=Xu(t,e.map.key.uri)),e.parts&&e.parts.length&&e.parts.forEach(function(e){e.resolvedUri||(e.resolvedUri=Xu(t,e.uri))}),e.preloadHints&&e.preloadHints.length&&e.preloadHints.forEach(function(e){e.resolvedUri||(e.resolvedUri=Xu(t,e.uri))})}function Go(e){var t=e.segments||[],i=e.preloadSegment;if(i&&i.parts&&i.parts.length){if(i.preloadHints)for(var n=0;n<i.preloadHints.length;n++)if("MAP"===i.preloadHints[n].type)return t;i.duration=e.targetDuration,i.preload=!0,t.push(i)}return t}function Xo(e,t){return e===t||e.segments&&t.segments&&e.segments.length===t.segments.length&&e.endList===t.endList&&e.mediaSequence===t.mediaSequence}function Ko(e,a,t){void 0===t&&(t=Xo);var i=Ju(e,{}),n=i.playlists[a.id];if(!n)return null;if(t(n,a))return null;a.segments=Go(a);var r=Ju(n,a);if(r.preloadSegment&&!a.preloadSegment&&delete r.preloadSegment,n.segments){if(a.skip){a.segments=a.segments||[];for(var s=0;s<a.skip.skippedSegments;s++)a.segments.unshift({skipped:!0})}r.segments=Wo(n.segments,a.segments,a.mediaSequence-n.mediaSequence)}r.segments.forEach(function(e){zo(e,r.resolvedUri)});for(var o=0;o<i.playlists.length;o++)i.playlists[o].id===a.id&&(i.playlists[o]=r);return i.playlists[a.id]=r,i.playlists[a.uri]=r,Ho(e,function(e,t,i,n){if(e.playlists)for(var r=0;r<e.playlists.length;r++)a.id===e.playlists[r].id&&(e.playlists[r]=a)}),i}function Yo(e,t){var i=(n=e.segments[e.segments.length-1])&&n.parts&&n.parts[n.parts.length-1],n=i&&i.duration||n&&n.duration;return t&&n?1e3*n:500*(e.partTargetDuration||e.targetDuration||10)}function Qo(e,t,i,n){var r="arraybuffer"===e.responseType?e.response:e.responseText;!t&&r&&(e.responseTime=Date.now(),e.roundTripTime=e.responseTime-e.requestTime,e.bytesReceived=r.byteLength||r.length,e.bandwidth||(e.bandwidth=Math.floor(e.bytesReceived/e.roundTripTime*8*1e3))),i.headers&&(e.responseHeaders=i.headers),t&&"ETIMEDOUT"===t.code&&(e.timedout=!0),n(t=!t&&!e.aborted&&200!==i.statusCode&&206!==i.statusCode&&0!==i.statusCode?new Error("XHR Failed with a response of: "+(e&&(r||e.responseText))):t,e)}function $o(){function a(e,i){e=tl({timeout:45e3},e);var t=a.beforeRequest||ir.Vhs.xhr.beforeRequest;!t||"function"!=typeof t||(t=t(e))&&(e=t);var n=(!0===ir.Vhs.xhr.original?el:ir.Vhs.xhr)(e,function(e,t){return Qo(n,e,t,i)}),r=n.abort;return n.abort=function(){return n.aborted=!0,r.apply(n,arguments)},n.uri=e.uri,n.requestTime=Date.now(),n}return a.original=!0,a}function Jo(e){var t,i={};return e.byterange&&(i.Range=(t=e.byterange,e=t.offset+t.length-1,"bytes="+t.offset+"-"+e)),i}function Zo(e,t){return e=e.toString(16),"00".substring(0,2-e.length)+e+(t%2?" ":"")}function eu(e){return 32<=e&&e<126?String.fromCharCode(e):"."}function tu(i){var n={};return Object.keys(i).forEach(function(e){var t=i[e];ArrayBuffer.isView(t)?n[e]={bytes:t.buffer,byteOffset:t.byteOffset,byteLength:t.byteLength}:n[e]=t}),n}function iu(e){var t=e.byterange||{length:1/0,offset:0};return[t.length,t.offset,e.resolvedUri].join(",")}function nu(e){return e.resolvedUri}function ru(e){for(var t=Array.prototype.slice.call(e),i="",n=0;n<t.length/16;n++)i+=t.slice(16*n,16*n+16).map(Zo).join("")+" "+t.slice(16*n,16*n+16).map(eu).join("")+"\n";return i}function au(e){var t=e.playlist,i=e.time,n=void 0===i?void 0:i;if(!(i=e.callback))throw new Error("getProgramTime: callback must be provided");return t&&void 0!==n?(e=function(e,t){if(!t||!t.segments||0===t.segments.length)return null;for(var i,n=0,r=0;r<t.segments.length&&!(e<=(n=(i=t.segments[r]).videoTimingInfo?i.videoTimingInfo.transmuxedPresentationEnd:n+i.duration));r++);var a=t.segments[t.segments.length-1];if(a.videoTimingInfo&&a.videoTimingInfo.transmuxedPresentationEnd<e)return null;if(n<e){if(e>n+.25*a.duration)return null;i=a}return{segment:i,estimatedStart:i.videoTimingInfo?i.videoTimingInfo.transmuxedPresentationStart:n-i.duration,type:i.videoTimingInfo?"accurate":"estimate"}}(n,t))?"estimate"===e.type?i({message:"Accurate programTime could not be determined. Please seek to e.seekTime and try again",seekTime:e.estimatedStart}):(t={mediaSeconds:n},(e=function(e,t){if(!t.dateTimeObject)return null;var i=t.videoTimingInfo.transmuxerPrependedSeconds,i=e-(t.videoTimingInfo.transmuxedPresentationStart+i);return new Date(t.dateTimeObject.getTime()+1e3*i)}(n,e.segment))&&(t.programDateTime=e.toISOString()),i(null,t)):i({message:"valid programTime was not found"}):i({message:"getProgramTime: playlist and time must be provided"})}function su(e){var t=e.programTime,i=e.playlist,n=e.retryCount,r=void 0===n?2:n,a=e.seekTo,s=e.pauseAfterSeek,o=void 0===s||s,u=e.tech,l=e.callback;if(!l)throw new Error("seekToProgramTime: callback must be provided");return"undefined"!=typeof t&&i&&a?i.endList||u.hasStarted_?function(e){if(!e.segments||0===e.segments.length)return!1;for(var t=0;t<e.segments.length;t++)if(!e.segments[t].dateTimeObject)return!1;return!0}(i)?(n=function(e,t){var i;try{i=new Date(e)}catch(e){return null}if(!t||!t.segments||0===t.segments.length)return null;if(i<(r=t.segments[0]).dateTimeObject)return null;for(var n=0;n<t.segments.length-1;n++){var r=t.segments[n];if(i<t.segments[n+1].dateTimeObject)break}var a,s=t.segments[t.segments.length-1],e=s.dateTimeObject,a=s.videoTimingInfo?(a=s.videoTimingInfo).transmuxedPresentationEnd-a.transmuxedPresentationStart-a.transmuxerPrependedSeconds:s.duration+.25*s.duration;return new Date(e.getTime()+1e3*a)<i?null:{segment:r=e<i?s:r,estimatedStart:r.videoTimingInfo?r.videoTimingInfo.transmuxedPresentationStart:Qu.duration(t,t.mediaSequence+t.segments.indexOf(r)),type:r.videoTimingInfo?"accurate":"estimate"}}(t,i))?(s=n.segment,e=function(e,t){var i;try{n=new Date(e),i=new Date(t)}catch(e){}var n=n.getTime();return(i.getTime()-n)/1e3}(s.dateTimeObject,t),"estimate"===n.type?0===r?l({message:t+" is not buffered yet. Try again"}):(a(n.estimatedStart+e),void u.one("seeked",function(){su({programTime:t,playlist:i,retryCount:r-1,seekTo:a,pauseAfterSeek:o,tech:u,callback:l})})):(e=s.start+e,u.one("seeked",function(){return l(null,u.currentTime())}),o&&u.pause(),void a(e))):l({message:t+" was not found in the stream"}):l({message:"programDateTime tags must be provided in the manifest "+i.resolvedUri}):l({message:"player must be playing a live stream to start buffering"}):l({message:"seekToProgramTime: programTime, seekTo and playlist must be provided"})}function ou(e,t){if(4===e.readyState)return t()}function uu(e,t,r){function n(e,t,i,n){return t.abort(),o=!0,r(e,t,i,n)}function i(e,t){if(!o){if(e)return n(e,t,"",s);var i=t.responseText.substring(s&&s.byteLength||0,t.responseText.length);if(s=function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];if((t=t.filter(function(e){return e&&(e.byteLength||e.length)&&"string"!=typeof e})).length<=1)return Os(t[0]);var n=t.reduce(function(e,t,i){return e+(t.byteLength||t.length)},0),r=new Uint8Array(n),a=0;return t.forEach(function(e){e=Os(e),r.set(e,a),a+=e.byteLength}),r}(s,Ms(i,!0)),a=a||Us(s),s.length<10||a&&s.length<a+2)return ou(t,function(){return n(e,t,"",s)});i=mo(s);return"ts"===i&&s.length<188||!i&&s.length<376?ou(t,function(){return n(e,t,"",s)}):n(null,t,i,s)}}var a,s=[],o=!1,u=t({uri:e,beforeSend:function(t){t.overrideMimeType("text/plain; charset=x-user-defined"),t.addEventListener("progress",function(e){return e.total,e.loaded,Qo(t,null,{statusCode:t.status},i)})}},function(e,t){return Qo(u,e,t,i)});return u}function lu(e,t){if(!Xo(e,t))return!1;if(e.sidx&&t.sidx&&(e.sidx.offset!==t.sidx.offset||e.sidx.length!==t.sidx.length))return!1;if(!e.sidx&&t.sidx||e.sidx&&!t.sidx)return!1;if(e.segments&&!t.segments||!e.segments&&t.segments)return!1;if(!e.segments&&!t.segments)return!0;for(var i=0;i<e.segments.length;i++){var n=e.segments[i],r=t.segments[i];if(n.uri!==r.uri)return!1;if(n.byterange||r.byterange){n=n.byterange,r=r.byterange;if(n&&!r||!n&&r)return!1;if(n.offset!==r.offset||n.length!==r.length)return!1}}return!0}function cu(e,t){var i,n={};for(i in e){var r=e[i].sidx;if(r){var a=us(r);if(!t[a])break;var s=t[a].sidxInfo;s=s,r=r,(Boolean(!s.map&&!r.map)||Boolean(s.map&&r.map&&s.map.byterange.offset===r.map.byterange.offset&&s.map.byterange.length===r.map.byterange.length))&&s.uri===r.uri&&s.byterange.offset===r.byterange.offset&&s.byterange.length===r.byterange.length&&(n[a]=t[a])}}return n}function du(e){return e.on=e.addEventListener,e.off=e.removeEventListener,e}function hu(i){var n=i.transmuxer,e=i.bytes,t=i.audioAppendStart,r=i.gopsToAlignWith,a=i.remux,s=i.onData,o=i.onTrackInfo,u=i.onAudioTimingInfo,l=i.onVideoTimingInfo,c=i.onVideoSegmentTimingInfo,d=i.onAudioSegmentTimingInfo,h=i.onId3,p=i.onCaptions,f=i.onDone,m=i.onEndedTimeline,g=i.onTransmuxerLog,y=i.isEndOfTimeline,v={buffer:[]},_=y;n.onmessage=function(e){var t;n.currentTransmux===i&&("data"===e.data.action&&function(e,t,i){var n=e.data.segment,r=n.type,a=n.initSegment,s=n.captions,o=n.captionStreams,u=n.metadata,l=n.videoFrameDtsTime,n=n.videoFramePtsTime;t.buffer.push({captions:s,captionStreams:o,metadata:u});e=e.data.segment.boxes||{data:e.data.segment.data},a={type:r,data:new Uint8Array(e.data,e.data.byteOffset,e.data.byteLength),initSegment:new Uint8Array(a.data,a.byteOffset,a.byteLength)};"undefined"!=typeof l&&(a.videoFrameDtsTime=l),"undefined"!=typeof n&&(a.videoFramePtsTime=n),i(a)}(e,v,s),"trackinfo"===e.data.action&&o(e.data.trackInfo),"gopInfo"===e.data.action&&(v.gopInfo=e.data.gopInfo),"audioTimingInfo"===e.data.action&&u(e.data.audioTimingInfo),"videoTimingInfo"===e.data.action&&l(e.data.videoTimingInfo),"videoSegmentTimingInfo"===e.data.action&&c(e.data.videoSegmentTimingInfo),"audioSegmentTimingInfo"===e.data.action&&d(e.data.audioSegmentTimingInfo),"id3Frame"===e.data.action&&h([e.data.id3Frame],e.data.id3Frame.dispatchType),"caption"===e.data.action&&p(e.data.caption),"endedtimeline"===e.data.action&&(_=!1,m()),"log"===e.data.action&&g(e.data.log),"transmuxed"===e.data.type&&(_||(n.onmessage=null,e=(t={transmuxedData:v,callback:f}).transmuxedData,t=t.callback,e.buffer=[],t(e),sl(n))))},t&&n.postMessage({action:"setAudioAppendStart",appendStart:t}),Array.isArray(r)&&n.postMessage({action:"alignGopsWith",gopsToAlignWith:r}),"undefined"!=typeof a&&n.postMessage({action:"setRemux",remux:a}),e.byteLength&&(r=e instanceof ArrayBuffer?e:e.buffer,a=e instanceof ArrayBuffer?0:e.byteOffset,n.postMessage({action:"push",data:r,byteOffset:a,byteLength:e.byteLength},[r])),y&&n.postMessage({action:"endTimeline"}),n.postMessage({action:"flush"})}function pu(e,t){e.postMessage({action:t}),sl(e)}function fu(e,t){if(!t.currentTransmux)return t.currentTransmux=e,pu(t,e),0;t.transmuxQueue.push(pu.bind(null,t,e))}function mu(e){if(!e.transmuxer.currentTransmux)return e.transmuxer.currentTransmux=e,void hu(e);e.transmuxer.transmuxQueue.push(e)}function gu(i){var n=i.transmuxer,r=i.endAction||i.action,a=i.callback,e=b({},i,{endAction:null,transmuxer:null,callback:null}),t=function e(t){t.data.action===r&&(n.removeEventListener("message",e),t.data.data&&(t.data.data=new Uint8Array(t.data.data,i.byteOffset||0,i.byteLength||t.data.data.byteLength),i.data&&(i.data=t.data.data)),a(t.data))};n.addEventListener("message",t),i.data?(t=i.data instanceof ArrayBuffer,e.byteOffset=t?0:i.data.byteOffset,e.byteLength=i.data.byteLength,t=[t?i.data:i.data.buffer],n.postMessage(e,t)):n.postMessage(e)}function yu(e){e.forEach(function(e){e.abort()})}function vu(e,t){return t.timedout?{status:t.status,message:"HLS request timed-out at URL: "+t.uri,code:cl,xhr:t}:t.aborted?{status:t.status,message:"HLS request aborted at URL: "+t.uri,code:dl,xhr:t}:e?{status:t.status,message:"HLS request errored at URL: "+t.uri,code:ll,xhr:t}:"arraybuffer"===t.responseType&&0===t.response.byteLength?{status:t.status,message:"Empty HLS response at URL: "+t.uri,code:ll,xhr:t}:null}function _u(a,s,o){return function(e,t){var i=t.response,e=vu(e,t);if(e)return o(e,a);if(16!==i.byteLength)return o({status:t.status,message:"Invalid HLS key at URL: "+t.uri,code:ll,xhr:t},a);for(var i=new DataView(i),n=new Uint32Array([i.getUint32(0),i.getUint32(4),i.getUint32(8),i.getUint32(12)]),r=0;r<s.length;r++)s[r].bytes=n;return o(null,a)}}function bu(i,n){var e=mo(i.map.bytes);if("mp4"!==e){var t=i.map.resolvedUri||i.map.uri;return n({internal:!0,message:"Found unsupported "+(e||"unknown")+" container for initialization segment at URL: "+t,code:ll})}gu({action:"probeMp4Tracks",data:i.map.bytes,transmuxer:i.transmuxer,callback:function(e){var t=e.tracks,e=e.data;return i.map.bytes=e,t.forEach(function(e){i.map.tracks=i.map.tracks||{},i.map.tracks[e.type]||"number"==typeof(i.map.tracks[e.type]=e).id&&e.timescale&&(i.map.timescales=i.map.timescales||{},i.map.timescales[e.id]=e.timescale)}),n(null)}})}function Tu(e){var i=e.segment,n=e.finishProcessingFn,r=e.responseType;return function(e,t){e=vu(e,t);if(e)return n(e,i);e="arraybuffer"!==r&&t.responseText?function(e){for(var t=new Uint8Array(new ArrayBuffer(e.length)),i=0;i<e.length;i++)t[i]=e.charCodeAt(i);return t.buffer}(t.responseText.substring(i.lastReachedChar||0)):t.response;return i.stats={bandwidth:(t=t).bandwidth,bytesReceived:t.bytesReceived||0,roundTripTime:t.roundTripTime||0},i.key?i.encryptedBytes=new Uint8Array(e):i.bytes=new Uint8Array(e),n(null,i)}}function Su(e){var i=e.segment,t=e.bytes,n=e.trackInfoFn,r=e.timingInfoFn,a=e.videoSegmentTimingInfoFn,s=e.audioSegmentTimingInfoFn,o=e.id3Fn,u=e.captionsFn,l=e.isEndOfTimeline,c=e.endedTimelineFn,d=e.dataFn,h=e.doneFn,p=e.onTransmuxerLog,e=i.map&&i.map.tracks||{},f=Boolean(e.audio&&e.video),m=r.bind(null,i,"audio","start"),g=r.bind(null,i,"audio","end"),y=r.bind(null,i,"video","start"),v=r.bind(null,i,"video","end");gu({action:"probeTs",transmuxer:i.transmuxer,data:t,baseStartTime:i.baseStartTime,callback:function(e){i.bytes=t=e.data;e=e.result;e&&(n(i,{hasAudio:e.hasAudio,hasVideo:e.hasVideo,isMuxed:f}),n=null,e.hasAudio&&!f&&m(e.audioStart),e.hasVideo&&y(e.videoStart),y=m=null),mu({bytes:t,transmuxer:i.transmuxer,audioAppendStart:i.audioAppendStart,gopsToAlignWith:i.gopsToAlignWith,remux:f,onData:function(e){e.type="combined"===e.type?"video":e.type,d(i,e)},onTrackInfo:function(e){n&&(f&&(e.isMuxed=!0),n(i,e))},onAudioTimingInfo:function(e){m&&"undefined"!=typeof e.start&&(m(e.start),m=null),g&&"undefined"!=typeof e.end&&g(e.end)},onVideoTimingInfo:function(e){y&&"undefined"!=typeof e.start&&(y(e.start),y=null),v&&"undefined"!=typeof e.end&&v(e.end)},onVideoSegmentTimingInfo:function(e){a(e)},onAudioSegmentTimingInfo:function(e){s(e)},onId3:function(e,t){o(i,e,t)},onCaptions:function(e){u(i,[e])},isEndOfTimeline:l,onEndedTimeline:function(){c()},onTransmuxerLog:p,onDone:function(e){h&&(e.type="combined"===e.type?"video":e.type,h(null,i,e))}})}})}function Eu(e){var i=e.segment,n=e.bytes,t=e.trackInfoFn,r=e.timingInfoFn,a=e.videoSegmentTimingInfoFn,s=e.audioSegmentTimingInfoFn,o=e.id3Fn,u=e.captionsFn,l=e.isEndOfTimeline,c=e.endedTimelineFn,d=e.dataFn,h=e.doneFn,p=e.onTransmuxerLog,f=new Uint8Array(n);if(0<Fs(f,["moof"]).length){i.isFmp4=!0;var m=i.map.tracks,g={isFmp4:!0,hasVideo:!!m.video,hasAudio:!!m.audio};m.audio&&m.audio.codec&&"enca"!==m.audio.codec&&(g.audioCodec=m.audio.codec),m.video&&m.video.codec&&"encv"!==m.video.codec&&(g.videoCodec=m.video.codec),m.video&&m.audio&&(g.isMuxed=!0),t(i,g);var y=function(e){d(i,{data:f,type:g.hasAudio&&!g.isMuxed?"audio":"video"}),e&&e.length&&u(i,e),h(null,i,{})};gu({action:"probeMp4StartTime",timescales:i.map.timescales,data:f,transmuxer:i.transmuxer,callback:function(e){var t=e.data,e=e.startTime;n=t.buffer,i.bytes=f=t,g.hasAudio&&!g.isMuxed&&r(i,"audio","start",e),g.hasVideo&&r(i,"video","start",e),m.video&&t.byteLength&&i.transmuxer?gu({action:"pushMp4Captions",endAction:"mp4Captions",transmuxer:i.transmuxer,data:f,timescales:i.map.timescales,trackIds:[m.video.id],callback:function(e){n=e.data.buffer,i.bytes=f=e.data,e.logs.forEach(function(e){p(ir.mergeOptions(e,{stream:"mp4CaptionParser"}))}),y(e.captions)}}):y()}})}else if(i.transmuxer){if("undefined"==typeof i.container&&(i.container=mo(f)),"ts"!==i.container&&"aac"!==i.container)return t(i,{hasAudio:!1,hasVideo:!1}),h(null,i,{}),0;Su({segment:i,bytes:n,trackInfoFn:t,timingInfoFn:r,videoSegmentTimingInfoFn:a,audioSegmentTimingInfoFn:s,id3Fn:o,captionsFn:u,isEndOfTimeline:l,endedTimelineFn:c,dataFn:d,doneFn:h,onTransmuxerLog:p})}else h(null,i,{})}function ku(e,i){var n=e.id,t=e.key,r=e.encryptedBytes,a=e.decryptionWorker,e=function e(t){t.data.source===n&&(a.removeEventListener("message",e),t=t.data.decrypted,i(new Uint8Array(t.bytes,t.byteOffset,t.byteLength)))};a.addEventListener("message",e),e=t.bytes.slice?t.bytes.slice():new Uint32Array(Array.prototype.slice.call(t.bytes)),a.postMessage(tu({source:n,encrypted:r,key:e,iv:t.iv}),[r.buffer,e.buffer])}function Cu(e){var i=e.activeXhrs,m=e.decryptionWorker,g=e.trackInfoFn,y=e.timingInfoFn,v=e.videoSegmentTimingInfoFn,_=e.audioSegmentTimingInfoFn,b=e.id3Fn,T=e.captionsFn,S=e.isEndOfTimeline,E=e.endedTimelineFn,k=e.dataFn,C=e.doneFn,w=e.onTransmuxerLog,n=0,r=!1;return function(e,f){if(!r){if(e)return r=!0,yu(i),C(e,f);if((n+=1)===i.length){var t=function(){if(f.encryptedBytes)return t=(e={decryptionWorker:m,segment:f,trackInfoFn:g,timingInfoFn:y,videoSegmentTimingInfoFn:v,audioSegmentTimingInfoFn:_,id3Fn:b,captionsFn:T,isEndOfTimeline:S,endedTimelineFn:E,dataFn:k,doneFn:C,onTransmuxerLog:w}).decryptionWorker,i=e.segment,n=e.trackInfoFn,r=e.timingInfoFn,a=e.videoSegmentTimingInfoFn,s=e.audioSegmentTimingInfoFn,o=e.id3Fn,u=e.captionsFn,l=e.isEndOfTimeline,c=e.endedTimelineFn,d=e.dataFn,h=e.doneFn,p=e.onTransmuxerLog,void ku({id:i.requestId,key:i.key,encryptedBytes:i.encryptedBytes,decryptionWorker:t},function(e){i.bytes=e,Eu({segment:i,bytes:i.bytes,trackInfoFn:n,timingInfoFn:r,videoSegmentTimingInfoFn:a,audioSegmentTimingInfoFn:s,id3Fn:o,captionsFn:u,isEndOfTimeline:l,endedTimelineFn:c,dataFn:d,doneFn:h,onTransmuxerLog:p})});var e,t,i,n,r,a,s,o,u,l,c,d,h,p;Eu({segment:f,bytes:f.bytes,trackInfoFn:g,timingInfoFn:y,videoSegmentTimingInfoFn:v,audioSegmentTimingInfoFn:_,id3Fn:b,captionsFn:T,isEndOfTimeline:S,endedTimelineFn:E,dataFn:k,doneFn:C,onTransmuxerLog:w})};if(f.endOfAllRequests=Date.now(),f.map&&f.map.encryptedBytes&&!f.map.bytes)return ku({decryptionWorker:m,id:f.requestId+"-init",encryptedBytes:f.map.encryptedBytes,key:f.map.key},function(e){f.map.bytes=e,bu(f,function(e){return e?(yu(i),C(e,f)):void t()})});t()}}}}function wu(e){var n=e.segment,r=e.progressFn;return e.trackInfoFn,e.timingInfoFn,e.videoSegmentTimingInfoFn,e.audioSegmentTimingInfoFn,e.id3Fn,e.captionsFn,e.isEndOfTimeline,e.endedTimelineFn,e.dataFn,function(e){var t,i=e.target;if(!i.aborted)return n.stats=ir.mergeOptions(n.stats,(i=(t=e).target,(i={bandwidth:1/0,bytesReceived:0,roundTripTime:Date.now()-i.requestTime||0}).bytesReceived=t.loaded,i.bandwidth=Math.floor(i.bytesReceived/i.roundTripTime*8*1e3),i)),!n.stats.firstBytesReceivedAt&&n.stats.bytesReceived&&(n.stats.firstBytesReceivedAt=Date.now()),r(e,n)}}function Iu(e){var t,i,n,r=e.xhr,a=e.xhrOptions,s=e.decryptionWorker,o=e.segment,u=e.abortFn,l=e.progressFn,c=e.trackInfoFn,d=e.timingInfoFn,h=e.videoSegmentTimingInfoFn,p=e.audioSegmentTimingInfoFn,f=e.id3Fn,m=e.captionsFn,g=e.isEndOfTimeline,y=e.endedTimelineFn,v=e.dataFn,_=e.doneFn,e=e.onTransmuxerLog,b=[],_=Cu({activeXhrs:b,decryptionWorker:s,trackInfoFn:c,timingInfoFn:d,videoSegmentTimingInfoFn:h,audioSegmentTimingInfoFn:p,id3Fn:f,captionsFn:m,isEndOfTimeline:g,endedTimelineFn:y,dataFn:v,doneFn:_,onTransmuxerLog:e});o.key&&!o.key.bytes&&(e=[o.key],o.map&&!o.map.bytes&&o.map.key&&o.map.key.resolvedUri===o.key.resolvedUri&&e.push(o.map.key),e=r(ir.mergeOptions(a,{uri:o.key.resolvedUri,responseType:"arraybuffer"}),_u(o,e,_)),b.push(e)),o.map&&!o.map.bytes&&(!o.map.key||o.key&&o.key.resolvedUri===o.map.key.resolvedUri||(t=r(ir.mergeOptions(a,{uri:o.map.key.resolvedUri,responseType:"arraybuffer"}),_u(o,[o.map.key],_)),b.push(t)),t=r(ir.mergeOptions(a,{uri:o.map.resolvedUri,responseType:"arraybuffer",headers:Jo(o.map)}),(i=(t={segment:o,finishProcessingFn:_}).segment,n=t.finishProcessingFn,function(e,t){e=vu(e,t);if(e)return n(e,i);e=new Uint8Array(t.response);if(i.map.key)return i.map.encryptedBytes=e,n(null,i);i.map.bytes=e,bu(i,function(e){return e?(e.xhr=t,e.status=t.status,n(e,i)):void n(null,i)})})),b.push(t)),a=ir.mergeOptions(a,{uri:o.part&&o.part.resolvedUri||o.resolvedUri,responseType:"arraybuffer",headers:Jo(o)}),(a=r(a,Tu({segment:o,finishProcessingFn:_,responseType:a.responseType}))).addEventListener("progress",wu({segment:o,progressFn:l,trackInfoFn:c,timingInfoFn:d,videoSegmentTimingInfoFn:h,audioSegmentTimingInfoFn:p,id3Fn:f,captionsFn:m,isEndOfTimeline:g,endedTimelineFn:y,dataFn:v})),b.push(a);var T={};return b.forEach(function(e){var t,i;e.addEventListener("loadend",(t=(e={loadendState:T,abortFn:u}).loadendState,i=e.abortFn,function(e){e.target.aborted&&i&&!t.calledAbortFn&&(i(),t.calledAbortFn=!0)}))}),function(){return yu(b)}}function xu(e,t){return t=t.attributes||{},e&&e.mediaGroups&&e.mediaGroups.AUDIO&&t.AUDIO&&e.mediaGroups.AUDIO[t.AUDIO]}function Au(e){var n={};return e.forEach(function(e){var t=e.mediaType,i=e.type,e=e.details;n[t]=n[t]||[],n[t].push(pr(""+i+e))}),Object.keys(n).forEach(function(e){return 1<n[e].length?(hl("multiple "+e+" codecs found as attributes: "+n[e].join(", ")+". Setting playlist codecs to null so that we wait for mux.js to probe segments for real codecs."),void(n[e]=null)):void(n[e]=n[e][0])}),n}function Pu(e){var t=0;return e.audio&&t++,e.video&&t++,t}function Lu(e,t){var i,n=t.attributes||{},r=Au(function(e){e=e.attributes||{};if(e.CODECS)return fr(e.CODECS)}(t)||[]);return xu(e,t)&&!r.audio&&!function(e,t){if(!xu(e,t))return!0;var i,t=t.attributes||{},n=e.mediaGroups.AUDIO[t.AUDIO];for(i in n)if(!n[i].uri&&!n[i].playlists)return!0;return!1}(e,t)&&(i=Au(function(e,t){if(!e.mediaGroups.AUDIO||!t)return null;var i,n=e.mediaGroups.AUDIO[t];if(!n)return null;for(i in n){var r=n[i];if(r.default&&r.playlists)return fr(r.playlists[0].attributes.CODECS)}return null}(e,n.AUDIO)||[])).audio&&(r.audio=i.audio),r}function Du(e){if(e&&e.playlist){var t=e.playlist;return JSON.stringify({id:t.id,bandwidth:e.bandwidth,width:e.width,height:e.height,codecs:t.attributes&&t.attributes.CODECS||""})}}function Ou(e,t){return(e=e&&_.getComputedStyle(e))?e[t]:""}function Ru(e,n){var r=e.slice();e.sort(function(e,t){var i=n(e,t);return 0===i?r.indexOf(e)-r.indexOf(t):i})}function Mu(e,t){var i,n;return(i=(i=e.attributes.BANDWIDTH?e.attributes.BANDWIDTH:i)||_.Number.MAX_VALUE)-(n=(n=t.attributes.BANDWIDTH?t.attributes.BANDWIDTH:n)||_.Number.MAX_VALUE)}function Nu(e,t,i,n,r,a){if(e){var s={bandwidth:t,width:i,height:n,limitRenditionByPlayerDimensions:r},o=e.playlists;Qu.isAudioOnly(e)&&(o=a.getAudioTrackPlaylists_(),s.audioOnly=!0);var u=o.map(function(e){var t=e.attributes&&e.attributes.RESOLUTION&&e.attributes.RESOLUTION.width,i=e.attributes&&e.attributes.RESOLUTION&&e.attributes.RESOLUTION.height,n=e.attributes&&e.attributes.BANDWIDTH;return{bandwidth:n||_.Number.MAX_VALUE,width:t,height:i,playlist:e}});Ru(u,function(e,t){return e.bandwidth-t.bandwidth});var l=(u=u.filter(function(e){return!Qu.isIncompatible(e.playlist)})).filter(function(e){return Qu.isEnabled(e.playlist)}),e=(l=!l.length?u.filter(function(e){return!Qu.isDisabled(e.playlist)}):l).filter(function(e){return e.bandwidth*rl.BANDWIDTH_VARIANCE<t}),c=e[e.length-1],o=e.filter(function(e){return e.bandwidth===c.bandwidth})[0];if(!1===r){var d=o||l[0]||u[0];if(d&&d.playlist){r=o?"bandwidthBestRep":"sortedPlaylistReps";return l[0]&&(r="enabledPlaylistReps"),pl("choosing "+Du(d)+" using "+r+" with options",s),d.playlist}return pl("could not choose a playlist with options",s),null}d=e.filter(function(e){return e.width&&e.height});Ru(d,function(e,t){return e.width-t.width});var h,p,f,e=d.filter(function(e){return e.width===i&&e.height===n}),c=e[e.length-1],e=e.filter(function(e){return e.bandwidth===c.bandwidth})[0];e||(p=(h=d.filter(function(e){return e.width>i||e.height>n})).filter(function(e){return e.width===h[0].width&&e.height===h[0].height}),c=p[p.length-1],p=p.filter(function(e){return e.bandwidth===c.bandwidth})[0]),a.experimentalLeastPixelDiffSelector&&(m=d.map(function(e){return e.pixelDiff=Math.abs(e.width-i)+Math.abs(e.height-n),e}),Ru(m,function(e,t){return e.pixelDiff===t.pixelDiff?t.bandwidth-e.bandwidth:e.pixelDiff-t.pixelDiff}),f=m[0]);var m=f||p||e||o||l[0]||u[0];if(m&&m.playlist){u="sortedPlaylistReps";return f?u="leastPixelDiffRep":p?u="resolutionPlusOneRep":e?u="resolutionBestRep":o?u="bandwidthBestRep":l[0]&&(u="enabledPlaylistReps"),pl("choosing "+Du(m)+" using "+u+" with options",s),m.playlist}return pl("could not choose a playlist with options",s),null}}function Uu(e){var t=e.inbandTextTracks,i=e.metadataArray,r=e.timestampOffset,n=e.videoDuration;if(i){var a=_.WebKitDataCue||_.VTTCue,s=t.metadataTrack_;if(s&&(i.forEach(function(e){var n=e.cueTime+r;!("number"!=typeof n||_.isNaN(n)||n<0)&&n<1/0&&e.frames.forEach(function(e){var t,i=new a(n,n,e.value||e.url||e.data||"");i.frame=e,i.value=e,t=i,Object.defineProperties(t.frame,{id:{get:function(){return ir.log.warn("cue.frame.id is deprecated. Use cue.value.key instead."),t.value.key}},value:{get:function(){return ir.log.warn("cue.frame.value is deprecated. Use cue.value.data instead."),t.value.data}},privateData:{get:function(){return ir.log.warn("cue.frame.privateData is deprecated. Use cue.value.data instead."),t.value.data}}}),s.addCue(i)})}),s.cues&&s.cues.length)){for(var o=s.cues,u=[],l=0;l<o.length;l++)o[l]&&u.push(o[l]);var c=u.reduce(function(e,t){var i=e[t.startTime]||[];return i.push(t),e[t.startTime]=i,e},{}),d=Object.keys(c).sort(function(e,t){return Number(e)-Number(t)});d.forEach(function(e,t){var e=c[e],i=Number(d[t+1])||n;e.forEach(function(e){e.endTime=i})})}}}function Bu(e,t,i){var n,r;if(i&&i.cues)for(n=i.cues.length;n--;)(r=i.cues[n]).startTime>=e&&r.endTime<=t&&i.removeCue(r)}function Fu(e){return"number"==typeof e&&isFinite(e)}function ju(e){var t=e.startOfSegment,i=e.duration,n=e.segment,r=e.part,a=e.playlist,s=a.mediaSequence,o=a.id,u=a.segments,l=e.mediaIndex,c=e.partIndex,d=e.timeline,h=(void 0===u?[]:u).length-1,p="mediaIndex/partIndex increment";return e.getMediaInfoForTime?p="getMediaInfoForTime ("+e.getMediaInfoForTime+")":e.isSyncRequest&&(p="getSyncSegmentCandidate (isSyncRequest)"),a="number"==typeof c,u=e.segment.uri?"segment":"pre-segment",e=a?wo({preloadSegment:n})-1:0,u+" ["+(s+l)+"/"+(s+h)+"]"+(a?" part ["+c+"/"+e+"]":"")+" segment start/end ["+n.start+" => "+n.end+"]"+(a?" part start/end ["+r.start+" => "+r.end+"]":"")+" startOfSegment ["+t+"] duration ["+i+"] timeline ["+d+"] selected by ["+p+"] playlist ["+o+"]"}function Hu(e){return e+"TimingInfo"}function qu(e){var t=e.timelineChangeController,i=e.currentTimeline,n=e.segmentTimeline,r=e.loaderType,e=e.audioDisabled;if(i!==n){if("audio"===r){i=t.lastTimelineChange({type:"main"});return!i||i.to!==n}if("main"===r&&e){t=t.pendingTimelineChange({type:"audio"});return t&&t.to===n?!1:!0}}}function Vu(e){var t=e.segmentDuration,e=e.maxDuration;return!!t&&Math.round(t)>e+Ku}function Wu(e,t){if("hls"!==t)return null;var i=function(e,t){e=e&&"number"==typeof e.start&&"number"==typeof e.end?e.end-e.start:0,t=t&&"number"==typeof t.start&&"number"==typeof t.end?t.end-t.start:0;return Math.max(e,t)}(e.audioTimingInfo,e.videoTimingInfo);if(!i)return null;var n=e.playlist.targetDuration,r=Vu({segmentDuration:i,maxDuration:2*n}),t=Vu({segmentDuration:i,maxDuration:n}),n="Segment with index "+e.mediaIndex+" from playlist "+e.playlist.id+" has a duration of "+i+" when the reported duration is "+e.duration+" and the target duration is "+n+". For HLS content, a duration in excess of the target duration may result in playback issues. See the HLS specification section on EXT-X-TARGETDURATION for more details: https://tools.ietf.org/html/draft-pantos-http-live-streaming-23#section-4.3.3.1";return r||t?{severity:r?"warn":"info",message:n}:null}var zu=po,Gu=9e4,Xu=nr,Ku=1/30,Yu=ir.createTimeRange,Qu={liveEdgeDelay:Io,duration:Ao,seekable:function(e,t,i){var n=t||0,i=Lo(e,t,!0,i);return null===i?Yu():Yu(n,i)},getMediaInfoForTime:function(e){for(var t=e.playlist,i=e.currentTime,n=e.startingSegmentIndex,r=e.startingPartIndex,a=e.startTime,s=e.experimentalExactManifestTimings,o=i-a,u=ko(t),l=0,c=0;c<u.length;c++){var d=u[c];if(n===d.segmentIndex&&("number"!=typeof r||"number"!=typeof d.partIndex||r===d.partIndex)){l=c;break}}if(o<0){if(0<l)for(var h=l-1;0<=h;h--){var p=u[h];if(o+=p.duration,s){if(o<0)continue}else if(o+Ku<=0)continue;return{partIndex:p.partIndex,segmentIndex:p.segmentIndex,startTime:a-Po({defaultDuration:t.targetDuration,durationList:u,startIndex:l,endIndex:h})}}return{partIndex:u[0]&&u[0].partIndex||null,segmentIndex:u[0]&&u[0].segmentIndex||0,startTime:i}}if(l<0){for(var f=l;f<0;f++)if((o-=t.targetDuration)<0)return{partIndex:u[0]&&u[0].partIndex||null,segmentIndex:u[0]&&u[0].segmentIndex||0,startTime:i};l=0}for(var m=l;m<u.length;m++){var g=u[m];if(o-=g.duration,s){if(0<o)continue}else if(0<=o-Ku)continue;return{partIndex:g.partIndex,segmentIndex:g.segmentIndex,startTime:a+Po({defaultDuration:t.targetDuration,durationList:u,startIndex:l,endIndex:m})}}return{segmentIndex:u[u.length-1].segmentIndex,partIndex:u[u.length-1].partIndex,startTime:i}},isEnabled:Ro,isDisabled:function(e){return e.disabled},isBlacklisted:Do,isIncompatible:Oo,playlistEnd:Lo,isAes:function(e){for(var t=0;t<e.segments.length;t++)if(e.segments[t].key)return!0;return!1},hasAttribute:Mo,estimateSegmentRequestTime:function(e,t,i,n){return Mo("BANDWIDTH",i)?(e*i.attributes.BANDWIDTH-8*(n=void 0===n?0:n))/t:NaN},isLowestEnabledRendition:No,isAudioOnly:Fo,playlistMatch:Uo},$u=ir.log,Ju=ir.mergeOptions,K=ir.EventTarget,Zu=function(a){function e(e,t,i){var n;if(void 0===i&&(i={}),n=a.call(this)||this,!e)throw new Error("A non-empty playlist URL or object is required");n.logger_=yo("PlaylistLoader");var r=i.withCredentials,r=void 0!==r&&r,i=i.handleManifestRedirects,i=void 0!==i&&i;n.src=e,n.vhs_=t,n.withCredentials=r,n.handleManifestRedirects=i;t=t.options_;return n.customTagParsers=t&&t.customTagParsers||[],n.customTagMappers=t&&t.customTagMappers||[],n.experimentalLLHLS=t&&t.experimentalLLHLS||!1,n.state="HAVE_NOTHING",n.handleMediaupdatetimeout_=n.handleMediaupdatetimeout_.bind(yt(n)),n.on("mediaupdatetimeout",n.handleMediaupdatetimeout_),n}vt(e,a);var t=e.prototype;return t.handleMediaupdatetimeout_=function(){var e,t,i=this;"HAVE_METADATA"===this.state&&(e=this.media(),t=Xu(this.master.uri,e.uri),this.experimentalLLHLS&&(t=function(i,e){if(e.endList)return i;var t,n,r,a=[];return e.serverControl&&e.serverControl.canBlockReload&&(r=e.preloadSegment,t=e.mediaSequence+e.segments.length,r&&(n=r.parts||[],-1<(r=wo(e)-1)&&r!=n.length-1&&a.push("_HLS_part="+r),(-1<r||n.length)&&t--),a.unshift("_HLS_msn="+t)),e.serverControl&&e.serverControl.canSkipUntil&&a.unshift("_HLS_skip="+(e.serverControl.canSkipDateranges?"v2":"YES")),a.forEach(function(e,t){i+=(0===t?"?":"&")+e}),i}(t,e)),this.state="HAVE_CURRENT_METADATA",this.request=this.vhs_.xhr({uri:t,withCredentials:this.withCredentials},function(e,t){if(i.request)return e?i.playlistRequestError(i.request,i.media(),"HAVE_METADATA"):void i.haveMetadata({playlistString:i.request.responseText,url:i.media().uri,id:i.media().id})}))},t.playlistRequestError=function(e,t,i){var n=t.uri,t=t.id;this.request=null,i&&(this.state=i),this.error={playlist:this.master.playlists[t],status:e.status,message:"HLS playlist request error at URL: "+n+".",responseText:e.responseText,code:500<=e.status?4:2},this.trigger("error")},t.parseManifest_=function(e){var t=this,i=e.url;return function(e){var t=e.onwarn,i=e.oninfo,n=e.manifestString,r=e.customTagParsers,a=void 0===r?[]:r,r=e.customTagMappers,r=void 0===r?[]:r,e=e.experimentalLLHLS,s=new Er;t&&s.on("warn",t),i&&s.on("info",i),a.forEach(function(e){return s.addParser(e)}),r.forEach(function(e){return s.addTagMapper(e)}),s.push(n),s.end();var o=s.manifest;e||(["preloadSegment","skip","serverControl","renditionReports","partInf","partTargetDuration"].forEach(function(e){o.hasOwnProperty(e)&&delete o[e]}),o.segments&&o.segments.forEach(function(t){["parts","preloadHints"].forEach(function(e){t.hasOwnProperty(e)&&delete t[e]})})),o.targetDuration||(u=10,o.segments&&o.segments.length&&(u=o.segments.reduce(function(e,t){return Math.max(e,t.duration)},0)),t&&t("manifest has no targetDuration defaulting to "+u),o.targetDuration=u);var u=Co(o);return u.length&&!o.partTargetDuration&&(u=u.reduce(function(e,t){return Math.max(e,t.duration)},0),t&&(t("manifest has no partTargetDuration defaulting to "+u),$u.error("LL-HLS manifest has parts but lacks required #EXT-X-PART-INF:PART-TARGET value. See https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-09#section-4.4.3.7. Playback is not guaranteed.")),o.partTargetDuration=u),o}({onwarn:function(e){e=e.message;return t.logger_("m3u8-parser warn for "+i+": "+e)},oninfo:function(e){e=e.message;return t.logger_("m3u8-parser info for "+i+": "+e)},manifestString:e.manifestString,customTagParsers:this.customTagParsers,customTagMappers:this.customTagMappers,experimentalLLHLS:this.experimentalLLHLS})},t.haveMetadata=function(e){var t=e.playlistString,i=e.playlistObject,n=e.url,e=e.id;this.request=null,this.state="HAVE_METADATA";t=i||this.parseManifest_({url:n,manifestString:t});t.lastRequest=Date.now(),qo({playlist:t,uri:n,id:e});n=Ko(this.master,t);this.targetDuration=t.partTargetDuration||t.targetDuration,n?(this.master=n,this.media_=this.master.playlists[e]):this.trigger("playlistunchanged"),this.updateMediaUpdateTimeout_(Yo(this.media(),!!n)),this.trigger("loadedplaylist")},t.dispose=function(){this.trigger("dispose"),this.stopRequest(),_.clearTimeout(this.mediaUpdateTimeout),_.clearTimeout(this.finalRenditionTimeout),this.off()},t.stopRequest=function(){var e;this.request&&(e=this.request,this.request=null,e.onreadystatechange=null,e.abort())},t.media=function(i,e){var n=this;if(!i)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);if("string"==typeof i){if(!this.master.playlists[i])throw new Error("Unknown playlist URI: "+i);i=this.master.playlists[i]}if(_.clearTimeout(this.finalRenditionTimeout),e){var t=(i.partTargetDuration||i.targetDuration)/2*1e3||5e3;this.finalRenditionTimeout=_.setTimeout(this.media.bind(this,i,!1),t)}else{var r=this.state,e=!this.media_||i.id!==this.media_.id,t=this.master.playlists[i.id];if(t&&t.endList||i.endList&&i.segments.length)return this.request&&(this.request.onreadystatechange=null,this.request.abort(),this.request=null),this.state="HAVE_METADATA",this.media_=i,void(e&&(this.trigger("mediachanging"),"HAVE_MASTER"===r?this.trigger("loadedmetadata"):this.trigger("mediachange")));if(this.updateMediaUpdateTimeout_(Yo(i,!0)),e){if(this.state="SWITCHING_MEDIA",this.request){if(i.resolvedUri===this.request.url)return;this.request.onreadystatechange=null,this.request.abort(),this.request=null}this.media_&&this.trigger("mediachanging"),this.request=this.vhs_.xhr({uri:i.resolvedUri,withCredentials:this.withCredentials},function(e,t){if(n.request){if(i.lastRequest=Date.now(),i.resolvedUri=go(n.handleManifestRedirects,i.resolvedUri,t),e)return n.playlistRequestError(n.request,i,r);n.haveMetadata({playlistString:t.responseText,url:i.uri,id:i.id}),"HAVE_MASTER"===r?n.trigger("loadedmetadata"):n.trigger("mediachange")}})}}},t.pause=function(){this.mediaUpdateTimeout&&(_.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null),this.stopRequest(),"HAVE_NOTHING"===this.state&&(this.started=!1),"SWITCHING_MEDIA"===this.state?this.media_?this.state="HAVE_METADATA":this.state="HAVE_MASTER":"HAVE_CURRENT_METADATA"===this.state&&(this.state="HAVE_METADATA")},t.load=function(e){var t=this;this.mediaUpdateTimeout&&(_.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null);var i=this.media();e?(e=i?(i.partTargetDuration||i.targetDuration)/2*1e3:5e3,this.mediaUpdateTimeout=_.setTimeout(function(){t.mediaUpdateTimeout=null,t.load()},e)):this.started?i&&!i.endList?this.trigger("mediaupdatetimeout"):this.trigger("loadedplaylist"):this.start()},t.updateMediaUpdateTimeout_=function(e){var t=this;this.mediaUpdateTimeout&&(_.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null),this.media()&&!this.media().endList&&(this.mediaUpdateTimeout=_.setTimeout(function(){t.mediaUpdateTimeout=null,t.trigger("mediaupdatetimeout"),t.updateMediaUpdateTimeout_(e)},e))},t.start=function(){var i=this;if(this.started=!0,"object"==typeof this.src)return this.src.uri||(this.src.uri=_.location.href),this.src.resolvedUri=this.src.uri,void setTimeout(function(){i.setupInitialPlaylist(i.src)},0);this.request=this.vhs_.xhr({uri:this.src,withCredentials:this.withCredentials},function(e,t){if(i.request){if(i.request=null,e)return i.error={status:t.status,message:"HLS playlist request error at URL: "+i.src+".",responseText:t.responseText,code:2},"HAVE_NOTHING"===i.state&&(i.started=!1),i.trigger("error");i.src=go(i.handleManifestRedirects,i.src,t);t=i.parseManifest_({manifestString:t.responseText,url:i.src});i.setupInitialPlaylist(t)}})},t.srcUri=function(){return"string"==typeof this.src?this.src:this.src.uri},t.setupInitialPlaylist=function(e){if(this.state="HAVE_MASTER",e.playlists)return this.master=e,Vo(this.master,this.srcUri()),e.playlists.forEach(function(t){t.segments=Go(t),t.segments.forEach(function(e){zo(e,t.resolvedUri)})}),this.trigger("loadedplaylist"),void(this.request||this.media(this.master.playlists[0]));var t,i,n,r=this.srcUri()||_.location.href;this.master=(i=jo(0,t=r),(n={mediaGroups:{AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},uri:_.location.href,resolvedUri:_.location.href,playlists:[{uri:t,id:i,resolvedUri:t,attributes:{}}]}).playlists[i]=n.playlists[0],n.playlists[t]=n.playlists[0],n),this.haveMetadata({playlistObject:e,url:r,id:this.master.playlists[0].id}),this.trigger("loadedmetadata")},e}(K),el=ir.xhr,tl=ir.mergeOptions,ai=Object.freeze({__proto__:null,createTransferableMessage:tu,initSegmentId:iu,segmentKeyId:nu,hexDump:ru,tagDump:function(e){e=e.bytes;return ru(e)},textRanges:function(e){for(var t,i,n="",r=0;r<e.length;r++)n+=(i=r,(t=e).start(i)+"-"+t.end(i)+" ");return n}}),Kt=ir.EventTarget,il=ir.mergeOptions,nl=function(a){function e(e,t,i,n){var r;void 0===i&&(i={}),(r=a.call(this)||this).masterPlaylistLoader_=n||yt(r),n||(r.isMaster_=!0);n=i.withCredentials,n=void 0!==n&&n,i=i.handleManifestRedirects,i=void 0!==i&&i;if(r.vhs_=t,r.withCredentials=n,r.handleManifestRedirects=i,!e)throw new Error("A non-empty playlist URL or object is required");return r.on("minimumUpdatePeriod",function(){r.refreshXml_()}),r.on("mediaupdatetimeout",function(){r.refreshMedia_(r.media().id)}),r.state="HAVE_NOTHING",r.loadedPlaylists_={},r.logger_=yo("DashPlaylistLoader"),r.isMaster_?(r.masterPlaylistLoader_.srcUrl=e,r.masterPlaylistLoader_.sidxMapping_={}):r.childPlaylist_=e,r}vt(e,a);var t=e.prototype;return t.requestErrored_=function(e,t,i){return!this.request||(this.request=null,e?(this.error="object"!=typeof e||e instanceof Error?{status:t.status,message:"DASH request error at URL: "+t.uri,response:t.response,code:2}:e,i&&(this.state=i),this.trigger("error"),!0):void 0)},t.addSidxSegments_=function(a,n,r){var s,o,u=this,l=a.sidx&&us(a.sidx);a.sidx&&l&&!this.masterPlaylistLoader_.sidxMapping_[l]?(s=go(this.handleManifestRedirects,a.sidx.resolvedUri),o=function(e,t){if(!u.requestErrored_(e,t,n)){var i,e=u.masterPlaylistLoader_.sidxMapping_;try{i=io(Os(t.response).subarray(8))}catch(e){return void u.requestErrored_(e,t,n)}return e[l]={sidxInfo:a.sidx,sidx:i},os(a,i,a.sidx.resolvedUri),r(!0)}},this.request=uu(s,this.vhs_.xhr,function(e,t,i,n){if(e)return o(e,t);if(!i||"mp4"!==i)return o({status:t.status,message:"Unsupported "+(i||"unknown")+" container type for sidx segment at URL: "+s,response:"",playlist:a,internal:!0,blacklistDuration:1/0,code:2},t);var r=a.sidx.byterange,i=r.offset,r=r.length;if(n.length>=r+i)return o(e,{response:n.subarray(i,i+r),status:t.status,uri:t.uri});u.request=u.vhs_.xhr({uri:s,responseType:"arraybuffer",headers:Jo({byterange:a.sidx.byterange})},o)})):this.mediaRequest_=_.setTimeout(function(){return r(!1)},0)},t.dispose=function(){this.trigger("dispose"),this.stopRequest(),this.loadedPlaylists_={},_.clearTimeout(this.minimumUpdatePeriodTimeout_),_.clearTimeout(this.mediaRequest_),_.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null,this.mediaRequest_=null,this.minimumUpdatePeriodTimeout_=null,this.masterPlaylistLoader_.createMupOnMedia_&&(this.off("loadedmetadata",this.masterPlaylistLoader_.createMupOnMedia_),this.masterPlaylistLoader_.createMupOnMedia_=null),this.off()},t.hasPendingRequest=function(){return this.request||this.mediaRequest_},t.stopRequest=function(){var e;this.request&&(e=this.request,this.request=null,e.onreadystatechange=null,e.abort())},t.media=function(t){var i=this;if(!t)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);var n=this.state;if("string"==typeof t){if(!this.masterPlaylistLoader_.master.playlists[t])throw new Error("Unknown playlist URI: "+t);t=this.masterPlaylistLoader_.master.playlists[t]}var e=!this.media_||t.id!==this.media_.id;if(e&&this.loadedPlaylists_[t.id]&&this.loadedPlaylists_[t.id].endList)return this.state="HAVE_METADATA",this.media_=t,void(e&&(this.trigger("mediachanging"),this.trigger("mediachange")));e&&(this.media_&&this.trigger("mediachanging"),this.addSidxSegments_(t,n,function(e){i.haveMetadata({startingState:n,playlist:t})}))},t.haveMetadata=function(e){var t=e.startingState,e=e.playlist;this.state="HAVE_METADATA",this.loadedPlaylists_[e.id]=e,this.mediaRequest_=null,this.refreshMedia_(e.id),"HAVE_MASTER"===t?this.trigger("loadedmetadata"):this.trigger("mediachange")},t.pause=function(){this.masterPlaylistLoader_.createMupOnMedia_&&(this.off("loadedmetadata",this.masterPlaylistLoader_.createMupOnMedia_),this.masterPlaylistLoader_.createMupOnMedia_=null),this.stopRequest(),_.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null,this.isMaster_&&(_.clearTimeout(this.masterPlaylistLoader_.minimumUpdatePeriodTimeout_),this.masterPlaylistLoader_.minimumUpdatePeriodTimeout_=null),"HAVE_NOTHING"===this.state&&(this.started=!1)},t.load=function(e){var t=this;_.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null;var i=this.media();e?(e=i?i.targetDuration/2*1e3:5e3,this.mediaUpdateTimeout=_.setTimeout(function(){return t.load()},e)):this.started?i&&!i.endList?(this.isMaster_&&!this.minimumUpdatePeriodTimeout_&&(this.trigger("minimumUpdatePeriod"),this.updateMinimumUpdatePeriodTimeout_()),this.trigger("mediaupdatetimeout")):this.trigger("loadedplaylist"):this.start()},t.start=function(){var i=this;this.started=!0,this.isMaster_?this.requestMaster_(function(e,t){i.haveMaster_(),i.hasPendingRequest()||i.media_||i.media(i.masterPlaylistLoader_.master.playlists[0])}):this.mediaRequest_=_.setTimeout(function(){return i.haveMaster_()},0)},t.requestMaster_=function(n){var r=this;this.request=this.vhs_.xhr({uri:this.masterPlaylistLoader_.srcUrl,withCredentials:this.withCredentials},function(e,t){if(!r.requestErrored_(e,t)){var i=t.responseText!==r.masterPlaylistLoader_.masterXml_;return r.masterPlaylistLoader_.masterXml_=t.responseText,t.responseHeaders&&t.responseHeaders.date?r.masterLoaded_=Date.parse(t.responseHeaders.date):r.masterLoaded_=Date.now(),r.masterPlaylistLoader_.srcUrl=go(r.handleManifestRedirects,r.masterPlaylistLoader_.srcUrl,t),i?(r.handleMaster_(),void r.syncClientServerClock_(function(){return n(t,i)})):n(t,i)}"HAVE_NOTHING"===r.state&&(r.started=!1)})},t.syncClientServerClock_=function(i){var n=this,r=Ds(this.masterPlaylistLoader_.masterXml_);return null===r?(this.masterPlaylistLoader_.clientOffset_=this.masterLoaded_-Date.now(),i()):"DIRECT"===r.method?(this.masterPlaylistLoader_.clientOffset_=r.value-Date.now(),i()):void(this.request=this.vhs_.xhr({uri:Xu(this.masterPlaylistLoader_.srcUrl,r.value),method:r.method,withCredentials:this.withCredentials},function(e,t){if(n.request){if(e)return n.masterPlaylistLoader_.clientOffset_=n.masterLoaded_-Date.now(),i();t="HEAD"===r.method?t.responseHeaders&&t.responseHeaders.date?Date.parse(t.responseHeaders.date):n.masterLoaded_:Date.parse(t.responseText);n.masterPlaylistLoader_.clientOffset_=t-Date.now(),i()}}))},t.haveMaster_=function(){this.state="HAVE_MASTER",this.isMaster_?this.trigger("loadedplaylist"):this.media_||this.media(this.childPlaylist_)},t.handleMaster_=function(){this.mediaRequest_=null;var e,t,t=(n={masterXml:this.masterPlaylistLoader_.masterXml_,srcUrl:this.masterPlaylistLoader_.srcUrl,clientOffset:this.masterPlaylistLoader_.clientOffset_,sidxMapping:this.masterPlaylistLoader_.sidxMapping_},e=n.masterXml,i=n.srcUrl,t=n.clientOffset,n=n.sidxMapping,n=Ls(e,{manifestUri:i,clientOffset:t,sidxMapping:n}),Vo(n,i),n),i=this.masterPlaylistLoader_.master;i&&(t=function(e,t,i){for(var a=!0,s=il(e,{duration:t.duration,minimumUpdatePeriod:t.minimumUpdatePeriod}),n=0;n<t.playlists.length;n++){var r,o=t.playlists[n];o.sidx&&(r=us(o.sidx),i&&i[r]&&i[r].sidx&&os(o,i[r].sidx,o.sidx.resolvedUri));o=Ko(s,o,lu);o&&(s=o,a=!1)}return Ho(t,function(e,t,i,n){var r;e.playlists&&e.playlists.length&&(r=e.playlists[0].id,(e=Ko(s,e.playlists[0],lu))&&((s=e).mediaGroups[t][i][n].playlists[0]=s.playlists[r],a=!1))}),(a=t.minimumUpdatePeriod===e.minimumUpdatePeriod&&a)?null:s}(i,t,this.masterPlaylistLoader_.sidxMapping_)),this.masterPlaylistLoader_.master=t||i;var n=this.masterPlaylistLoader_.master.locations&&this.masterPlaylistLoader_.master.locations[0];return n&&n!==this.masterPlaylistLoader_.srcUrl&&(this.masterPlaylistLoader_.srcUrl=n),(!i||t&&t.minimumUpdatePeriod!==i.minimumUpdatePeriod)&&this.updateMinimumUpdatePeriodTimeout_(),Boolean(t)},t.updateMinimumUpdatePeriodTimeout_=function(){var e=this.masterPlaylistLoader_;e.createMupOnMedia_&&(e.off("loadedmetadata",e.createMupOnMedia_),e.createMupOnMedia_=null),e.minimumUpdatePeriodTimeout_&&(_.clearTimeout(e.minimumUpdatePeriodTimeout_),e.minimumUpdatePeriodTimeout_=null);var t=e.master&&e.master.minimumUpdatePeriod;0===t&&(e.media()?t=1e3*e.media().targetDuration:(e.createMupOnMedia_=e.updateMinimumUpdatePeriodTimeout_,e.one("loadedmetadata",e.createMupOnMedia_))),"number"!=typeof t||t<=0?t<0&&this.logger_("found invalid minimumUpdatePeriod of "+t+", not setting a timeout"):this.createMUPTimeout_(t)},t.createMUPTimeout_=function(e){var t=this.masterPlaylistLoader_;t.minimumUpdatePeriodTimeout_=_.setTimeout(function(){t.minimumUpdatePeriodTimeout_=null,t.trigger("minimumUpdatePeriod"),t.createMUPTimeout_(e)},e)},t.refreshXml_=function(){var i=this;this.requestMaster_(function(e,t){var r,a;t&&(i.media_&&(i.media_=i.masterPlaylistLoader_.master.playlists[i.media_.id]),i.masterPlaylistLoader_.sidxMapping_=(t=i.masterPlaylistLoader_.master,r=i.masterPlaylistLoader_.sidxMapping_,a=cu(t.playlists,r),Ho(t,function(e,t,i,n){e.playlists&&e.playlists.length&&(e=e.playlists,a=il(a,cu(e,r)))}),a),i.addSidxSegments_(i.media(),i.state,function(e){i.refreshMedia_(i.media().id)}))})},t.refreshMedia_=function(e){var t=this;if(!e)throw new Error("refreshMedia_ must take a media id");this.media_&&this.isMaster_&&this.handleMaster_();var i=this.masterPlaylistLoader_.master.playlists,n=!this.media_||this.media_!==i[e];n?this.media_=i[e]:this.trigger("playlistunchanged"),this.mediaUpdateTimeout||function e(){t.media().endList||(t.mediaUpdateTimeout=_.setTimeout(function(){t.trigger("mediaupdatetimeout"),e()},Yo(t.media(),Boolean(n))))}(),this.trigger("loadedplaylist")},e}(Kt),rl={GOAL_BUFFER_LENGTH:30,MAX_GOAL_BUFFER_LENGTH:60,BACK_BUFFER_LENGTH:30,GOAL_BUFFER_LENGTH_RATE:1,INITIAL_BANDWIDTH:4194304,BANDWIDTH_VARIANCE:1.2,BUFFER_LOW_WATER_LINE:0,MAX_BUFFER_LOW_WATER_LINE:30,EXPERIMENTAL_MAX_BUFFER_LOW_WATER_LINE:16,BUFFER_LOW_WATER_LINE_RATE:1,BUFFER_HIGH_WATER_LINE:30},si=function(n){return function(){var e=function(t){try{return URL.createObjectURL(new Blob([t],{type:"application/javascript"}))}catch(e){var i=new BlobBuilder;return i.append(t),URL.createObjectURL(i.getBlob())}}(n),t=du(new Worker(e));t.objURL=e;var i=t.terminate;return t.on=t.addEventListener,t.off=t.removeEventListener,t.terminate=function(){return URL.revokeObjectURL(e),i.call(this)},t}},sr=function(e){return"var browserWorkerPolyFill = "+du.toString()+";\nbrowserWorkerPolyFill(self);\n"+e},K=function(e){return e.toString().replace(/^function.+?{/,"").slice(0,-1)},al=si(sr(K(function(){var e=function(){this.init=function(){var a={};this.on=function(e,t){a[e]||(a[e]=[]),a[e]=a[e].concat(t)},this.off=function(e,t){return!!a[e]&&(t=a[e].indexOf(t),a[e]=a[e].slice(),a[e].splice(t,1),-1<t)},this.trigger=function(e){var t,i,n,r=a[e];if(r)if(2===arguments.length)for(i=r.length,t=0;t<i;++t)r[t].call(this,arguments[1]);else{for(n=[],t=arguments.length,t=1;t<arguments.length;++t)n.push(arguments[t]);for(i=r.length,t=0;t<i;++t)r[t].apply(this,n)}},this.dispose=function(){a={}}}};e.prototype.pipe=function(t){return this.on("data",function(e){t.push(e)}),this.on("done",function(e){t.flush(e)}),this.on("partialdone",function(e){t.partialFlush(e)}),this.on("endedtimeline",function(e){t.endTimeline(e)}),this.on("reset",function(e){t.reset(e)}),t},e.prototype.push=function(e){this.trigger("data",e)},e.prototype.flush=function(e){this.trigger("done",e)},e.prototype.partialFlush=function(e){this.trigger("partialdone",e)},e.prototype.endTimeline=function(e){this.trigger("endedtimeline",e)},e.prototype.reset=function(e){this.trigger("reset",e)};var u,t,i,n,r,a,s,o,l,c,d,h,p,f,m,g,y,v,_,b,T,S,E,k,C,w,I,x,A,P,L,D,O,R,M,N,U,B,F,j=e,H=Math.pow(2,32)-1;!function(){if(T={avc1:[],avcC:[],btrt:[],dinf:[],dref:[],esds:[],ftyp:[],hdlr:[],mdat:[],mdhd:[],mdia:[],mfhd:[],minf:[],moof:[],moov:[],mp4a:[],mvex:[],mvhd:[],pasp:[],sdtp:[],smhd:[],stbl:[],stco:[],stsc:[],stsd:[],stsz:[],stts:[],styp:[],tfdt:[],tfhd:[],traf:[],trak:[],trun:[],trex:[],tkhd:[],vmhd:[]},"undefined"!=typeof Uint8Array){for(var e in T)T.hasOwnProperty(e)&&(T[e]=[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]);S=new Uint8Array(["i".charCodeAt(0),"s".charCodeAt(0),"o".charCodeAt(0),"m".charCodeAt(0)]),k=new Uint8Array(["a".charCodeAt(0),"v".charCodeAt(0),"c".charCodeAt(0),"1".charCodeAt(0)]),E=new Uint8Array([0,0,0,1]),C=new Uint8Array([0,0,0,0,0,0,0,0,118,105,100,101,0,0,0,0,0,0,0,0,0,0,0,0,86,105,100,101,111,72,97,110,100,108,101,114,0]),w=new Uint8Array([0,0,0,0,0,0,0,0,115,111,117,110,0,0,0,0,0,0,0,0,0,0,0,0,83,111,117,110,100,72,97,110,100,108,101,114,0]),I={video:C,audio:w},P=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,12,117,114,108,32,0,0,0,1]),A=new Uint8Array([0,0,0,0,0,0,0,0]),L=new Uint8Array([0,0,0,0,0,0,0,0]),D=L,O=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]),R=L,x=new Uint8Array([0,0,0,1,0,0,0,0,0,0,0,0])}}(),u=function(e){for(var t,i=[],n=0,r=1;r<arguments.length;r++)i.push(arguments[r]);for(r=i.length;r--;)n+=i[r].byteLength;for(t=new Uint8Array(n+8),new DataView(t.buffer,t.byteOffset,t.byteLength).setUint32(0,t.byteLength),t.set(e,4),r=0,n=8;r<i.length;r++)t.set(i[r],n),n+=i[r].byteLength;return t},t=function(){return u(T.dinf,u(T.dref,P))},i=function(e){return u(T.esds,new Uint8Array([0,0,0,0,3,25,0,0,0,4,17,64,21,0,6,0,0,0,218,192,0,0,218,192,5,2,e.audioobjecttype<<3|e.samplingfrequencyindex>>>1,e.samplingfrequencyindex<<7|e.channelcount<<3,6,1,2]))},f=function(e){return u(T.hdlr,I[e])},p=function(e){var t=new Uint8Array([0,0,0,0,0,0,0,2,0,0,0,3,0,1,95,144,e.duration>>>24&255,e.duration>>>16&255,e.duration>>>8&255,255&e.duration,85,196,0,0]);return e.samplerate&&(t[12]=e.samplerate>>>24&255,t[13]=e.samplerate>>>16&255,t[14]=e.samplerate>>>8&255,t[15]=255&e.samplerate),u(T.mdhd,t)},h=function(e){return u(T.mdia,p(e),f(e.type),a(e))},r=function(e){return u(T.mfhd,new Uint8Array([0,0,0,0,(4278190080&e)>>24,(16711680&e)>>16,(65280&e)>>8,255&e]))},a=function(e){return u(T.minf,"video"===e.type?u(T.vmhd,x):u(T.smhd,A),t(),g(e))},qe=function(e,t){for(var i=[],n=t.length;n--;)i[n]=v(t[n]);return u.apply(null,[T.moof,r(e)].concat(i))},s=function(e){for(var t=e.length,i=[];t--;)i[t]=c(e[t]);return u.apply(null,[T.moov,l(4294967295)].concat(i).concat(o(e)))},o=function(e){for(var t=e.length,i=[];t--;)i[t]=_(e[t]);return u.apply(null,[T.mvex].concat(i))},l=function(e){e=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,2,0,1,95,144,(4278190080&e)>>24,(16711680&e)>>16,(65280&e)>>8,255&e,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255]);return u(T.mvhd,e)},m=function(e){for(var t,i=e.samples||[],n=new Uint8Array(4+i.length),r=0;r<i.length;r++)t=i[r].flags,n[r+4]=t.dependsOn<<4|t.isDependedOn<<2|t.hasRedundancy;return u(T.sdtp,n)},g=function(e){return u(T.stbl,y(e),u(T.stts,R),u(T.stsc,D),u(T.stsz,O),u(T.stco,L))},y=function(e){return u(T.stsd,new Uint8Array([0,0,0,0,0,0,0,1]),("video"===e.type?M:N)(e))},M=function(e){for(var t,i,n=e.sps||[],r=e.pps||[],a=[],s=[],o=0;o<n.length;o++)a.push((65280&n[o].byteLength)>>>8),a.push(255&n[o].byteLength),a=a.concat(Array.prototype.slice.call(n[o]));for(o=0;o<r.length;o++)s.push((65280&r[o].byteLength)>>>8),s.push(255&r[o].byteLength),s=s.concat(Array.prototype.slice.call(r[o]));return t=[T.avc1,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(65280&e.width)>>8,255&e.width,(65280&e.height)>>8,255&e.height,0,72,0,0,0,72,0,0,0,0,0,0,0,1,19,118,105,100,101,111,106,115,45,99,111,110,116,114,105,98,45,104,108,115,0,0,0,0,0,0,0,0,0,0,0,0,0,24,17,17]),u(T.avcC,new Uint8Array([1,e.profileIdc,e.profileCompatibility,e.levelIdc,255].concat([n.length],a,[r.length],s))),u(T.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192]))],e.sarRatio&&(i=e.sarRatio[0],e=e.sarRatio[1],t.push(u(T.pasp,new Uint8Array([(4278190080&i)>>24,(16711680&i)>>16,(65280&i)>>8,255&i,(4278190080&e)>>24,(16711680&e)>>16,(65280&e)>>8,255&e])))),u.apply(null,t)},N=function(e){return u(T.mp4a,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,(65280&e.channelcount)>>8,255&e.channelcount,(65280&e.samplesize)>>8,255&e.samplesize,0,0,0,0,(65280&e.samplerate)>>8,255&e.samplerate,0,0]),i(e))},d=function(e){e=new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,0,(4278190080&e.duration)>>24,(16711680&e.duration)>>16,(65280&e.duration)>>8,255&e.duration,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,(65280&e.width)>>8,255&e.width,0,0,(65280&e.height)>>8,255&e.height,0,0]);return u(T.tkhd,e)},v=function(e){var t,i=u(T.tfhd,new Uint8Array([0,0,0,58,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0])),n=Math.floor(e.baseMediaDecodeTime/(1+H)),r=Math.floor(e.baseMediaDecodeTime%(1+H)),n=u(T.tfdt,new Uint8Array([1,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,255&n,r>>>24&255,r>>>16&255,r>>>8&255,255&r]));return"audio"===e.type?(t=b(e,92),u(T.traf,i,n,t)):(r=m(e),t=b(e,r.length+92),u(T.traf,i,n,t,r))},c=function(e){return e.duration=e.duration||4294967295,u(T.trak,d(e),h(e))},_=function(e){var t=new Uint8Array([0,0,0,0,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]);return"video"!==e.type&&(t[t.length-1]=0),u(T.trex,t)},U=function(e,t){var i=0,n=0,r=0,a=0;return e.length&&(void 0!==e[0].duration&&(i=1),void 0!==e[0].size&&(n=2),void 0!==e[0].flags&&(r=4),void 0!==e[0].compositionTimeOffset&&(a=8)),[0,0,i|n|r|a,1,(4278190080&e.length)>>>24,(16711680&e.length)>>>16,(65280&e.length)>>>8,255&e.length,(4278190080&t)>>>24,(16711680&t)>>>16,(65280&t)>>>8,255&t]},B=function(e,t){var i,n,r,a,s=e.samples||[];for(t+=20+16*s.length,t=U(s,t),(n=new Uint8Array(t.length+16*s.length)).set(t),i=t.length,a=0;a<s.length;a++)r=s[a],n[i++]=(4278190080&r.duration)>>>24,n[i++]=(16711680&r.duration)>>>16,n[i++]=(65280&r.duration)>>>8,n[i++]=255&r.duration,n[i++]=(4278190080&r.size)>>>24,n[i++]=(16711680&r.size)>>>16,n[i++]=(65280&r.size)>>>8,n[i++]=255&r.size,n[i++]=r.flags.isLeading<<2|r.flags.dependsOn,n[i++]=r.flags.isDependedOn<<6|r.flags.hasRedundancy<<4|r.flags.paddingValue<<1|r.flags.isNonSyncSample,n[i++]=61440&r.flags.degradationPriority,n[i++]=15&r.flags.degradationPriority,n[i++]=(4278190080&r.compositionTimeOffset)>>>24,n[i++]=(16711680&r.compositionTimeOffset)>>>16,n[i++]=(65280&r.compositionTimeOffset)>>>8,n[i++]=255&r.compositionTimeOffset;return u(T.trun,n)},F=function(e,t){var i,n,r,a,s=e.samples||[];for(t+=20+8*s.length,t=U(s,t),(i=new Uint8Array(t.length+8*s.length)).set(t),n=t.length,a=0;a<s.length;a++)r=s[a],i[n++]=(4278190080&r.duration)>>>24,i[n++]=(16711680&r.duration)>>>16,i[n++]=(65280&r.duration)>>>8,i[n++]=255&r.duration,i[n++]=(4278190080&r.size)>>>24,i[n++]=(16711680&r.size)>>>16,i[n++]=(65280&r.size)>>>8,i[n++]=255&r.size;return u(T.trun,i)},b=function(e,t){return("audio"===e.type?F:B)(e,t)};n=function(){return u(T.ftyp,S,E,S,k)};function q(e,t){var i={size:0,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0,degradationPriority:0,isNonSyncSample:1}};return i.dataOffset=t,i.compositionTimeOffset=e.pts-e.dts,i.duration=e.duration,i.size=4*e.length,i.size+=e.byteLength,e.keyFrame&&(i.flags.dependsOn=2,i.flags.isNonSyncSample=0),i}function V(e){for(var t=[];e--;)t.push(0);return t}function W(){var e,i;return z||(e={96e3:[ee,[227,64],V(154),[56]],88200:[ee,[231],V(170),[56]],64e3:[ee,[248,192],V(240),[56]],48e3:[ee,[255,192],V(268),[55,148,128],V(54),[112]],44100:[ee,[255,192],V(268),[55,163,128],V(84),[112]],32e3:[ee,[255,192],V(268),[55,234],V(226),[112]],24e3:[ee,[255,192],V(268),[55,255,128],V(268),[111,112],V(126),[224]],16e3:[ee,[255,192],V(268),[55,255,128],V(268),[111,255],V(269),[223,108],V(195),[1,192]],12e3:[te,V(268),[3,127,248],V(268),[6,255,240],V(268),[13,255,224],V(268),[27,253,128],V(259),[56]],11025:[te,V(268),[3,127,248],V(268),[6,255,240],V(268),[13,255,224],V(268),[27,255,192],V(268),[55,175,128],V(108),[112]],8e3:[te,V(268),[3,121,16],V(47),[7]]},i=e,z=Object.keys(i).reduce(function(e,t){return e[t]=new Uint8Array(i[t].reduce(function(e,t){return e.concat(t)},[])),e},{})),z}var z,G=function(e){return u(T.mdat,e)},X=qe,K=function(e){var t=n(),i=s(e),e=new Uint8Array(t.byteLength+i.byteLength);return e.set(t),e.set(i,t.byteLength),e},Y=function(e){var t,i,n=[],r=[];for(r.byteLength=0,r.nalCount=0,r.duration=0,t=n.byteLength=0;t<e.length;t++)"access_unit_delimiter_rbsp"===(i=e[t]).nalUnitType?(n.length&&(n.duration=i.dts-n.dts,r.byteLength+=n.byteLength,r.nalCount+=n.length,r.duration+=n.duration,r.push(n)),(n=[i]).byteLength=i.data.byteLength,n.pts=i.pts,n.dts=i.dts):("slice_layer_without_partitioning_rbsp_idr"===i.nalUnitType&&(n.keyFrame=!0),n.duration=i.dts-n.dts,n.byteLength+=i.data.byteLength,n.push(i));return r.length&&(!n.duration||n.duration<=0)&&(n.duration=r[r.length-1].duration),r.byteLength+=n.byteLength,r.nalCount+=n.length,r.duration+=n.duration,r.push(n),r},Q=function(e){var t,i,n=[],r=[];for(n.byteLength=0,n.nalCount=0,n.duration=0,n.pts=e[0].pts,n.dts=e[0].dts,r.byteLength=0,r.nalCount=0,r.duration=0,r.pts=e[0].pts,r.dts=e[0].dts,t=0;t<e.length;t++)(i=e[t]).keyFrame?(n.length&&(r.push(n),r.byteLength+=n.byteLength,r.nalCount+=n.nalCount,r.duration+=n.duration),(n=[i]).nalCount=i.length,n.byteLength=i.byteLength,n.pts=i.pts,n.dts=i.dts,n.duration=i.duration):(n.duration+=i.duration,n.nalCount+=i.length,n.byteLength+=i.byteLength,n.push(i));return r.length&&n.duration<=0&&(n.duration=r[r.length-1].duration),r.byteLength+=n.byteLength,r.nalCount+=n.nalCount,r.duration+=n.duration,r.push(n),r},$=function(e){var t;return!e[0][0].keyFrame&&1<e.length&&(t=e.shift(),e.byteLength-=t.byteLength,e.nalCount-=t.nalCount,e[0][0].dts=t.dts,e[0][0].pts=t.pts,e[0][0].duration+=t.duration),e},J=function(e,t){for(var i,n,r,a=t||0,s=[],o=0;o<e.length;o++)for(n=e[o],i=0;i<n.length;i++)r=n[i],a+=(r=q(r,a)).size,s.push(r);return s},Z=function(e){for(var t,i,n,r,a,s=0,o=e.byteLength,u=e.nalCount,l=new Uint8Array(o+4*u),c=new DataView(l.buffer),d=0;d<e.length;d++)for(n=e[d],t=0;t<n.length;t++)for(r=n[t],i=0;i<r.length;i++)a=r[i],c.setUint32(s,a.data.byteLength),l.set(a.data,s+=4),s+=a.data.byteLength;return l},ee=[33,16,5,32,164,27],te=[33,65,108,84,1,2,4,8,168,2,4,8,17,191,252],ie=function(e){return 9e4*e},ne=function(e,t){return e*t},re=function(e){return e/9e4},ae=function(e,t){return e/t},se=9e4,oe=ie,ue=re,le=function(e,t){return ie(ae(e,t))},ce=function(e,t){return ne(re(e),t)},de=function(e,t,i){return re(i?e:e-t)},he=function(e,t,i,n){var r,a,s,o,u,l,c=0,d=0;if(t.length&&(r=le(e.baseMediaDecodeTime,e.samplerate),a=Math.ceil(se/(e.samplerate/1024)),i&&n&&(s=r-Math.max(i,n),d=(c=Math.floor(s/a))*a),!(c<1||se/2<d))){for(o=(o=W()[e.samplerate])||t[0].data,u=0;u<c;u++)l=t[0],t.splice(0,0,{data:o,dts:l.dts-a,pts:l.pts-a});return e.baseMediaDecodeTime-=Math.floor(ce(d,e.samplerate)),d}},pe=function(e,t,i){return t.minSegmentDts>=i?e:(t.minSegmentDts=1/0,e.filter(function(e){return e.dts>=i&&(t.minSegmentDts=Math.min(t.minSegmentDts,e.dts),t.minSegmentPts=t.minSegmentDts,!0)}))},fe=function(e){for(var t,i=[],n=0;n<e.length;n++)t=e[n],i.push({size:t.data.byteLength,duration:1024});return i},me=function(e){for(var t,i=0,n=new Uint8Array(function(e){for(var t=0,i=0;i<e.length;i++)t+=e[i].data.byteLength;return t}(e)),r=0;r<e.length;r++)t=e[r],n.set(t.data,i),i+=t.data.byteLength;return n},ge=se,ye=function(e){delete e.minSegmentDts,delete e.maxSegmentDts,delete e.minSegmentPts,delete e.maxSegmentPts},ve=function(e,t){var i=e.minSegmentDts;return t||(i-=e.timelineStartInfo.dts),t=e.timelineStartInfo.baseMediaDecodeTime,t+=i,t=Math.max(0,t),"audio"===e.type&&(t*=e.samplerate/ge,t=Math.floor(t)),t},_e=function(e,t){"number"==typeof t.pts&&(void 0===e.timelineStartInfo.pts&&(e.timelineStartInfo.pts=t.pts),void 0===e.minSegmentPts?e.minSegmentPts=t.pts:e.minSegmentPts=Math.min(e.minSegmentPts,t.pts),void 0===e.maxSegmentPts?e.maxSegmentPts=t.pts:e.maxSegmentPts=Math.max(e.maxSegmentPts,t.pts)),"number"==typeof t.dts&&(void 0===e.timelineStartInfo.dts&&(e.timelineStartInfo.dts=t.dts),void 0===e.minSegmentDts?e.minSegmentDts=t.dts:e.minSegmentDts=Math.min(e.minSegmentDts,t.dts),void 0===e.maxSegmentDts?e.maxSegmentDts=t.dts:e.maxSegmentDts=Math.max(e.maxSegmentDts,t.dts))},be=function(e){for(var t=0,i={payloadType:-1,payloadSize:0},n=0,r=0;t<e.byteLength&&128!==e[t];){for(;255===e[t];)n+=255,t++;for(n+=e[t++];255===e[t];)r+=255,t++;if(r+=e[t++],!i.payload&&4===n){if("GA94"===String.fromCharCode(e[t+3],e[t+4],e[t+5],e[t+6])){i.payloadType=n,i.payloadSize=r,i.payload=e.subarray(t,t+r);break}i.payload=void 0}t+=r,r=n=0}return i},Te=function(e){return 181!==e.payload[0]||49!=(e.payload[1]<<8|e.payload[2])||"GA94"!==String.fromCharCode(e.payload[3],e.payload[4],e.payload[5],e.payload[6])||3!==e.payload[7]?null:e.payload.subarray(8,e.payload.length-1)},Se=function(e,t){var i,n,r,a,s=[];if(!(64&t[0]))return s;for(n=31&t[0],i=0;i<n;i++)a={type:3&t[2+(r=3*i)],pts:e},4&t[2+r]&&(a.ccData=t[3+r]<<8|t[4+r],s.push(a));return s},Ee=function(e){for(var t=e.byteLength,i=[],n=1;n<t-2;)0===e[n]&&0===e[n+1]&&3===e[n+2]?(i.push(n+2),n+=2):n++;if(0===i.length)return e;for(var r=t-i.length,a=new Uint8Array(r),s=0,n=0;n<r;s++,n++)s===i[0]&&(s++,i.shift()),a[n]=e[s];return a},ke=4,Ce=function e(t){t=t||{},e.prototype.init.call(this),this.parse708captions_="boolean"!=typeof t.parse708captions||t.parse708captions,this.captionPackets_=[],this.ccStreams_=[new Me(0,0),new Me(0,1),new Me(1,0),new Me(1,1)],this.parse708captions_&&(this.cc708Stream_=new Pe),this.reset(),this.ccStreams_.forEach(function(e){e.on("data",this.trigger.bind(this,"data")),e.on("partialdone",this.trigger.bind(this,"partialdone")),e.on("done",this.trigger.bind(this,"done"))},this),this.parse708captions_&&(this.cc708Stream_.on("data",this.trigger.bind(this,"data")),this.cc708Stream_.on("partialdone",this.trigger.bind(this,"partialdone")),this.cc708Stream_.on("done",this.trigger.bind(this,"done")))};(Ce.prototype=new j).push=function(e){var t,i;if("sei_rbsp"===e.nalUnitType&&(t=be(e.escapedRBSP)).payload&&t.payloadType===ke&&(i=Te(t)))if(e.dts<this.latestDts_)this.ignoreNextEqualDts_=!0;else{if(e.dts===this.latestDts_&&this.ignoreNextEqualDts_)return this.numSameDts_--,void(this.numSameDts_||(this.ignoreNextEqualDts_=!1));i=Se(e.pts,i),this.captionPackets_=this.captionPackets_.concat(i),this.latestDts_!==e.dts&&(this.numSameDts_=0),this.numSameDts_++,this.latestDts_=e.dts}},Ce.prototype.flushCCStreams=function(t){this.ccStreams_.forEach(function(e){return"flush"===t?e.flush():e.partialFlush()},this)},Ce.prototype.flushStream=function(e){this.captionPackets_.length&&(this.captionPackets_.forEach(function(e,t){e.presortIndex=t}),this.captionPackets_.sort(function(e,t){return e.pts===t.pts?e.presortIndex-t.presortIndex:e.pts-t.pts}),this.captionPackets_.forEach(function(e){e.type<2?this.dispatchCea608Packet(e):this.dispatchCea708Packet(e)},this),this.captionPackets_.length=0),this.flushCCStreams(e)},Ce.prototype.flush=function(){return this.flushStream("flush")},Ce.prototype.partialFlush=function(){return this.flushStream("partialFlush")},Ce.prototype.reset=function(){this.latestDts_=null,this.ignoreNextEqualDts_=!1,this.numSameDts_=0,this.activeCea608Channel_=[null,null],this.ccStreams_.forEach(function(e){e.reset()})},Ce.prototype.dispatchCea608Packet=function(e){this.setsTextOrXDSActive(e)?this.activeCea608Channel_[e.type]=null:this.setsChannel1Active(e)?this.activeCea608Channel_[e.type]=0:this.setsChannel2Active(e)&&(this.activeCea608Channel_[e.type]=1),null!==this.activeCea608Channel_[e.type]&&this.ccStreams_[(e.type<<1)+this.activeCea608Channel_[e.type]].push(e)},Ce.prototype.setsChannel1Active=function(e){return 4096==(30720&e.ccData)},Ce.prototype.setsChannel2Active=function(e){return 6144==(30720&e.ccData)},Ce.prototype.setsTextOrXDSActive=function(e){return 256==(28928&e.ccData)||4138==(30974&e.ccData)||6186==(30974&e.ccData)},Ce.prototype.dispatchCea708Packet=function(e){this.parse708captions_&&this.cc708Stream_.push(e)};function we(e){return 32<=e&&e<=127||160<=e&&e<=255}function Ie(e){this.windowNum=e,this.reset()}var xe={127:9834,4128:32,4129:160,4133:8230,4138:352,4140:338,4144:9608,4145:8216,4146:8217,4147:8220,4148:8221,4149:8226,4153:8482,4154:353,4156:339,4157:8480,4159:376,4214:8539,4215:8540,4216:8541,4217:8542,4218:9168,4219:9124,4220:9123,4221:9135,4222:9126,4223:9121,4256:12600};Ie.prototype.reset=function(){this.clearText(),this.pendingNewLine=!1,this.winAttr={},this.penAttr={},this.penLoc={},this.penColor={},this.visible=0,this.rowLock=0,this.columnLock=0,this.priority=0,this.relativePositioning=0,this.anchorVertical=0,this.anchorHorizontal=0,this.anchorPoint=0,this.rowCount=1,this.virtualRowCount=this.rowCount+1,this.columnCount=41,this.windowStyle=0,this.penStyle=0},Ie.prototype.getText=function(){return this.rows.join("\n")},Ie.prototype.clearText=function(){this.rows=[""],this.rowIdx=0},Ie.prototype.newLine=function(e){for(this.rows.length>=this.virtualRowCount&&"function"==typeof this.beforeRowOverflow&&this.beforeRowOverflow(e),0<this.rows.length&&(this.rows.push(""),this.rowIdx++);this.rows.length>this.virtualRowCount;)this.rows.shift(),this.rowIdx--},Ie.prototype.isEmpty=function(){return 0===this.rows.length||1===this.rows.length&&""===this.rows[0]},Ie.prototype.addText=function(e){this.rows[this.rowIdx]+=e},Ie.prototype.backspace=function(){var e;this.isEmpty()||(e=this.rows[this.rowIdx],this.rows[this.rowIdx]=e.substr(0,e.length-1))};function Ae(e){this.serviceNum=e,this.text="",this.currentWindow=new Ie(-1),this.windows=[]}Ae.prototype.init=function(e,t){this.startPts=e;for(var i=0;i<8;i++)this.windows[i]=new Ie(i),"function"==typeof t&&(this.windows[i].beforeRowOverflow=t)},Ae.prototype.setCurrentWindow=function(e){this.currentWindow=this.windows[e]};var Pe=function e(){e.prototype.init.call(this);var t=this;this.current708Packet=null,this.services={},this.push=function(e){(3===e.type||null===t.current708Packet)&&t.new708Packet(),t.add708Bytes(e)}};Pe.prototype=new j,Pe.prototype.new708Packet=function(){null!==this.current708Packet&&this.push708Packet(),this.current708Packet={data:[],ptsVals:[]}},Pe.prototype.add708Bytes=function(e){var t=e.ccData,i=t>>>8,t=255&t;this.current708Packet.ptsVals.push(e.pts),this.current708Packet.data.push(i),this.current708Packet.data.push(t)},Pe.prototype.push708Packet=function(){var e,t=this.current708Packet,i=t.data,n=null,r=0,a=i[r++];for(t.seq=a>>6,t.sizeCode=63&a;r<i.length;r++)e=31&(a=i[r++]),7===(n=a>>5)&&0<e&&(n=i[r++]),this.pushServiceBlock(n,r,e),0<e&&(r+=e-1)},Pe.prototype.pushServiceBlock=function(e,t,i){for(var n,r=t,a=this.current708Packet.data,s=(s=this.services[e])||this.initService(e,r);r<t+i&&r<a.length;r++)n=a[r],we(n)?r=this.handleText(r,s):16===n?r=this.extendedCommands(r,s):128<=n&&n<=135?r=this.setCurrentWindow(r,s):152<=n&&n<=159?r=this.defineWindow(r,s):136===n?r=this.clearWindows(r,s):140===n?r=this.deleteWindows(r,s):137===n?r=this.displayWindows(r,s):138===n?r=this.hideWindows(r,s):139===n?r=this.toggleWindows(r,s):151===n?r=this.setWindowAttributes(r,s):144===n?r=this.setPenAttributes(r,s):145===n?r=this.setPenColor(r,s):146===n?r=this.setPenLocation(r,s):143===n?s=this.reset(r,s):8===n?s.currentWindow.backspace():12===n?s.currentWindow.clearText():13===n?s.currentWindow.pendingNewLine=!0:14===n?s.currentWindow.clearText():141===n&&r++},Pe.prototype.extendedCommands=function(e,t){var i=this.current708Packet.data[++e];return e=we(i)?this.handleText(e,t,!0):e},Pe.prototype.getPts=function(e){return this.current708Packet.ptsVals[Math.floor(e/2)]},Pe.prototype.initService=function(t,e){var i=this;return this.services[t]=new Ae(t),this.services[t].init(this.getPts(e),function(e){i.flushDisplayed(e,i.services[t])}),this.services[t]},Pe.prototype.handleText=function(e,t,i){var n=this.current708Packet.data[e],n=(n=xe[i=(i?4096:0)|n]||i,4096&i&&i===n?"":String.fromCharCode(n)),t=t.currentWindow;return t.pendingNewLine&&!t.isEmpty()&&t.newLine(this.getPts(e)),t.pendingNewLine=!1,t.addText(n),e},Pe.prototype.setCurrentWindow=function(e,t){var i=this.current708Packet.data[e];return t.setCurrentWindow(7&i),e},Pe.prototype.defineWindow=function(e,t){var i=this.current708Packet.data,n=i[e];t.setCurrentWindow(7&n);t=t.currentWindow,n=i[++e];return t.visible=(32&n)>>5,t.rowLock=(16&n)>>4,t.columnLock=(8&n)>>3,t.priority=7&n,n=i[++e],t.relativePositioning=(128&n)>>7,t.anchorVertical=127&n,n=i[++e],t.anchorHorizontal=n,n=i[++e],t.anchorPoint=(240&n)>>4,t.rowCount=15&n,n=i[++e],t.columnCount=63&n,n=i[++e],t.windowStyle=(56&n)>>3,t.penStyle=7&n,t.virtualRowCount=t.rowCount+1,e},Pe.prototype.setWindowAttributes=function(e,t){var i=this.current708Packet.data,n=i[e],t=t.currentWindow.winAttr,n=i[++e];return t.fillOpacity=(192&n)>>6,t.fillRed=(48&n)>>4,t.fillGreen=(12&n)>>2,t.fillBlue=3&n,n=i[++e],t.borderType=(192&n)>>6,t.borderRed=(48&n)>>4,t.borderGreen=(12&n)>>2,t.borderBlue=3&n,n=i[++e],t.borderType+=(128&n)>>5,t.wordWrap=(64&n)>>6,t.printDirection=(48&n)>>4,t.scrollDirection=(12&n)>>2,t.justify=3&n,n=i[++e],t.effectSpeed=(240&n)>>4,t.effectDirection=(12&n)>>2,t.displayEffect=3&n,e},Pe.prototype.flushDisplayed=function(e,t){for(var i=[],n=0;n<8;n++)t.windows[n].visible&&!t.windows[n].isEmpty()&&i.push(t.windows[n].getText());t.endPts=e,t.text=i.join("\n\n"),this.pushCaption(t),t.startPts=e},Pe.prototype.pushCaption=function(e){""!==e.text&&(this.trigger("data",{startPts:e.startPts,endPts:e.endPts,text:e.text,stream:"cc708_"+e.serviceNum}),e.text="",e.startPts=e.endPts)},Pe.prototype.displayWindows=function(e,t){var i=this.current708Packet.data[++e],n=this.getPts(e);this.flushDisplayed(n,t);for(var r=0;r<8;r++)i&1<<r&&(t.windows[r].visible=1);return e},Pe.prototype.hideWindows=function(e,t){var i=this.current708Packet.data[++e],n=this.getPts(e);this.flushDisplayed(n,t);for(var r=0;r<8;r++)i&1<<r&&(t.windows[r].visible=0);return e},Pe.prototype.toggleWindows=function(e,t){var i=this.current708Packet.data[++e],n=this.getPts(e);this.flushDisplayed(n,t);for(var r=0;r<8;r++)i&1<<r&&(t.windows[r].visible^=1);return e},Pe.prototype.clearWindows=function(e,t){var i=this.current708Packet.data[++e],n=this.getPts(e);this.flushDisplayed(n,t);for(var r=0;r<8;r++)i&1<<r&&t.windows[r].clearText();return e},Pe.prototype.deleteWindows=function(e,t){var i=this.current708Packet.data[++e],n=this.getPts(e);this.flushDisplayed(n,t);for(var r=0;r<8;r++)i&1<<r&&t.windows[r].reset();return e},Pe.prototype.setPenAttributes=function(e,t){var i=this.current708Packet.data,n=i[e],t=t.currentWindow.penAttr,n=i[++e];return t.textTag=(240&n)>>4,t.offset=(12&n)>>2,t.penSize=3&n,n=i[++e],t.italics=(128&n)>>7,t.underline=(64&n)>>6,t.edgeType=(56&n)>>3,t.fontStyle=7&n,e},Pe.prototype.setPenColor=function(e,t){var i=this.current708Packet.data,n=i[e],t=t.currentWindow.penColor,n=i[++e];return t.fgOpacity=(192&n)>>6,t.fgRed=(48&n)>>4,t.fgGreen=(12&n)>>2,t.fgBlue=3&n,n=i[++e],t.bgOpacity=(192&n)>>6,t.bgRed=(48&n)>>4,t.bgGreen=(12&n)>>2,t.bgBlue=3&n,n=i[++e],t.edgeRed=(48&n)>>4,t.edgeGreen=(12&n)>>2,t.edgeBlue=3&n,e},Pe.prototype.setPenLocation=function(e,t){var i=this.current708Packet.data,n=i[e],r=t.currentWindow.penLoc;return t.currentWindow.pendingNewLine=!0,n=i[++e],r.row=15&n,n=i[++e],r.column=63&n,e},Pe.prototype.reset=function(e,t){var i=this.getPts(e);return this.flushDisplayed(i,t),this.initService(t.serviceNum,e)};function Le(e){return null===e?"":(e=Oe[e]||e,String.fromCharCode(e))}function De(){for(var e=[],t=15;t--;)e.push("");return e}var Oe={42:225,92:233,94:237,95:243,96:250,123:231,124:247,125:209,126:241,127:9608,304:174,305:176,306:189,307:191,308:8482,309:162,310:163,311:9834,312:224,313:160,314:232,315:226,316:234,317:238,318:244,319:251,544:193,545:201,546:211,547:218,548:220,549:252,550:8216,551:161,552:42,553:39,554:8212,555:169,556:8480,557:8226,558:8220,559:8221,560:192,561:194,562:199,563:200,564:202,565:203,566:235,567:206,568:207,569:239,570:212,571:217,572:249,573:219,574:171,575:187,800:195,801:227,802:205,803:204,804:236,805:210,806:242,807:213,808:245,809:123,810:125,811:92,812:94,813:95,814:124,815:126,816:196,817:228,818:214,819:246,820:223,821:165,822:164,823:9474,824:197,825:229,826:216,827:248,828:9484,829:9488,830:9492,831:9496},Re=[4352,4384,4608,4640,5376,5408,5632,5664,5888,5920,4096,4864,4896,5120,5152],Me=function e(t,i){e.prototype.init.call(this),this.field_=t||0,this.dataChannel_=i||0,this.name_="CC"+(1+(this.field_<<1|this.dataChannel_)),this.setConstants(),this.reset(),this.push=function(e){var t,i,n,r,a=32639&e.ccData;a!==this.lastControlCode_?(4096==(61440&a)?this.lastControlCode_=a:a!==this.PADDING_&&(this.lastControlCode_=null),t=a>>>8,i=255&a,a===this.PADDING_||(a===this.RESUME_CAPTION_LOADING_?this.mode_="popOn":a===this.END_OF_CAPTION_?(this.mode_="popOn",this.clearFormatting(e.pts),this.flushDisplayed(e.pts),r=this.displayed_,this.displayed_=this.nonDisplayed_,this.nonDisplayed_=r,this.startPts_=e.pts):a===this.ROLL_UP_2_ROWS_?(this.rollUpRows_=2,this.setRollUp(e.pts)):a===this.ROLL_UP_3_ROWS_?(this.rollUpRows_=3,this.setRollUp(e.pts)):a===this.ROLL_UP_4_ROWS_?(this.rollUpRows_=4,this.setRollUp(e.pts)):a===this.CARRIAGE_RETURN_?(this.clearFormatting(e.pts),this.flushDisplayed(e.pts),this.shiftRowsUp_(),this.startPts_=e.pts):a===this.BACKSPACE_?"popOn"===this.mode_?this.nonDisplayed_[this.row_]=this.nonDisplayed_[this.row_].slice(0,-1):this.displayed_[this.row_]=this.displayed_[this.row_].slice(0,-1):a===this.ERASE_DISPLAYED_MEMORY_?(this.flushDisplayed(e.pts),this.displayed_=De()):a===this.ERASE_NON_DISPLAYED_MEMORY_?this.nonDisplayed_=De():a===this.RESUME_DIRECT_CAPTIONING_?("paintOn"!==this.mode_&&(this.flushDisplayed(e.pts),this.displayed_=De()),this.mode_="paintOn",this.startPts_=e.pts):this.isSpecialCharacter(t,i)?(n=Le((t=(3&t)<<8)|i),this[this.mode_](e.pts,n),this.column_++):this.isExtCharacter(t,i)?("popOn"===this.mode_?this.nonDisplayed_[this.row_]=this.nonDisplayed_[this.row_].slice(0,-1):this.displayed_[this.row_]=this.displayed_[this.row_].slice(0,-1),n=Le((t=(3&t)<<8)|i),this[this.mode_](e.pts,n),this.column_++):this.isMidRowCode(t,i)?(this.clearFormatting(e.pts),this[this.mode_](e.pts," "),this.column_++,14==(14&i)&&this.addFormatting(e.pts,["i"]),1==(1&i)&&this.addFormatting(e.pts,["u"])):this.isOffsetControlCode(t,i)?this.column_+=3&i:this.isPAC(t,i)?(r=Re.indexOf(7968&a),"rollUp"===this.mode_&&(r-this.rollUpRows_+1<0&&(r=this.rollUpRows_-1),this.setRollUp(e.pts,r)),r!==this.row_&&(this.clearFormatting(e.pts),this.row_=r),1&i&&-1===this.formatting_.indexOf("u")&&this.addFormatting(e.pts,["u"]),16==(16&a)&&(this.column_=4*((14&a)>>1)),this.isColorPAC(i)&&14==(14&i)&&this.addFormatting(e.pts,["i"])):this.isNormalChar(t)&&(0===i&&(i=null),n=Le(t),n+=Le(i),this[this.mode_](e.pts,n),this.column_+=n.length))):this.lastControlCode_=null}};Me.prototype=new j,Me.prototype.flushDisplayed=function(e){var t=this.displayed_.map(function(e,t){try{return e.trim()}catch(e){return this.trigger("log",{level:"warn",message:"Skipping a malformed 608 caption at index "+t+"."}),""}},this).join("\n").replace(/^\n+|\n+$/g,"");t.length&&this.trigger("data",{startPts:this.startPts_,endPts:e,text:t,stream:this.name_})},Me.prototype.reset=function(){this.mode_="popOn",this.topRow_=0,this.startPts_=0,this.displayed_=De(),this.nonDisplayed_=De(),this.lastControlCode_=null,this.column_=0,this.row_=14,this.rollUpRows_=2,this.formatting_=[]},Me.prototype.setConstants=function(){0===this.dataChannel_?(this.BASE_=16,this.EXT_=17,this.CONTROL_=(20|this.field_)<<8,this.OFFSET_=23):1===this.dataChannel_&&(this.BASE_=24,this.EXT_=25,this.CONTROL_=(28|this.field_)<<8,this.OFFSET_=31),this.PADDING_=0,this.RESUME_CAPTION_LOADING_=32|this.CONTROL_,this.END_OF_CAPTION_=47|this.CONTROL_,this.ROLL_UP_2_ROWS_=37|this.CONTROL_,this.ROLL_UP_3_ROWS_=38|this.CONTROL_,this.ROLL_UP_4_ROWS_=39|this.CONTROL_,this.CARRIAGE_RETURN_=45|this.CONTROL_,this.RESUME_DIRECT_CAPTIONING_=41|this.CONTROL_,this.BACKSPACE_=33|this.CONTROL_,this.ERASE_DISPLAYED_MEMORY_=44|this.CONTROL_,this.ERASE_NON_DISPLAYED_MEMORY_=46|this.CONTROL_},Me.prototype.isSpecialCharacter=function(e,t){return e===this.EXT_&&48<=t&&t<=63},Me.prototype.isExtCharacter=function(e,t){return(e===this.EXT_+1||e===this.EXT_+2)&&32<=t&&t<=63},Me.prototype.isMidRowCode=function(e,t){return e===this.EXT_&&32<=t&&t<=47},Me.prototype.isOffsetControlCode=function(e,t){return e===this.OFFSET_&&33<=t&&t<=35},Me.prototype.isPAC=function(e,t){return e>=this.BASE_&&e<this.BASE_+8&&64<=t&&t<=127},Me.prototype.isColorPAC=function(e){return 64<=e&&e<=79||96<=e&&e<=127},Me.prototype.isNormalChar=function(e){return 32<=e&&e<=127},Me.prototype.setRollUp=function(e,t){if("rollUp"!==this.mode_&&(this.row_=14,this.mode_="rollUp",this.flushDisplayed(e),this.nonDisplayed_=De(),this.displayed_=De()),void 0!==t&&t!==this.row_)for(var i=0;i<this.rollUpRows_;i++)this.displayed_[t-i]=this.displayed_[this.row_-i],this.displayed_[this.row_-i]="";void 0===t&&(t=this.row_),this.topRow_=t-this.rollUpRows_+1},Me.prototype.addFormatting=function(e,t){this.formatting_=this.formatting_.concat(t);t=t.reduce(function(e,t){return e+"<"+t+">"},"");this[this.mode_](e,t)},Me.prototype.clearFormatting=function(e){var t;this.formatting_.length&&(t=this.formatting_.reverse().reduce(function(e,t){return e+"</"+t+">"},""),this.formatting_=[],this[this.mode_](e,t))},Me.prototype.popOn=function(e,t){var i=this.nonDisplayed_[this.row_];this.nonDisplayed_[this.row_]=i+=t},Me.prototype.rollUp=function(e,t){var i=this.displayed_[this.row_];this.displayed_[this.row_]=i+=t},Me.prototype.shiftRowsUp_=function(){for(var e=0;e<this.topRow_;e++)this.displayed_[e]="";for(e=this.row_+1;e<15;e++)this.displayed_[e]="";for(e=this.topRow_;e<this.row_;e++)this.displayed_[e]=this.displayed_[e+1];this.displayed_[this.row_]=""},Me.prototype.paintOn=function(e,t){var i=this.displayed_[this.row_];this.displayed_[this.row_]=i+=t};function Ne(e,t){var i=1;for(t<e&&(i=-1);4294967296<Math.abs(t-e);)e+=8589934592*i;return e}var Ue={CaptionStream:Ce,Cea608Stream:Me,Cea708Stream:Pe},Be={H264_STREAM_TYPE:27,ADTS_STREAM_TYPE:15,METADATA_STREAM_TYPE:21},e=function e(t){var i,n;e.prototype.init.call(this),this.type_=t||"shared",this.push=function(e){"shared"!==this.type_&&e.type!==this.type_||(void 0===n&&(n=e.dts),e.dts=Ne(e.dts,n),e.pts=Ne(e.pts,n),i=e.dts,this.trigger("data",e))},this.flush=function(){n=i,this.trigger("done")},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline")},this.discontinuity=function(){i=n=void 0},this.reset=function(){this.discontinuity(),this.trigger("reset")}};e.prototype=new j;function Fe(e,t,i){for(var n="",r=t;r<i;r++)n+="%"+("00"+e[r].toString(16)).slice(-2);return n}function je(e,t,i){return decodeURIComponent(Fe(e,t,i))}function He(e){return e[0]<<21|e[1]<<14|e[2]<<7|e[3]}var qe=e,Ce=Ne,Ve={TXXX:function(e){var t;if(3===e.data[0]){for(t=1;t<e.data.length;t++)if(0===e.data[t]){e.description=je(e.data,1,t),e.value=je(e.data,t+1,e.data.length).replace(/\0*$/,"");break}e.data=e.value}},WXXX:function(e){var t;if(3===e.data[0])for(t=1;t<e.data.length;t++)if(0===e.data[t]){e.description=je(e.data,1,t),e.url=je(e.data,t+1,e.data.length);break}},PRIV:function(e){for(var t,i=0;i<e.data.length;i++)if(0===e.data[i]){e.owner=(t=e.data,unescape(Fe(t,0,i)));break}e.privateData=e.data.subarray(i+1),e.data=e.privateData}},We=function(e){var t,i={descriptor:e&&e.descriptor},u=0,l=[],c=0;if(We.prototype.init.call(this),this.dispatchType=Be.METADATA_STREAM_TYPE.toString(16),i.descriptor)for(t=0;t<i.descriptor.length;t++)this.dispatchType+=("00"+i.descriptor[t].toString(16)).slice(-2);this.push=function(e){var t,i,n,r,a,s,o;if("timed-metadata"===e.type)if(e.dataAlignmentIndicator&&(c=0,l.length=0),0===l.length&&(e.data.length<10||e.data[0]!=="I".charCodeAt(0)||e.data[1]!=="D".charCodeAt(0)||e.data[2]!=="3".charCodeAt(0)))this.trigger("log",{level:"warn",message:"Skipping unrecognized metadata packet"});else if(l.push(e),c+=e.data.byteLength,1===l.length&&(u=He(e.data.subarray(6,10)),u+=10),!(c<u)){for(t={data:new Uint8Array(u),frames:[],pts:l[0].pts,dts:l[0].dts},r=0;r<u;)t.data.set(l[0].data.subarray(0,u-r),r),r+=l[0].data.byteLength,c-=l[0].data.byteLength,l.shift();i=10,64&t.data[5]&&(i+=4,i+=He(t.data.subarray(10,14)),u-=He(t.data.subarray(16,20)));do{if((n=He(t.data.subarray(i+4,i+8)))<1)return void this.trigger("log",{level:"warn",message:"Malformed ID3 frame encountered. Skipping metadata parsing."})}while((o={id:String.fromCharCode(t.data[i],t.data[i+1],t.data[i+2],t.data[i+3]),data:t.data.subarray(i+10,i+n+10)}).key=o.id,Ve[o.id]&&(Ve[o.id](o),"com.apple.streaming.transportStreamTimestamp"===o.owner&&(s=(1&(a=o.data)[3])<<30|a[4]<<22|a[5]<<14|a[6]<<6|a[7]>>>2,s*=4,s+=3&a[7],o.timeStamp=s,void 0===t.pts&&void 0===t.dts&&(t.pts=o.timeStamp,t.dts=o.timeStamp),this.trigger("timestamp",o))),t.frames.push(o),i+=10,(i+=n)<u);this.trigger("data",t)}}};We.prototype=new j;var ze,Ge,e=We,qe=qe,Xe=function(){var r=new Uint8Array(188),a=0;Xe.prototype.init.call(this),this.push=function(e){var t,i=0,n=188;for(a?((t=new Uint8Array(e.byteLength+a)).set(r.subarray(0,a)),t.set(e,a),a=0):t=e;n<t.byteLength;)71!==t[i]||71!==t[n]?(i++,n++):(this.trigger("data",t.subarray(i,n)),i+=188,n+=188);i<t.byteLength&&(r.set(t.subarray(i),0),a=t.byteLength-i)},this.flush=function(){188===a&&71===r[0]&&(this.trigger("data",r),a=0),this.trigger("done")},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline")},this.reset=function(){a=0,this.trigger("reset")}};Xe.prototype=new j,(ze=function(){var n,r,a,s;ze.prototype.init.call(this),(s=this).packetsWaitingForPmt=[],this.programMapTable=void 0,n=function(e,t){var i=0;t.payloadUnitStartIndicator&&(i+=e[i]+1),("pat"===t.type?r:a)(e.subarray(i),t)},r=function(e,t){t.section_number=e[7],t.last_section_number=e[8],s.pmtPid=(31&e[10])<<8|e[11],t.pmtPid=s.pmtPid},a=function(e,t){var i,n;if(1&e[5]){for(s.programMapTable={video:null,audio:null,"timed-metadata":{}},i=3+((15&e[1])<<8|e[2])-4,n=12+((15&e[10])<<8|e[11]);n<i;){var r=e[n],a=(31&e[n+1])<<8|e[n+2];r===Be.H264_STREAM_TYPE&&null===s.programMapTable.video?s.programMapTable.video=a:r===Be.ADTS_STREAM_TYPE&&null===s.programMapTable.audio?s.programMapTable.audio=a:r===Be.METADATA_STREAM_TYPE&&(s.programMapTable["timed-metadata"][a]=r),n+=5+((15&e[n+3])<<8|e[n+4])}t.programMapTable=s.programMapTable}},this.push=function(e){var t={},i=4;if(t.payloadUnitStartIndicator=!!(64&e[1]),t.pid=31&e[1],t.pid<<=8,t.pid|=e[2],1<(48&e[3])>>>4&&(i+=e[i]+1),0===t.pid)t.type="pat",n(e.subarray(i),t),this.trigger("data",t);else if(t.pid===this.pmtPid)for(t.type="pmt",n(e.subarray(i),t),this.trigger("data",t);this.packetsWaitingForPmt.length;)this.processPes_.apply(this,this.packetsWaitingForPmt.shift());else void 0===this.programMapTable?this.packetsWaitingForPmt.push([e,i,t]):this.processPes_(e,i,t)},this.processPes_=function(e,t,i){i.pid===this.programMapTable.video?i.streamType=Be.H264_STREAM_TYPE:i.pid===this.programMapTable.audio?i.streamType=Be.ADTS_STREAM_TYPE:i.streamType=this.programMapTable["timed-metadata"][i.pid],i.type="pes",i.data=e.subarray(t),this.trigger("data",i)}}).prototype=new j,ze.STREAM_TYPES={h264:27,adts:15},(Ge=function(){function n(e,t,i){var n,r,a,s,o=new Uint8Array(e.size),u={type:t},l=0,c=0;if(e.data.length&&!(e.size<9)){for(u.trackId=e.data[0].pid,l=0;l<e.data.length;l++)n=e.data[l],o.set(n.data,c),c+=n.data.byteLength;a=u,s=(r=o)[0]<<16|r[1]<<8|r[2],a.data=new Uint8Array,1==s&&(a.packetLength=6+(r[4]<<8|r[5]),a.dataAlignmentIndicator=0!=(4&r[6]),192&(s=r[7])&&(a.pts=(14&r[9])<<27|(255&r[10])<<20|(254&r[11])<<12|(255&r[12])<<5|(254&r[13])>>>3,a.pts*=4,a.pts+=(6&r[13])>>>1,a.dts=a.pts,64&s&&(a.dts=(14&r[14])<<27|(255&r[15])<<20|(254&r[16])<<12|(255&r[17])<<5|(254&r[18])>>>3,a.dts*=4,a.dts+=(6&r[18])>>>1)),a.data=r.subarray(9+r[8])),t="video"===t||u.packetLength<=e.size,(i||t)&&(e.size=0,e.data.length=0),t&&d.trigger("data",u)}}var t,d=this,r=!1,a={data:[],size:0},s={data:[],size:0},o={data:[],size:0};Ge.prototype.init.call(this),this.push=function(i){({pat:function(){},pes:function(){var e,t;switch(i.streamType){case Be.H264_STREAM_TYPE:e=a,t="video";break;case Be.ADTS_STREAM_TYPE:e=s,t="audio";break;case Be.METADATA_STREAM_TYPE:e=o,t="timed-metadata";break;default:return}i.payloadUnitStartIndicator&&n(e,t,!0),e.data.push(i),e.size+=i.data.byteLength},pmt:function(){var e={type:"metadata",tracks:[]};null!==(t=i.programMapTable).video&&e.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+t.video,codec:"avc",type:"video"}),null!==t.audio&&e.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+t.audio,codec:"adts",type:"audio"}),r=!0,d.trigger("data",e)}})[i.type]()},this.reset=function(){a.size=0,a.data.length=0,s.size=0,s.data.length=0,this.trigger("reset")},this.flushStreams_=function(){n(a,"video"),n(s,"audio"),n(o,"timed-metadata")},this.flush=function(){var e;!r&&t&&(e={type:"metadata",tracks:[]},null!==t.video&&e.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+t.video,codec:"avc",type:"video"}),null!==t.audio&&e.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+t.audio,codec:"adts",type:"audio"}),d.trigger("data",e)),r=!1,this.flushStreams_(),this.trigger("done")}}).prototype=new j;var Ke,Ye={PAT_PID:0,MP2T_PACKET_LENGTH:188,TransportPacketStream:Xe,TransportParseStream:ze,ElementaryStream:Ge,TimestampRolloverStream:qe,CaptionStream:Ue.CaptionStream,Cea608Stream:Ue.Cea608Stream,Cea708Stream:Ue.Cea708Stream,MetadataStream:e};for(Ke in Be)Be.hasOwnProperty(Ke)&&(Ye[Ke]=Be[Ke]);var Qe=Ye,$e=se,Je=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350],Ze=function(u){var l,c=0;Ze.prototype.init.call(this),this.skipWarn_=function(e,t){this.trigger("log",{level:"warn",message:"adts skiping bytes "+e+" to "+t+" in frame "+c+" outside syncword"})},this.push=function(e){var t,i,n,r,a,s,o=0;if(u||(c=0),"audio"===e.type){for(l&&l.length?(n=l,(l=new Uint8Array(n.byteLength+e.data.byteLength)).set(n),l.set(e.data,n.byteLength)):l=e.data;o+7<l.length;)if(255===l[o]&&240==(246&l[o+1])){if("number"==typeof s&&(this.skipWarn_(s,o),s=null),i=2*(1&~l[o+1]),t=(3&l[o+3])<<11|l[o+4]<<3|(224&l[o+5])>>5,a=(r=1024*(1+(3&l[o+6])))*$e/Je[(60&l[o+2])>>>2],l.byteLength-o<t)break;this.trigger("data",{pts:e.pts+c*a,dts:e.dts+c*a,sampleCount:r,audioobjecttype:1+(l[o+2]>>>6&3),channelcount:(1&l[o+2])<<2|(192&l[o+3])>>>6,samplerate:Je[(60&l[o+2])>>>2],samplingfrequencyindex:(60&l[o+2])>>>2,samplesize:16,data:l.subarray(o+7+i,o+t)}),c++,o+=t}else"number"!=typeof s&&(s=o),o++;"number"==typeof s&&(this.skipWarn_(s,o),s=null),l=l.subarray(o)}},this.flush=function(){c=0,this.trigger("done")},this.reset=function(){l=void 0,this.trigger("reset")},this.endTimeline=function(){l=void 0,this.trigger("endedtimeline")}};Ze.prototype=new j;var et,tt,it=Ze,nt=function(n){var r=n.byteLength,a=0,s=0;this.length=function(){return 8*r},this.bitsAvailable=function(){return 8*r+s},this.loadWord=function(){var e=n.byteLength-r,t=new Uint8Array(4),i=Math.min(4,r);if(0===i)throw new Error("no bytes available");t.set(n.subarray(e,e+i)),a=new DataView(t.buffer).getUint32(0),s=8*i,r-=i},this.skipBits=function(e){var t;e<s||(e-=s,e-=8*(t=Math.floor(e/8)),r-=t,this.loadWord()),a<<=e,s-=e},this.readBits=function(e){var t=Math.min(s,e),i=a>>>32-t;return 0<(s-=t)?a<<=t:0<r&&this.loadWord(),0<(t=e-t)?i<<t|this.readBits(t):i},this.skipLeadingZeros=function(){for(var e=0;e<s;++e)if(0!=(a&2147483648>>>e))return a<<=e,s-=e,e;return this.loadWord(),e+this.skipLeadingZeros()},this.skipUnsignedExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros())},this.skipExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros())},this.readUnsignedExpGolomb=function(){var e=this.skipLeadingZeros();return this.readBits(e+1)-1},this.readExpGolomb=function(){var e=this.readUnsignedExpGolomb();return 1&e?1+e>>>1:-1*(e>>>1)},this.readBoolean=function(){return 1===this.readBits(1)},this.readUnsignedByte=function(){return this.readBits(8)},this.loadWord()},rt=function(){var n,r,a=0;rt.prototype.init.call(this),this.push=function(e){for(var t,i=(r=r?((t=new Uint8Array(r.byteLength+e.data.byteLength)).set(r),t.set(e.data,r.byteLength),t):e.data).byteLength;a<i-3;a++)if(1===r[a+2]){n=a+5;break}for(;n<i;)switch(r[n]){case 0:if(0!==r[n-1]){n+=2;break}if(0!==r[n-2]){n++;break}for(a+3!==n-2&&this.trigger("data",r.subarray(a+3,n-2));1!==r[++n]&&n<i;);a=n-2,n+=3;break;case 1:if(0!==r[n-1]||0!==r[n-2]){n+=3;break}this.trigger("data",r.subarray(a+3,n-2)),a=n-2,n+=3;break;default:n+=3}r=r.subarray(a),n-=a,a=0},this.reset=function(){r=null,a=0,this.trigger("reset")},this.flush=function(){r&&3<r.byteLength&&this.trigger("data",r.subarray(a+3)),r=null,a=0,this.trigger("done")},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline")}};rt.prototype=new j,tt={100:!0,110:!0,122:!0,244:!0,44:!0,83:!0,86:!0,118:!0,128:!0,138:!0,139:!0,134:!0},(et=function(){var i,n,r,a,s,o,m,t=new rt;et.prototype.init.call(this),(i=this).push=function(e){"video"===e.type&&(n=e.trackId,r=e.pts,a=e.dts,t.push(e))},t.on("data",function(e){var t={trackId:n,pts:r,dts:a,data:e,nalUnitTypeCode:31&e[0]};switch(t.nalUnitTypeCode){case 5:t.nalUnitType="slice_layer_without_partitioning_rbsp_idr";break;case 6:t.nalUnitType="sei_rbsp",t.escapedRBSP=s(e.subarray(1));break;case 7:t.nalUnitType="seq_parameter_set_rbsp",t.escapedRBSP=s(e.subarray(1)),t.config=o(t.escapedRBSP);break;case 8:t.nalUnitType="pic_parameter_set_rbsp";break;case 9:t.nalUnitType="access_unit_delimiter_rbsp"}i.trigger("data",t)}),t.on("done",function(){i.trigger("done")}),t.on("partialdone",function(){i.trigger("partialdone")}),t.on("reset",function(){i.trigger("reset")}),t.on("endedtimeline",function(){i.trigger("endedtimeline")}),this.flush=function(){t.flush()},this.partialFlush=function(){t.partialFlush()},this.reset=function(){t.reset()},this.endTimeline=function(){t.endTimeline()},m=function(e,t){for(var i=8,n=8,r=0;r<e;r++)i=0===(n=0!==n?(i+t.readExpGolomb()+256)%256:n)?i:n},s=function(e){for(var t=e.byteLength,i=[],n=1;n<t-2;)0===e[n]&&0===e[n+1]&&3===e[n+2]?(i.push(n+2),n+=2):n++;if(0===i.length)return e;for(var r=t-i.length,a=new Uint8Array(r),s=0,n=0;n<r;s++,n++)s===i[0]&&(s++,i.shift()),a[n]=e[s];return a},o=function(e){var t,i,n,r,a,s=0,o=0,u=0,l=0,c=[1,1],d=new nt(e),h=d.readUnsignedByte(),p=d.readUnsignedByte(),f=d.readUnsignedByte();if(d.skipUnsignedExpGolomb(),tt[h]&&(3===(i=d.readUnsignedExpGolomb())&&d.skipBits(1),d.skipUnsignedExpGolomb(),d.skipUnsignedExpGolomb(),d.skipBits(1),d.readBoolean()))for(r=3!==i?8:12,a=0;a<r;a++)d.readBoolean()&&m(a<6?16:64,d);if(d.skipUnsignedExpGolomb(),0===(n=d.readUnsignedExpGolomb()))d.readUnsignedExpGolomb();else if(1===n)for(d.skipBits(1),d.skipExpGolomb(),d.skipExpGolomb(),t=d.readUnsignedExpGolomb(),a=0;a<t;a++)d.skipExpGolomb();if(d.skipUnsignedExpGolomb(),d.skipBits(1),e=d.readUnsignedExpGolomb(),i=d.readUnsignedExpGolomb(),0===(n=d.readBits(1))&&d.skipBits(1),d.skipBits(1),d.readBoolean()&&(s=d.readUnsignedExpGolomb(),o=d.readUnsignedExpGolomb(),u=d.readUnsignedExpGolomb(),l=d.readUnsignedExpGolomb()),d.readBoolean()&&d.readBoolean()){switch(d.readUnsignedByte()){case 1:c=[1,1];break;case 2:c=[12,11];break;case 3:c=[10,11];break;case 4:c=[16,11];break;case 5:c=[40,33];break;case 6:c=[24,11];break;case 7:c=[20,11];break;case 8:c=[32,11];break;case 9:c=[80,33];break;case 10:c=[18,11];break;case 11:c=[15,11];break;case 12:c=[64,33];break;case 13:c=[160,99];break;case 14:c=[4,3];break;case 15:c=[3,2];break;case 16:c=[2,1];break;case 255:c=[d.readUnsignedByte()<<8|d.readUnsignedByte(),d.readUnsignedByte()<<8|d.readUnsignedByte()]}c&&(c[0],c[1])}return{profileIdc:h,levelIdc:f,profileCompatibility:p,width:16*(e+1)-2*s-2*o,height:(2-n)*(i+1)*16-2*u-2*l,sarRatio:c}}}).prototype=new j;function at(e,t){var i=0<=(i=e[t+6]<<21|e[t+7]<<14|e[t+8]<<7|e[t+9])?i:0;return(16&e[t+5])>>4?i+20:i+10}function st(e,t){return e.length-t<10||e[t]!=="I".charCodeAt(0)||e[t+1]!=="D".charCodeAt(0)||e[t+2]!=="3".charCodeAt(0)?t:st(e,t+=at(e,t))}function ot(e){return e[0]<<21|e[1]<<14|e[2]<<7|e[3]}var qe={H264Stream:et,NalByteStream:rt},ut=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350],lt={isLikelyAacData:function(e){var t=st(e,0);return e.length>=t+2&&255==(255&e[t])&&240==(240&e[t+1])&&16==(22&e[t+1])},parseId3TagSize:at,parseAdtsSize:function(e,t){var i=(224&e[t+5])>>5,n=e[t+4]<<3;return 6144&e[t+3]|n|i},parseType:function(e,t){return e[t]==="I".charCodeAt(0)&&e[t+1]==="D".charCodeAt(0)&&e[t+2]==="3".charCodeAt(0)?"timed-metadata":!0&e[t]&&240==(240&e[t+1])?"audio":null},parseSampleRate:function(e){for(var t=0;t+5<e.length;){if(255===e[t]&&240==(246&e[t+1]))return ut[(60&e[t+2])>>>2];t++}return null},parseAacTimestamp:function(e){var t,i=10;64&e[5]&&(i+=4,i+=ot(e.subarray(10,14)));do{if((t=ot(e.subarray(i+4,i+8)))<1)return null;if("PRIV"===String.fromCharCode(e[i],e[i+1],e[i+2],e[i+3]))for(var n=e.subarray(i+10,i+t+10),r=0;r<n.byteLength;r++)if(0===n[r]){if("com.apple.streaming.transportStreamTimestamp"!==unescape(function(e,t,i){for(var n="",r=t;r<i;r++)n+="%"+("00"+e[r].toString(16)).slice(-2);return n}(n,0,r)))break;var a=n.subarray(r+1),s=(1&a[3])<<30|a[4]<<22|a[5]<<14|a[6]<<6|a[7]>>>2;return s*=4,s+=3&a[7]}}while(i+=10,(i+=t)<e.byteLength);return null}},ct=function(){var a=new Uint8Array,s=0;ct.prototype.init.call(this),this.setTimestamp=function(e){s=e},this.push=function(e){var t,i,n=0,r=0;for(a.length?(i=a.length,(a=new Uint8Array(e.byteLength+i)).set(a.subarray(0,i)),a.set(e,i)):a=e;3<=a.length-r;)if(a[r]!=="I".charCodeAt(0)||a[r+1]!=="D".charCodeAt(0)||a[r+2]!=="3".charCodeAt(0))if(255!=(255&a[r])||240!=(240&a[r+1]))r++;else{if(a.length-r<7)break;if(r+(n=lt.parseAdtsSize(a,r))>a.length)break;t={type:"audio",data:a.subarray(r,r+n),pts:s,dts:s},this.trigger("data",t),r+=n}else{if(a.length-r<10)break;if(r+(n=lt.parseId3TagSize(a,r))>a.length)break;t={type:"timed-metadata",data:a.subarray(r,r+n)},this.trigger("data",t),r+=n}e=a.length-r,a=0<e?a.subarray(r):new Uint8Array},this.reset=function(){a=new Uint8Array,this.trigger("reset")},this.endTimeline=function(){a=new Uint8Array,this.trigger("endedtimeline")}};ct.prototype=new j;function dt(e,t){var i;if(e.length===t.length){for(i=0;i<e.length;i++)if(e[i]!==t[i])return;return 1}}function ht(e,t,i,n,r,a){return{start:{dts:e,pts:e+(i-t)},end:{dts:e+(n-t),pts:e+(r-i)},prependedContentDuration:a,baseMediaDecodeTime:e}}var pt,ft,mt,gt=ct,yt=["audioobjecttype","channelcount","samplerate","samplingfrequencyindex","samplesize"],vt=["width","height","profileIdc","levelIdc","profileCompatibility","sarRatio"],_t=qe.H264Stream,bt=lt.isLikelyAacData,Tt=se,St=function(a,s){var o=[],u=0,l=0,c=1/0,d=(s=s||{}).firstSequenceNumber||0;St.prototype.init.call(this),this.push=function(t){_e(a,t),a&&yt.forEach(function(e){a[e]=t[e]}),o.push(t)},this.setEarliestDts=function(e){u=e},this.setVideoBaseMediaDecodeTime=function(e){c=e},this.setAudioAppendStart=function(e){l=e},this.flush=function(){var e,t,i,n,r;0!==o.length&&(e=pe(o,a,u),a.baseMediaDecodeTime=ve(a,s.keepOriginalTimestamps),r=he(a,e,l,c),a.samples=fe(e),t=G(me(e)),o=[],n=X(d,[a]),i=new Uint8Array(n.byteLength+t.byteLength),d++,i.set(n),i.set(t,n.byteLength),ye(a),n=Math.ceil(1024*Tt/a.samplerate),e.length&&(n=e.length*n,this.trigger("segmentTimingInfo",ht(le(a.baseMediaDecodeTime,a.samplerate),e[0].dts,e[0].pts,e[0].dts+n,e[0].pts+n,r||0)),this.trigger("timingInfo",{start:e[0].pts,end:e[0].pts+n})),this.trigger("data",{track:a,boxes:i})),this.trigger("done","AudioSegmentStream")},this.reset=function(){ye(a),o=[],this.trigger("reset")}};St.prototype=new j,(pt=function(s,a){var t,i,o=[],l=[],u=(a=a||{}).firstSequenceNumber||0;pt.prototype.init.call(this),delete s.minPTS,this.gopCache_=[],this.push=function(e){_e(s,e),"seq_parameter_set_rbsp"!==e.nalUnitType||t||(t=e.config,s.sps=[e.data],vt.forEach(function(e){s[e]=t[e]},this)),"pic_parameter_set_rbsp"!==e.nalUnitType||i||(i=e.data,s.pps=[e.data]),o.push(e)},this.flush=function(){for(var e,t,i,n=0;o.length&&"access_unit_delimiter_rbsp"!==o[0].nalUnitType;)o.shift();if(0===o.length)return this.resetStream_(),void this.trigger("done","VideoSegmentStream");if(e=Y(o),(t=Q(e))[0][0].keyFrame||((i=this.getGopForFusion_(o[0],s))?(n=i.duration,t.unshift(i),t.byteLength+=i.byteLength,t.nalCount+=i.nalCount,t.pts=i.pts,t.dts=i.dts,t.duration+=i.duration):t=$(t)),l.length){var r=a.alignGopsAtEnd?this.alignGopsAtEnd_(t):this.alignGopsAtStart_(t);if(!r)return this.gopCache_.unshift({gop:t.pop(),pps:s.pps,sps:s.sps}),this.gopCache_.length=Math.min(6,this.gopCache_.length),o=[],this.resetStream_(),void this.trigger("done","VideoSegmentStream");ye(s),t=r}_e(s,t),s.samples=J(t),e=G(Z(t)),s.baseMediaDecodeTime=ve(s,a.keepOriginalTimestamps),this.trigger("processedGopsInfo",t.map(function(e){return{pts:e.pts,dts:e.dts,byteLength:e.byteLength}})),i=t[0],r=t[t.length-1],this.trigger("segmentTimingInfo",ht(s.baseMediaDecodeTime,i.dts,i.pts,r.dts+r.duration,r.pts+r.duration,n)),this.trigger("timingInfo",{start:t[0].pts,end:t[t.length-1].pts+t[t.length-1].duration}),this.gopCache_.unshift({gop:t.pop(),pps:s.pps,sps:s.sps}),this.gopCache_.length=Math.min(6,this.gopCache_.length),o=[],this.trigger("baseMediaDecodeTime",s.baseMediaDecodeTime),this.trigger("timelineStartInfo",s.timelineStartInfo),n=X(u,[s]),t=new Uint8Array(n.byteLength+e.byteLength),u++,t.set(n),t.set(e,n.byteLength),this.trigger("data",{track:s,boxes:t}),this.resetStream_(),this.trigger("done","VideoSegmentStream")},this.reset=function(){this.resetStream_(),o=[],this.gopCache_.length=0,l.length=0,this.trigger("reset")},this.resetStream_=function(){ye(s),i=t=void 0},this.getGopForFusion_=function(e){for(var t,i,n,r=1/0,a=0;a<this.gopCache_.length;a++)i=(n=this.gopCache_[a]).gop,s.pps&&dt(s.pps[0],n.pps[0])&&s.sps&&dt(s.sps[0],n.sps[0])&&(i.dts<s.timelineStartInfo.dts||-1e4<=(i=e.dts-i.dts-i.duration)&&i<=45e3&&(!t||i<r)&&(t=n,r=i));return t?t.gop:null},this.alignGopsAtStart_=function(e){for(var t,i,n,r,a=e.byteLength,s=e.nalCount,o=e.duration,u=t=0;u<l.length&&t<e.length&&(i=l[u],n=e[t],i.pts!==n.pts);)n.pts>i.pts?u++:(t++,a-=n.byteLength,s-=n.nalCount,o-=n.duration);return 0===t?e:t===e.length?null:((r=e.slice(t)).byteLength=a,r.duration=o,r.nalCount=s,r.pts=r[0].pts,r.dts=r[0].dts,r)},this.alignGopsAtEnd_=function(e){for(var t,i,n=l.length-1,r=e.length-1,a=null,s=!1;0<=n&&0<=r;){if(t=l[n],i=e[r],t.pts===i.pts){s=!0;break}t.pts>i.pts?n--:(n===l.length-1&&(a=r),r--)}if(!s&&null===a)return null;if(0===(u=s?r:a))return e;var o=e.slice(u),u=o.reduce(function(e,t){return e.byteLength+=t.byteLength,e.duration+=t.duration,e.nalCount+=t.nalCount,e},{byteLength:0,duration:0,nalCount:0});return o.byteLength=u.byteLength,o.duration=u.duration,o.nalCount=u.nalCount,o.pts=o[0].pts,o.dts=o[0].dts,o},this.alignGopsWith=function(e){l=e}}).prototype=new j,(mt=function(e,t){this.numberOfTracks=0,this.metadataStream=t,"undefined"!=typeof(e=e||{}).remux?this.remuxTracks=!!e.remux:this.remuxTracks=!0,"boolean"==typeof e.keepOriginalTimestamps?this.keepOriginalTimestamps=e.keepOriginalTimestamps:this.keepOriginalTimestamps=!1,this.pendingTracks=[],this.videoTrack=null,this.pendingBoxes=[],this.pendingCaptions=[],this.pendingMetadata=[],this.pendingBytes=0,this.emittedTracks=0,mt.prototype.init.call(this),this.push=function(e){return e.text?this.pendingCaptions.push(e):e.frames?this.pendingMetadata.push(e):(this.pendingTracks.push(e.track),this.pendingBytes+=e.boxes.byteLength,"video"===e.track.type&&(this.videoTrack=e.track,this.pendingBoxes.push(e.boxes)),void("audio"===e.track.type&&(this.audioTrack=e.track,this.pendingBoxes.unshift(e.boxes))))}}).prototype=new j,mt.prototype.flush=function(e){var t,i,n,r=0,a={captions:[],captionStreams:{},metadata:[],info:{}},s=0;if(this.pendingTracks.length<this.numberOfTracks){if("VideoSegmentStream"!==e&&"AudioSegmentStream"!==e)return;if(this.remuxTracks)return;if(0===this.pendingTracks.length)return this.emittedTracks++,void(this.emittedTracks>=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0))}if(this.videoTrack?(s=this.videoTrack.timelineStartInfo.pts,vt.forEach(function(e){a.info[e]=this.videoTrack[e]},this)):this.audioTrack&&(s=this.audioTrack.timelineStartInfo.pts,yt.forEach(function(e){a.info[e]=this.audioTrack[e]},this)),this.videoTrack||this.audioTrack){for(1===this.pendingTracks.length?a.type=this.pendingTracks[0].type:a.type="combined",this.emittedTracks+=this.pendingTracks.length,e=K(this.pendingTracks),a.initSegment=new Uint8Array(e.byteLength),a.initSegment.set(e),a.data=new Uint8Array(this.pendingBytes),n=0;n<this.pendingBoxes.length;n++)a.data.set(this.pendingBoxes[n],r),r+=this.pendingBoxes[n].byteLength;for(n=0;n<this.pendingCaptions.length;n++)(t=this.pendingCaptions[n]).startTime=de(t.startPts,s,this.keepOriginalTimestamps),t.endTime=de(t.endPts,s,this.keepOriginalTimestamps),a.captionStreams[t.stream]=!0,a.captions.push(t);for(n=0;n<this.pendingMetadata.length;n++)(i=this.pendingMetadata[n]).cueTime=de(i.pts,s,this.keepOriginalTimestamps),a.metadata.push(i);for(a.metadata.dispatchType=this.metadataStream.dispatchType,this.pendingTracks.length=0,this.videoTrack=null,this.pendingBoxes.length=0,this.pendingCaptions.length=0,this.pendingBytes=0,this.pendingMetadata.length=0,this.trigger("data",a),n=0;n<a.captions.length;n++)t=a.captions[n],this.trigger("caption",t);for(n=0;n<a.metadata.length;n++)i=a.metadata[n],this.trigger("id3Frame",i)}this.emittedTracks>=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0)},mt.prototype.setRemux=function(e){this.remuxTracks=e},(ft=function(n){var r,a,s=this,o=!0;ft.prototype.init.call(this),this.baseMediaDecodeTime=(n=n||{}).baseMediaDecodeTime||0,this.transmuxPipeline_={},this.setupAacPipeline=function(){var t={};(this.transmuxPipeline_=t).type="aac",t.metadataStream=new Qe.MetadataStream,t.aacStream=new gt,t.audioTimestampRolloverStream=new Qe.TimestampRolloverStream("audio"),t.timedMetadataTimestampRolloverStream=new Qe.TimestampRolloverStream("timed-metadata"),t.adtsStream=new it,t.coalesceStream=new mt(n,t.metadataStream),t.headOfPipeline=t.aacStream,t.aacStream.pipe(t.audioTimestampRolloverStream).pipe(t.adtsStream),t.aacStream.pipe(t.timedMetadataTimestampRolloverStream).pipe(t.metadataStream).pipe(t.coalesceStream),t.metadataStream.on("timestamp",function(e){t.aacStream.setTimestamp(e.timeStamp)}),t.aacStream.on("data",function(e){"timed-metadata"!==e.type&&"audio"!==e.type||t.audioSegmentStream||(a=a||{timelineStartInfo:{baseMediaDecodeTime:s.baseMediaDecodeTime},codec:"adts",type:"audio"},t.coalesceStream.numberOfTracks++,t.audioSegmentStream=new St(a,n),t.audioSegmentStream.on("log",s.getLogTrigger_("audioSegmentStream")),t.audioSegmentStream.on("timingInfo",s.trigger.bind(s,"audioTimingInfo")),t.adtsStream.pipe(t.audioSegmentStream).pipe(t.coalesceStream),s.trigger("trackinfo",{hasAudio:!!a,hasVideo:!!r}))}),t.coalesceStream.on("data",this.trigger.bind(this,"data")),t.coalesceStream.on("done",this.trigger.bind(this,"done"))},this.setupTsPipeline=function(){var i={};(this.transmuxPipeline_=i).type="ts",i.metadataStream=new Qe.MetadataStream,i.packetStream=new Qe.TransportPacketStream,i.parseStream=new Qe.TransportParseStream,i.elementaryStream=new Qe.ElementaryStream,i.timestampRolloverStream=new Qe.TimestampRolloverStream,i.adtsStream=new it,i.h264Stream=new _t,i.captionStream=new Qe.CaptionStream(n),i.coalesceStream=new mt(n,i.metadataStream),i.headOfPipeline=i.packetStream,i.packetStream.pipe(i.parseStream).pipe(i.elementaryStream).pipe(i.timestampRolloverStream),i.timestampRolloverStream.pipe(i.h264Stream),i.timestampRolloverStream.pipe(i.adtsStream),i.timestampRolloverStream.pipe(i.metadataStream).pipe(i.coalesceStream),i.h264Stream.pipe(i.captionStream).pipe(i.coalesceStream),i.elementaryStream.on("data",function(e){var t;if("metadata"===e.type){for(t=e.tracks.length;t--;)r||"video"!==e.tracks[t].type?a||"audio"!==e.tracks[t].type||((a=e.tracks[t]).timelineStartInfo.baseMediaDecodeTime=s.baseMediaDecodeTime):(r=e.tracks[t]).timelineStartInfo.baseMediaDecodeTime=s.baseMediaDecodeTime;r&&!i.videoSegmentStream&&(i.coalesceStream.numberOfTracks++,i.videoSegmentStream=new pt(r,n),i.videoSegmentStream.on("log",s.getLogTrigger_("videoSegmentStream")),i.videoSegmentStream.on("timelineStartInfo",function(e){a&&!n.keepOriginalTimestamps&&(a.timelineStartInfo=e,i.audioSegmentStream.setEarliestDts(e.dts-s.baseMediaDecodeTime))}),i.videoSegmentStream.on("processedGopsInfo",s.trigger.bind(s,"gopInfo")),i.videoSegmentStream.on("segmentTimingInfo",s.trigger.bind(s,"videoSegmentTimingInfo")),i.videoSegmentStream.on("baseMediaDecodeTime",function(e){a&&i.audioSegmentStream.setVideoBaseMediaDecodeTime(e)}),i.videoSegmentStream.on("timingInfo",s.trigger.bind(s,"videoTimingInfo")),i.h264Stream.pipe(i.videoSegmentStream).pipe(i.coalesceStream)),a&&!i.audioSegmentStream&&(i.coalesceStream.numberOfTracks++,i.audioSegmentStream=new St(a,n),i.audioSegmentStream.on("log",s.getLogTrigger_("audioSegmentStream")),i.audioSegmentStream.on("timingInfo",s.trigger.bind(s,"audioTimingInfo")),i.audioSegmentStream.on("segmentTimingInfo",s.trigger.bind(s,"audioSegmentTimingInfo")),i.adtsStream.pipe(i.audioSegmentStream).pipe(i.coalesceStream)),s.trigger("trackinfo",{hasAudio:!!a,hasVideo:!!r})}}),i.coalesceStream.on("data",this.trigger.bind(this,"data")),i.coalesceStream.on("id3Frame",function(e){e.dispatchType=i.metadataStream.dispatchType,s.trigger("id3Frame",e)}),i.coalesceStream.on("caption",this.trigger.bind(this,"caption")),i.coalesceStream.on("done",this.trigger.bind(this,"done"))},this.setBaseMediaDecodeTime=function(e){var t=this.transmuxPipeline_;n.keepOriginalTimestamps||(this.baseMediaDecodeTime=e),a&&(a.timelineStartInfo.dts=void 0,a.timelineStartInfo.pts=void 0,ye(a),t.audioTimestampRolloverStream&&t.audioTimestampRolloverStream.discontinuity()),r&&(t.videoSegmentStream&&(t.videoSegmentStream.gopCache_=[]),r.timelineStartInfo.dts=void 0,r.timelineStartInfo.pts=void 0,ye(r),t.captionStream.reset()),t.timestampRolloverStream&&t.timestampRolloverStream.discontinuity()},this.setAudioAppendStart=function(e){a&&this.transmuxPipeline_.audioSegmentStream.setAudioAppendStart(e)},this.setRemux=function(e){var t=this.transmuxPipeline_;n.remux=e,t&&t.coalesceStream&&t.coalesceStream.setRemux(e)},this.alignGopsWith=function(e){r&&this.transmuxPipeline_.videoSegmentStream&&this.transmuxPipeline_.videoSegmentStream.alignGopsWith(e)},this.getLogTrigger_=function(t){var i=this;return function(e){e.stream=t,i.trigger("log",e)}},this.push=function(e){if(o){var t=bt(e);if(t&&"aac"!==this.transmuxPipeline_.type?this.setupAacPipeline():t||"ts"===this.transmuxPipeline_.type||this.setupTsPipeline(),this.transmuxPipeline_)for(var i=Object.keys(this.transmuxPipeline_),n=0;n<i.length;n++){var r=i[n];"headOfPipeline"!==r&&this.transmuxPipeline_[r].on&&this.transmuxPipeline_[r].on("log",this.getLogTrigger_(r))}o=!1}this.transmuxPipeline_.headOfPipeline.push(e)},this.flush=function(){o=!0,this.transmuxPipeline_.headOfPipeline.flush()},this.endTimeline=function(){this.transmuxPipeline_.headOfPipeline.endTimeline()},this.reset=function(){this.transmuxPipeline_.headOfPipeline&&this.transmuxPipeline_.headOfPipeline.reset()},this.resetCaptions=function(){this.transmuxPipeline_.captionStream&&this.transmuxPipeline_.captionStream.reset()}}).prototype=new j;function Et(e,c){var i=Lt(e,["moof","traf"]),e=Lt(e,["mdat"]),d={},n=[];return e.forEach(function(e,t){t=i[t];n.push({mdat:e,traf:t})}),n.forEach(function(e){var t,i,n,r,a,s=e.mdat,o=e.traf,u=Lt(o,["tfhd"]),l=Nt(u[0]),e=l.trackId,u=Lt(o,["tfdt"]),u=0<u.length?Ot(u[0]).baseMediaDecodeTime:0,o=Lt(o,["trun"]);c===e&&0<o.length&&(o=o,t=u,i=(l=l).defaultSampleDuration||0,n=l.defaultSampleSize||0,r=l.trackId,a=[],o.forEach(function(e){e=Mt(e).samples;e.forEach(function(e){void 0===e.duration&&(e.duration=i),void 0===e.size&&(e.size=n),e.trackId=r,e.dts=t,void 0===e.compositionTimeOffset&&(e.compositionTimeOffset=0),e.pts=t+e.compositionTimeOffset,t+=e.duration}),a=a.concat(e)}),s=function(e,t,i){for(var n,r,a=new DataView(e.buffer,e.byteOffset,e.byteLength),s={logs:[],seiNals:[]},o=0;o+4<e.length;o+=n)if(n=a.getUint32(o),o+=4,!(n<=0))switch(31&e[o]){case 6:var u=e.subarray(o+1,o+1+n),l=function(e,t){for(var i=e,n=0;n<t.length;n++){var r=t[n];if(i<r.size)return r;i-=r.size}return null}(o,t),u={nalUnitType:"sei_rbsp",size:n,data:u,escapedRBSP:Ut(u),trackId:i};if(l)u.pts=l.pts,u.dts=l.dts,r=l;else{if(!r){s.logs.push({level:"warn",message:"We've encountered a nal unit without data at "+o+" for trackId "+i+". See mux.js#223."});break}u.pts=r.pts,u.dts=r.dts}s.seiNals.push(u)}return s}(s,a,e),d[e]||(d[e]={seiNals:[],logs:[]}),d[e].seiNals=d[e].seiNals.concat(s.seiNals),d[e].logs=d[e].logs.concat(s.logs))}),d}function kt(e){var t=31&e[1];return t<<=8,t|=e[2]}function Ct(e){return!!(64&e[1])}function wt(e){var t=0;return 1<(48&e[3])>>>4&&(t+=e[4]+1),t}function It(e){switch(e){case 5:return"slice_layer_without_partitioning_rbsp_idr";case 6:return"sei_rbsp";case 7:return"seq_parameter_set_rbsp";case 8:return"pic_parameter_set_rbsp";case 9:return"access_unit_delimiter_rbsp";default:return null}}var xt={Transmuxer:ft,VideoSegmentStream:pt,AudioSegmentStream:St,AUDIO_PROPERTIES:yt,VIDEO_PROPERTIES:vt,generateSegmentTimingInfo:ht},e=function(e){return e>>>0},At=function(e){var t="";return t+=String.fromCharCode(e[0]),t+=String.fromCharCode(e[1]),t+=String.fromCharCode(e[2]),t+=String.fromCharCode(e[3])},Pt=e,Lt=function e(t,i){var n,r,a,s=[];if(!i.length)return null;for(n=0;n<t.byteLength;)r=Pt(t[n]<<24|t[n+1]<<16|t[n+2]<<8|t[n+3]),a=At(t.subarray(n+4,n+8)),r=1<r?n+r:t.byteLength,a===i[0]&&(1===i.length?s.push(t.subarray(n+8,r)):(a=e(t.subarray(n+8,r),i.slice(1))).length&&(s=s.concat(a))),n=r;return s},Dt=e,Ot=function(e){var t={version:e[0],flags:new Uint8Array(e.subarray(1,4)),baseMediaDecodeTime:Dt(e[4]<<24|e[5]<<16|e[6]<<8|e[7])};return 1===t.version&&(t.baseMediaDecodeTime*=Math.pow(2,32),t.baseMediaDecodeTime+=Dt(e[8]<<24|e[9]<<16|e[10]<<8|e[11])),t},Rt=function(e){return{isLeading:(12&e[0])>>>2,dependsOn:3&e[0],isDependedOn:(192&e[1])>>>6,hasRedundancy:(48&e[1])>>>4,paddingValue:(14&e[1])>>>1,isNonSyncSample:1&e[1],degradationPriority:e[2]<<8|e[3]}},Mt=function(e){var t,i={version:e[0],flags:new Uint8Array(e.subarray(1,4)),samples:[]},n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=1&i.flags[2],a=4&i.flags[2],s=1&i.flags[1],o=2&i.flags[1],u=4&i.flags[1],l=8&i.flags[1],c=n.getUint32(4),d=8;for(r&&(i.dataOffset=n.getInt32(d),d+=4),a&&c&&(t={flags:Rt(e.subarray(d,d+4))},d+=4,s&&(t.duration=n.getUint32(d),d+=4),o&&(t.size=n.getUint32(d),d+=4),l&&(1===i.version?t.compositionTimeOffset=n.getInt32(d):t.compositionTimeOffset=n.getUint32(d),d+=4),i.samples.push(t),c--);c--;)t={},s&&(t.duration=n.getUint32(d),d+=4),o&&(t.size=n.getUint32(d),d+=4),u&&(t.flags=Rt(e.subarray(d,d+4)),d+=4),l&&(1===i.version?t.compositionTimeOffset=n.getInt32(d):t.compositionTimeOffset=n.getUint32(d),d+=4),i.samples.push(t);return i},Nt=function(e){var t=new DataView(e.buffer,e.byteOffset,e.byteLength),i={version:e[0],flags:new Uint8Array(e.subarray(1,4)),trackId:t.getUint32(4)},n=1&i.flags[2],r=2&i.flags[2],a=8&i.flags[2],s=16&i.flags[2],o=32&i.flags[2],u=65536&i.flags[0],l=131072&i.flags[0],e=8;return n&&(e+=4,i.baseDataOffset=t.getUint32(12),e+=4),r&&(i.sampleDescriptionIndex=t.getUint32(e),e+=4),a&&(i.defaultSampleDuration=t.getUint32(e),e+=4),s&&(i.defaultSampleSize=t.getUint32(e),e+=4),o&&(i.defaultSampleFlags=t.getUint32(e)),u&&(i.durationIsEmpty=!0),!n&&l&&(i.baseDataOffsetIsMoof=!0),i},Ut=Ee,Bt=Ue.CaptionStream,Ft=function(){var t,r,a,s,o,i,n=!1;this.isInitialized=function(){return n},this.init=function(e){t=new Bt,n=!0,i=!!e&&e.isPartial,t.on("data",function(e){e.startTime=e.startPts/s,e.endTime=e.endPts/s,o.captions.push(e),o.captionStreams[e.stream]=!0}),t.on("log",function(e){o.logs.push(e)})},this.isNewInit=function(e,t){return!(e&&0===e.length||t&&"object"==typeof t&&0===Object.keys(t).length)&&(a!==e[0]||s!==t[a])},this.parse=function(e,t,i){if(!this.isInitialized())return null;if(!t||!i)return null;if(this.isNewInit(t,i))a=t[0],s=i[a];else if(null===a||!s)return r.push(e),null;for(;0<r.length;){var n=r.shift();this.parse(n,t,i)}return(e=function(e,t,i){if(null===t)return null;t=Et(e,t)[t]||{};return{seiNals:t.seiNals,logs:t.logs,timescale:i}}(e,a,s))&&e.logs&&(o.logs=o.logs.concat(e.logs)),null!==e&&e.seiNals?(this.pushNals(e.seiNals),this.flushStream(),o):o.logs.length?{logs:o.logs,captions:[],captionStreams:[]}:null},this.pushNals=function(e){if(!this.isInitialized()||!e||0===e.length)return null;e.forEach(function(e){t.push(e)})},this.flushStream=function(){if(!this.isInitialized())return null;i?t.partialFlush():t.flush()},this.clearParsedCaptions=function(){o.captions=[],o.captionStreams={},o.logs=[]},this.resetCaptionStream=function(){if(!this.isInitialized())return null;t.reset()},this.clearAllCaptions=function(){this.clearParsedCaptions(),this.resetCaptionStream()},this.reset=function(){r=[],s=a=null,o?this.clearParsedCaptions():o={captions:[],captionStreams:{},logs:[]},this.resetCaptionStream()},this.reset()},jt=e,Ht=function(e){return("00"+e.toString(16)).slice(-2)},qe=function(e){return Lt(e,["moov","trak"]).reduce(function(e,t){var i,n,r=Lt(t,["tkhd"])[0];return r?(i=r[0],r=jt(r[n=0===i?12:20]<<24|r[1+n]<<16|r[2+n]<<8|r[3+n]),(t=Lt(t,["mdia","mdhd"])[0])?(i=t[0],e[r]=jt(t[n=0===i?12:20]<<24|t[1+n]<<16|t[2+n]<<8|t[3+n]),e):null):null},{})},j=function(n,e){var e=Lt(e,["moof","traf"]),e=[].concat.apply([],e.map(function(i){return Lt(i,["tfhd"]).map(function(e){var t=jt(e[4]<<24|e[5]<<16|e[6]<<8|e[7]),e=n[t]||9e4,t=Lt(i,["tfdt"]).map(function(e){var t=e[0],i=jt(e[4]<<24|e[5]<<16|e[6]<<8|e[7]);return 1===t&&(i*=Math.pow(2,32),i+=jt(e[8]<<24|e[9]<<16|e[10]<<8|e[11])),i})[0];return(t="number"!=typeof t||isNaN(t)?1/0:t)/e})})),e=Math.min.apply(null,e);return isFinite(e)?e:0},Ee=function(e,t){var i,n,r=Lt(t,["moof","traf"]),a=0,s=0;return r&&r.length&&(i=Lt(r[0],["tfhd"])[0],t=Lt(r[0],["trun"])[0],r=Lt(r[0],["tfdt"])[0],i&&(n=Nt(i).trackId),r&&(a=Ot(r).baseMediaDecodeTime),!t||(t=Mt(t)).samples&&t.samples.length&&(s=t.samples[0].compositionTimeOffset||0)),(a+s)/(e[n]||9e4)},qt=function(e){var t=0===e[0]?12:20;return jt(e[t]<<24|e[1+t]<<16|e[2+t]<<8|e[3+t])},e=function(e){var e=Lt(e,["moov","trak"]),s=[];return e.forEach(function(e){var t={},i=Lt(e,["tkhd"])[0];i&&(i=(n=new DataView(i.buffer,i.byteOffset,i.byteLength)).getUint8(0),t.id=0===i?n.getUint32(12):n.getUint32(20));var n=Lt(e,["mdia","hdlr"])[0];n&&(a=At(n.subarray(8,12)),t.type="vide"===a?"video":"soun"===a?"audio":a);var r,a=Lt(e,["mdia","minf","stbl","stsd"])[0];a&&(a=a.subarray(8),t.codec=At(a.subarray(4,8)),(a=Lt(a,[t.codec])[0])&&(/^[a-z]vc[1-9]$/i.test(t.codec)?(r=a.subarray(78),"avcC"===At(r.subarray(4,8))&&11<r.length?(t.codec+=".",t.codec+=Ht(r[9]),t.codec+=Ht(r[10]),t.codec+=Ht(r[11])):t.codec="avc1.4d400d"):/^mp4[a,v]$/i.test(t.codec)?(r=a.subarray(28),"esds"===At(r.subarray(4,8))&&20<r.length&&0!==r[19]?(t.codec+="."+Ht(r[19]),t.codec+="."+Ht(r[20]>>>2&63).replace(/^0/,"")):t.codec="mp4a.40.2"):t.codec=t.codec.toLowerCase()));e=Lt(e,["mdia","mdhd"])[0];e&&(t.timescale=qt(e)),s.push(t)}),s},Vt=j,Wt=e,zt=Ce,Gt={};Gt.ts={parseType:function(e,t){e=kt(e);return 0===e?"pat":e===t?"pmt":t?"pes":null},parsePat:function(e){var t=Ct(e),i=4+wt(e);return t&&(i+=e[i]+1),(31&e[i+10])<<8|e[i+11]},parsePmt:function(e){var t={},i=Ct(e),n=4+wt(e);if(i&&(n+=e[n]+1),1&e[n+5]){for(var r=3+((15&e[n+1])<<8|e[n+2])-4,a=12+((15&e[n+10])<<8|e[n+11]);a<r;){var s=n+a;t[(31&e[s+1])<<8|e[s+2]]=e[s],a+=5+((15&e[s+3])<<8|e[s+4])}return t}},parsePayloadUnitStartIndicator:Ct,parsePesType:function(e,t){switch(t[kt(e)]){case Be.H264_STREAM_TYPE:return"video";case Be.ADTS_STREAM_TYPE:return"audio";case Be.METADATA_STREAM_TYPE:return"timed-metadata";default:return null}},parsePesTime:function(e){if(!Ct(e))return null;var t=4+wt(e);if(t>=e.byteLength)return null;var i=null,n=e[t+7];return 192&n&&((i={}).pts=(14&e[t+9])<<27|(255&e[t+10])<<20|(254&e[t+11])<<12|(255&e[t+12])<<5|(254&e[t+13])>>>3,i.pts*=4,i.pts+=(6&e[t+13])>>>1,i.dts=i.pts,64&n&&(i.dts=(14&e[t+14])<<27|(255&e[t+15])<<20|(254&e[t+16])<<12|(255&e[t+17])<<5|(254&e[t+18])>>>3,i.dts*=4,i.dts+=(6&e[t+18])>>>1)),i},videoPacketContainsKeyFrame:function(e){for(var t=4+wt(e),i=e.subarray(t),n=0,r=0,a=!1;r<i.byteLength-3;r++)if(1===i[r+2]){n=r+5;break}for(;n<i.byteLength;)switch(i[n]){case 0:if(0!==i[n-1]){n+=2;break}if(0!==i[n-2]){n++;break}for(r+3!==n-2&&"slice_layer_without_partitioning_rbsp_idr"===It(31&i[r+3])&&(a=!0);1!==i[++n]&&n<i.length;);r=n-2,n+=3;break;case 1:if(0!==i[n-1]||0!==i[n-2]){n+=3;break}"slice_layer_without_partitioning_rbsp_idr"===It(31&i[r+3])&&(a=!0),r=n-2,n+=3;break;default:n+=3}return i=i.subarray(r),n-=r,r=0,a=i&&3<i.byteLength&&"slice_layer_without_partitioning_rbsp_idr"===It(31&i[r+3])?!0:a}},Gt.aac=lt;function Xt(e,t,i){for(var n,r,a,s,o=0,u=188,l=!1;u<=e.byteLength;)if(71!==e[o]||71!==e[u]&&u!==e.byteLength)o++,u++;else{if(n=e.subarray(o,u),"pes"===Gt.ts.parseType(n,t.pid)&&(r=Gt.ts.parsePesType(n,t.table),a=Gt.ts.parsePayloadUnitStartIndicator(n),"audio"===r&&a&&(s=Gt.ts.parsePesTime(n))&&(s.type="audio",i.audio.push(s),l=!0)),l)break;o+=188,u+=188}for(o=(u=e.byteLength)-188,l=!1;0<=o;)if(71!==e[o]||71!==e[u]&&u!==e.byteLength)o--,u--;else{if(n=e.subarray(o,u),"pes"===Gt.ts.parseType(n,t.pid)&&(r=Gt.ts.parsePesType(n,t.table),a=Gt.ts.parsePayloadUnitStartIndicator(n),"audio"===r&&a&&(s=Gt.ts.parsePesTime(n))&&(s.type="audio",i.audio.push(s),l=!0)),l)break;o-=188,u-=188}}function Kt(e){var t,i={pid:null,table:null},n={};for(t in!function(e,t){for(var i,n=0,r=188;r<e.byteLength;)if(71!==e[n]||71!==e[r])n++,r++;else{switch(i=e.subarray(n,r),Gt.ts.parseType(i,t.pid)){case"pat":t.pid=Gt.ts.parsePat(i);break;case"pmt":var a=Gt.ts.parsePmt(i);t.table=t.table||{},Object.keys(a).forEach(function(e){t.table[e]=a[e]})}n+=188,r+=188}}(e,i),i.table)if(i.table.hasOwnProperty(t))switch(i.table[t]){case Be.H264_STREAM_TYPE:n.video=[],function(e,t,i){for(var n,r,a,s,o,u,l,c,d=0,h=188,p=!1,f={data:[],size:0};h<e.byteLength;)if(71!==e[d]||71!==e[h])d++,h++;else{if(n=e.subarray(d,h),"pes"===Gt.ts.parseType(n,t.pid))if(r=Gt.ts.parsePesType(n,t.table),a=Gt.ts.parsePayloadUnitStartIndicator(n),"video"===r&&(a&&!p&&(s=Gt.ts.parsePesTime(n))&&(s.type="video",i.video.push(s),p=!0),!i.firstKeyFrame)){if(a&&0!==f.size){for(o=new Uint8Array(f.size),u=0;f.data.length;)l=f.data.shift(),o.set(l,u),u+=l.byteLength;!Gt.ts.videoPacketContainsKeyFrame(o)||(c=Gt.ts.parsePesTime(o))&&(i.firstKeyFrame=c,i.firstKeyFrame.type="video"),f.size=0}f.data.push(n),f.size+=n.byteLength}if(p&&i.firstKeyFrame)break;d+=188,h+=188}for(d=(h=e.byteLength)-188,p=!1;0<=d;)if(71!==e[d]||71!==e[h])d--,h--;else{if(n=e.subarray(d,h),"pes"===Gt.ts.parseType(n,t.pid)&&(r=Gt.ts.parsePesType(n,t.table),a=Gt.ts.parsePayloadUnitStartIndicator(n),"video"===r&&a&&(s=Gt.ts.parsePesTime(n))&&(s.type="video",i.video.push(s),p=!0)),p)break;d-=188,h-=188}}(e,i,n),0===n.video.length&&delete n.video;break;case Be.ADTS_STREAM_TYPE:n.audio=[],Xt(e,i,n),0===n.audio.length&&delete n.audio}return n}var Yt=se,Qt=function(e,t){var i,n,r=(Gt.aac.isLikelyAacData(e)?function(e){for(var t,i=!1,n=0,r=null,a=null,s=0,o=0;3<=e.length-o;){switch(Gt.aac.parseType(e,o)){case"timed-metadata":if(e.length-o<10){i=!0;break}if((s=Gt.aac.parseId3TagSize(e,o))>e.length){i=!0;break}null===a&&(t=e.subarray(o,o+s),a=Gt.aac.parseAacTimestamp(t)),o+=s;break;case"audio":if(e.length-o<7){i=!0;break}if((s=Gt.aac.parseAdtsSize(e,o))>e.length){i=!0;break}null===r&&(t=e.subarray(o,o+s),r=Gt.aac.parseSampleRate(t)),n++,o+=s;break;default:o++}if(i)return null}if(null===r||null===a)return null;var u=Yt/r;return{audio:[{type:"audio",dts:a,pts:a},{type:"audio",dts:a+1024*n*u,pts:a+1024*n*u}]}}:Kt)(e);return r&&(r.audio||r.video)?(e=t,(t=r).audio&&t.audio.length&&("undefined"!=typeof(i=e)&&!isNaN(i)||(i=t.audio[0].dts),t.audio.forEach(function(e){e.dts=zt(e.dts,i),e.pts=zt(e.pts,i),e.dtsTime=e.dts/Yt,e.ptsTime=e.pts/Yt})),t.video&&t.video.length&&("undefined"!=typeof(n=e)&&!isNaN(n)||(n=t.video[0].dts),t.video.forEach(function(e){e.dts=zt(e.dts,n),e.pts=zt(e.pts,n),e.dtsTime=e.dts/Yt,e.ptsTime=e.pts/Yt}),t.firstKeyFrame&&((t=t.firstKeyFrame).dts=zt(t.dts,n),t.pts=zt(t.pts,n),t.dtsTime=t.dts/Yt,t.ptsTime=t.pts/Yt)),r):null},$t=function(){function e(e,t){this.options=t||{},this.self=e,this.init()}var t=e.prototype;return t.init=function(){var i,e;this.transmuxer&&this.transmuxer.dispose(),this.transmuxer=new xt.Transmuxer(this.options),i=this.self,(e=this.transmuxer).on("data",function(e){var t=e.initSegment;e.initSegment={data:t.buffer,byteOffset:t.byteOffset,byteLength:t.byteLength};t=e.data;e.data=t.buffer,i.postMessage({action:"data",segment:e,byteOffset:t.byteOffset,byteLength:t.byteLength},[e.data])}),e.on("done",function(e){i.postMessage({action:"done"})}),e.on("gopInfo",function(e){i.postMessage({action:"gopInfo",gopInfo:e})}),e.on("videoSegmentTimingInfo",function(e){var t={start:{decode:ue(e.start.dts),presentation:ue(e.start.pts)},end:{decode:ue(e.end.dts),presentation:ue(e.end.pts)},baseMediaDecodeTime:ue(e.baseMediaDecodeTime)};e.prependedContentDuration&&(t.prependedContentDuration=ue(e.prependedContentDuration)),i.postMessage({action:"videoSegmentTimingInfo",videoSegmentTimingInfo:t})}),e.on("audioSegmentTimingInfo",function(e){var t={start:{decode:ue(e.start.dts),presentation:ue(e.start.pts)},end:{decode:ue(e.end.dts),presentation:ue(e.end.pts)},baseMediaDecodeTime:ue(e.baseMediaDecodeTime)};e.prependedContentDuration&&(t.prependedContentDuration=ue(e.prependedContentDuration)),i.postMessage({action:"audioSegmentTimingInfo",audioSegmentTimingInfo:t})}),e.on("id3Frame",function(e){i.postMessage({action:"id3Frame",id3Frame:e})}),e.on("caption",function(e){i.postMessage({action:"caption",caption:e})}),e.on("trackinfo",function(e){i.postMessage({action:"trackinfo",trackInfo:e})}),e.on("audioTimingInfo",function(e){i.postMessage({action:"audioTimingInfo",audioTimingInfo:{start:ue(e.start),end:ue(e.end)}})}),e.on("videoTimingInfo",function(e){i.postMessage({action:"videoTimingInfo",videoTimingInfo:{start:ue(e.start),end:ue(e.end)}})}),e.on("log",function(e){i.postMessage({action:"log",log:e})})},t.pushMp4Captions=function(e){this.captionParser||(this.captionParser=new Ft,this.captionParser.init());var t=new Uint8Array(e.data,e.byteOffset,e.byteLength),e=this.captionParser.parse(t,e.trackIds,e.timescales);this.self.postMessage({action:"mp4Captions",captions:e&&e.captions||[],logs:e&&e.logs||[],data:t.buffer},[t.buffer])},t.probeMp4StartTime=function(e){var t=e.timescales,e=e.data,t=Vt(t,e);this.self.postMessage({action:"probeMp4StartTime",startTime:t,data:e},[e.buffer])},t.probeMp4Tracks=function(e){var t=e.data,e=Wt(t);this.self.postMessage({action:"probeMp4Tracks",tracks:e,data:t},[t.buffer])},t.probeTs=function(e){var t=e.data,i=e.baseStartTime,e="number"!=typeof i||isNaN(i)?void 0:i*se,i=Qt(t,e),e=null;i&&((e={hasVideo:i.video&&2===i.video.length||!1,hasAudio:i.audio&&2===i.audio.length||!1}).hasVideo&&(e.videoStart=i.video[0].ptsTime),e.hasAudio&&(e.audioStart=i.audio[0].ptsTime)),this.self.postMessage({action:"probeTs",result:e,data:t},[t.buffer])},t.clearAllMp4Captions=function(){this.captionParser&&this.captionParser.clearAllCaptions()},t.clearParsedMp4Captions=function(){this.captionParser&&this.captionParser.clearParsedCaptions()},t.push=function(e){e=new Uint8Array(e.data,e.byteOffset,e.byteLength);this.transmuxer.push(e)},t.reset=function(){this.transmuxer.reset()},t.setTimestampOffset=function(e){e=e.timestampOffset||0;this.transmuxer.setBaseMediaDecodeTime(Math.round(oe(e)))},t.setAudioAppendStart=function(e){this.transmuxer.setAudioAppendStart(Math.ceil(oe(e.appendStart)))},t.setRemux=function(e){this.transmuxer.setRemux(e.remux)},t.flush=function(e){this.transmuxer.flush(),self.postMessage({action:"done",type:"transmuxed"})},t.endTimeline=function(){this.transmuxer.endTimeline(),self.postMessage({action:"endedtimeline",type:"transmuxed"})},t.alignGopsWith=function(e){this.transmuxer.alignGopsWith(e.gopsToAlignWith.slice())},e}();self.onmessage=function(e){"init"===e.data.action&&e.data.options?this.messageHandlers=new $t(self,e.data.options):(this.messageHandlers||(this.messageHandlers=new $t(self)),e.data&&e.data.action&&"init"!==e.data.action&&this.messageHandlers[e.data.action]&&this.messageHandlers[e.data.action](e.data))}}))),sl=function(e){e.currentTransmux=null,e.transmuxQueue.length&&(e.currentTransmux=e.transmuxQueue.shift(),"function"==typeof e.currentTransmux?e.currentTransmux():hu(e.currentTransmux))},ol=function(e){fu("reset",e)},ul=function(e){var t=new al;t.currentTransmux=null,t.transmuxQueue=[];var i=t.terminate;return t.terminate=function(){return t.currentTransmux=null,t.transmuxQueue.length=0,i.call(t)},t.postMessage({action:"init",options:e}),t},ll=2,cl=-101,dl=-102,hl=yo("CodecUtils"),pl=yo("PlaylistSelector"),Kt=function(){var e=this.useDevicePixelRatio&&_.devicePixelRatio||1;return Nu(this.playlists.master,this.systemBandwidth,parseInt(Ou(this.tech_.el(),"width"),10)*e,parseInt(Ou(this.tech_.el(),"height"),10)*e,this.limitRenditionByPlayerDimensions,this.masterPlaylistController_)},fl=function(n){function e(e,t){var i=n.call(this)||this;if(!e)throw new TypeError("Initialization settings are required");if("function"!=typeof e.currentTime)throw new TypeError("No currentTime getter specified");if(!e.mediaSource)throw new TypeError("No MediaSource specified");return i.bandwidth=e.bandwidth,i.throughput={rate:0,count:0},i.roundTrip=NaN,i.resetStats_(),i.mediaIndex=null,i.partIndex=null,i.hasPlayed_=e.hasPlayed,i.currentTime_=e.currentTime,i.seekable_=e.seekable,i.seeking_=e.seeking,i.duration_=e.duration,i.mediaSource_=e.mediaSource,i.vhs_=e.vhs,i.loaderType_=e.loaderType,i.currentMediaInfo_=void 0,i.startingMediaInfo_=void 0,i.segmentMetadataTrack_=e.segmentMetadataTrack,i.goalBufferLength_=e.goalBufferLength,i.sourceType_=e.sourceType,i.sourceUpdater_=e.sourceUpdater,i.inbandTextTracks_=e.inbandTextTracks,i.state_="INIT",i.timelineChangeController_=e.timelineChangeController,i.shouldSaveSegmentTimingInfo_=!0,i.parse708captions_=e.parse708captions,i.experimentalExactManifestTimings=e.experimentalExactManifestTimings,i.checkBufferTimeout_=null,i.error_=void 0,i.currentTimeline_=-1,i.pendingSegment_=null,i.xhrOptions_=null,i.pendingSegments_=[],i.audioDisabled_=!1,i.isPendingTimestampOffset_=!1,i.gopBuffer_=[],i.timeMapping_=0,i.safeAppend_=11<=ir.browser.IE_VERSION,i.appendInitSegment_={audio:!0,video:!0},i.playlistOfLastInitSegment_={audio:null,video:null},i.callQueue_=[],i.loadQueue_=[],i.metadataQueue_={id3:[],caption:[]},i.waitingOnRemove_=!1,i.quotaExceededErrorRetryTimeout_=null,i.activeInitSegmentId_=null,i.initSegments_={},i.cacheEncryptionKeys_=e.cacheEncryptionKeys,i.keyCache_={},i.decrypter_=e.decrypter,i.syncController_=e.syncController,i.syncPoint_={segmentIndex:0,time:0},i.transmuxer_=i.createTransmuxer_(),i.triggerSyncInfoUpdate_=function(){return i.trigger("syncinfoupdate")},i.syncController_.on("syncinfoupdate",i.triggerSyncInfoUpdate_),i.mediaSource_.addEventListener("sourceopen",function(){i.isEndOfStream_()||(i.ended_=!1)}),i.fetchAtBuffer_=!1,i.logger_=yo("SegmentLoader["+i.loaderType_+"]"),Object.defineProperty(yt(i),"state",{get:function(){return this.state_},set:function(e){e!==this.state_&&(this.logger_(this.state_+" -> "+e),this.state_=e,this.trigger("statechange"))}}),i.sourceUpdater_.on("ready",function(){i.hasEnoughInfoToAppend_()&&i.processCallQueue_()}),"main"===i.loaderType_&&i.timelineChangeController_.on("pendingtimelinechange",function(){i.hasEnoughInfoToAppend_()&&i.processCallQueue_()}),"audio"===i.loaderType_&&i.timelineChangeController_.on("timelinechange",function(){i.hasEnoughInfoToLoad_()&&i.processLoadQueue_(),i.hasEnoughInfoToAppend_()&&i.processCallQueue_()}),i}vt(e,n);var t=e.prototype;return t.createTransmuxer_=function(){return ul({remux:!1,alignGopsAtEnd:this.safeAppend_,keepOriginalTimestamps:!0,parse708captions:this.parse708captions_})},t.resetStats_=function(){this.mediaBytesTransferred=0,this.mediaRequests=0,this.mediaRequestsAborted=0,this.mediaRequestsTimedout=0,this.mediaRequestsErrored=0,this.mediaTransferDuration=0,this.mediaSecondsLoaded=0,this.mediaAppends=0},t.dispose=function(){this.trigger("dispose"),this.state="DISPOSED",this.pause(),this.abort_(),this.transmuxer_&&this.transmuxer_.terminate(),this.resetStats_(),this.checkBufferTimeout_&&_.clearTimeout(this.checkBufferTimeout_),this.syncController_&&this.triggerSyncInfoUpdate_&&this.syncController_.off("syncinfoupdate",this.triggerSyncInfoUpdate_),this.off()},t.setAudio=function(e){this.audioDisabled_=!e,e?this.appendInitSegment_.audio=!0:this.sourceUpdater_.removeAudio(0,this.duration_())},t.abort=function(){"WAITING"===this.state?(this.abort_(),this.state="READY",this.paused()||this.monitorBuffer_()):this.pendingSegment_&&(this.pendingSegment_=null)},t.abort_=function(){this.pendingSegment_&&this.pendingSegment_.abortRequests&&this.pendingSegment_.abortRequests(),this.pendingSegment_=null,this.callQueue_=[],this.loadQueue_=[],this.metadataQueue_.id3=[],this.metadataQueue_.caption=[],this.timelineChangeController_.clearPendingTimelineChange(this.loaderType_),this.waitingOnRemove_=!1,_.clearTimeout(this.quotaExceededErrorRetryTimeout_),this.quotaExceededErrorRetryTimeout_=null},t.checkForAbort_=function(e){return"APPENDING"!==this.state||this.pendingSegment_?!this.pendingSegment_||this.pendingSegment_.requestId!==e:(this.state="READY",!0)},t.error=function(e){return"undefined"!=typeof e&&(this.logger_("error occurred:",e),this.error_=e),this.pendingSegment_=null,this.error_},t.endOfStream=function(){this.ended_=!0,this.transmuxer_&&ol(this.transmuxer_),this.gopBuffer_.length=0,this.pause(),this.trigger("ended")},t.buffered_=function(){var e=this.getMediaInfo_();if(!this.sourceUpdater_||!e)return ir.createTimeRanges();if("main"===this.loaderType_){var t=e.hasAudio,i=e.hasVideo,e=e.isMuxed;if(i&&t&&!this.audioDisabled_&&!e)return this.sourceUpdater_.buffered();if(i)return this.sourceUpdater_.videoBuffered()}return this.sourceUpdater_.audioBuffered()},t.initSegmentForMap=function(e,t){if(void 0===t&&(t=!1),!e)return null;var i=iu(e),n=this.initSegments_[i];return t&&!n&&e.bytes&&(this.initSegments_[i]=n={resolvedUri:e.resolvedUri,byterange:e.byterange,bytes:e.bytes,tracks:e.tracks,timescales:e.timescales}),n||e},t.segmentKey=function(e,t){if(void 0===t&&(t=!1),!e)return null;var i=nu(e),n=this.keyCache_[i];this.cacheEncryptionKeys_&&t&&!n&&e.bytes&&(this.keyCache_[i]=n={resolvedUri:e.resolvedUri,bytes:e.bytes});e={resolvedUri:(n||e).resolvedUri};return n&&(e.bytes=n.bytes),e},t.couldBeginLoading_=function(){return this.playlist_&&!this.paused()},t.load=function(){if(this.monitorBuffer_(),this.playlist_)return"INIT"===this.state&&this.couldBeginLoading_()?this.init_():void(!this.couldBeginLoading_()||"READY"!==this.state&&"INIT"!==this.state||(this.state="READY"))},t.init_=function(){return this.state="READY",this.resetEverything(),this.monitorBuffer_()},t.playlist=function(e,t){if(void 0===t&&(t={}),e){var i=this.playlist_,n=this.pendingSegment_;this.playlist_=e,this.xhrOptions_=t,"INIT"===this.state&&(e.syncInfo={mediaSequence:e.mediaSequence,time:0},"main"===this.loaderType_&&this.syncController_.setDateTimeMappingForStart(e));var r=null;if(i&&(i.id?r=i.id:i.uri&&(r=i.uri)),this.logger_("playlist update ["+r+" => "+(e.id||e.uri)+"]"),this.trigger("syncinfoupdate"),"INIT"===this.state&&this.couldBeginLoading_())return this.init_();if(!i||i.uri!==e.uri)return null!==this.mediaIndex&&this.resyncLoader(),this.currentMediaInfo_=void 0,void this.trigger("playlistupdate");t=e.mediaSequence-i.mediaSequence;this.logger_("live window shift ["+t+"]"),null!==this.mediaIndex&&(this.mediaIndex-=t,this.mediaIndex<0?(this.mediaIndex=null,this.partIndex=null):(r=this.playlist_.segments[this.mediaIndex],!this.partIndex||r.parts&&r.parts.length&&r.parts[this.partIndex]||(r=this.mediaIndex,this.logger_("currently processing part (index "+this.partIndex+") no longer exists."),this.resetLoader(),this.mediaIndex=r))),n&&(n.mediaIndex-=t,n.mediaIndex<0?(n.mediaIndex=null,n.partIndex=null):(0<=n.mediaIndex&&(n.segment=e.segments[n.mediaIndex]),0<=n.partIndex&&n.segment.parts&&(n.part=n.segment.parts[n.partIndex]))),this.syncController_.saveExpiredSegmentInfo(i,e)}},t.pause=function(){this.checkBufferTimeout_&&(_.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=null)},t.paused=function(){return null===this.checkBufferTimeout_},t.resetEverything=function(e){this.ended_=!1,this.appendInitSegment_={audio:!0,video:!0},this.resetLoader(),this.remove(0,1/0,e),this.transmuxer_&&this.transmuxer_.postMessage({action:"clearAllMp4Captions"})},t.resetLoader=function(){this.fetchAtBuffer_=!1,this.resyncLoader()},t.resyncLoader=function(){this.transmuxer_&&ol(this.transmuxer_),this.mediaIndex=null,this.partIndex=null,this.syncPoint_=null,this.isPendingTimestampOffset_=!1,this.callQueue_=[],this.loadQueue_=[],this.metadataQueue_.id3=[],this.metadataQueue_.caption=[],this.abort(),this.transmuxer_&&this.transmuxer_.postMessage({action:"clearParsedMp4Captions"})},t.remove=function(e,t,i,n){if(void 0===i&&(i=function(){}),void 0===n&&(n=!1),(t=t===1/0?this.duration_():t)<=e)this.logger_("skipping remove because end ${end} is <= start ${start}");else if(this.sourceUpdater_&&this.getMediaInfo_()){var r,a=1,s=function(){0===--a&&i()};for(r in!n&&this.audioDisabled_||(a++,this.sourceUpdater_.removeAudio(e,t,s)),!n&&"main"!==this.loaderType_||(this.gopBuffer_=function(e,t,i,n){for(var r=Math.ceil((t-n)*Gu),a=Math.ceil((i-n)*Gu),n=e.slice(),s=e.length;s--&&!(e[s].pts<=a););if(-1===s)return n;for(var o=s+1;o--&&!(e[o].pts<=r););return o=Math.max(o,0),n.splice(o,s-o+1),n}(this.gopBuffer_,e,t,this.timeMapping_),a++,this.sourceUpdater_.removeVideo(e,t,s)),this.inbandTextTracks_)Bu(e,t,this.inbandTextTracks_[r]);Bu(e,t,this.segmentMetadataTrack_),s()}else this.logger_("skipping remove because no source updater or starting media info")},t.monitorBuffer_=function(){this.checkBufferTimeout_&&_.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=_.setTimeout(this.monitorBufferTick_.bind(this),1)},t.monitorBufferTick_=function(){"READY"===this.state&&this.fillBuffer_(),this.checkBufferTimeout_&&_.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=_.setTimeout(this.monitorBufferTick_.bind(this),500)},t.fillBuffer_=function(){var e;this.sourceUpdater_.updating()||(e=this.chooseNextRequest_())&&("number"==typeof e.timestampOffset&&(this.isPendingTimestampOffset_=!1,this.timelineChangeController_.pendingTimelineChange({type:this.loaderType_,from:this.currentTimeline_,to:e.timeline})),this.loadSegment_(e))},t.isEndOfStream_=function(e,t,i){if(void 0===e&&(e=this.mediaIndex),void 0===t&&(t=this.playlist_),void 0===i&&(i=this.partIndex),!t||!this.mediaSource_)return!1;var n="number"==typeof e&&t.segments[e],e=e+1===t.segments.length,n=!n||!n.parts||i+1===n.parts.length;return t.endList&&"open"===this.mediaSource_.readyState&&e&&n},t.chooseNextRequest_=function(){var e=Eo(this.buffered_())||0,t=Math.max(0,e-this.currentTime_()),i=!this.hasPlayed_()&&1<=t,n=t>=this.goalBufferLength_(),r=this.playlist_.segments;if(!r.length||i||n)return null;this.syncPoint_=this.syncPoint_||this.syncController_.getSyncPoint(this.playlist_,this.duration_(),this.currentTimeline_,this.currentTime_());t={partIndex:null,mediaIndex:null,startOfSegment:null,playlist:this.playlist_,isSyncRequest:Boolean(!this.syncPoint_)};t.isSyncRequest?t.mediaIndex=function(e,t,i){t=t||[];for(var n=[],r=0,a=0;a<t.length;a++){var s=t[a];if(e===s.timeline&&(n.push(a),i<(r+=s.duration)))return a}return 0===n.length?0:n[n.length-1]}(this.currentTimeline_,r,e):null!==this.mediaIndex?(i=r[this.mediaIndex],n="number"==typeof this.partIndex?this.partIndex:-1,t.startOfSegment=i.end||e,i.parts&&i.parts[n+1]?(t.mediaIndex=this.mediaIndex,t.partIndex=n+1):t.mediaIndex=this.mediaIndex+1):(e=(s=Qu.getMediaInfoForTime({experimentalExactManifestTimings:this.experimentalExactManifestTimings,playlist:this.playlist_,currentTime:this.fetchAtBuffer_?e:this.currentTime_(),startingPartIndex:this.syncPoint_.partIndex,startingSegmentIndex:this.syncPoint_.segmentIndex,startTime:this.syncPoint_.time})).segmentIndex,a=s.startTime,s=s.partIndex,t.getMediaInfoForTime=this.fetchAtBuffer_?"bufferedEnd":"currentTime",t.mediaIndex=e,t.startOfSegment=a,t.partIndex=s);var a=r[t.mediaIndex],s=a&&"number"==typeof t.partIndex&&a.parts&&a.parts[t.partIndex];if(!a||"number"==typeof t.partIndex&&!s)return null;"number"!=typeof t.partIndex&&a.parts&&(t.partIndex=0);a=this.mediaSource_&&"ended"===this.mediaSource_.readyState;return t.mediaIndex>=r.length-1&&a&&!this.seeking_()?null:this.generateSegmentInfo_(t)},t.generateSegmentInfo_=function(e){var t=e.playlist,i=e.mediaIndex,n=e.startOfSegment,r=e.isSyncRequest,a=e.partIndex,s=e.forceTimestampOffset,o=e.getMediaInfoForTime,u=t.segments[i],e="number"==typeof a&&u.parts[a],o={requestId:"segment-loader-"+Math.random(),uri:e&&e.resolvedUri||u.resolvedUri,mediaIndex:i,partIndex:e?a:null,isSyncRequest:r,startOfSegment:n,playlist:t,bytes:null,encryptedBytes:null,timestampOffset:null,timeline:u.timeline,duration:e&&e.duration||u.duration,segment:u,part:e,byteLength:0,transmuxer:this.transmuxer_,getMediaInfoForTime:o},s="undefined"!=typeof s?s:this.isPendingTimestampOffset_;o.timestampOffset=this.timestampOffsetForSegment_({segmentTimeline:u.timeline,currentTimeline:this.currentTimeline_,startOfSegment:n,buffered:this.buffered_(),overrideCheck:s});s=Eo(this.sourceUpdater_.audioBuffered());return"number"==typeof s&&(o.audioAppendStart=s-this.sourceUpdater_.audioTimestampOffset()),this.sourceUpdater_.videoBuffered().length&&(o.gopsToAlignWith=function(e,t,i){if("undefined"==typeof t||null===t||!e.length)return[];for(var n=Math.ceil((t-i+3)*Gu),r=0;r<e.length&&!(e[r].pts>n);r++);return e.slice(r)}(this.gopBuffer_,this.currentTime_()-this.sourceUpdater_.videoTimestampOffset(),this.timeMapping_)),o},t.timestampOffsetForSegment_=function(e){return i=(t=e).segmentTimeline,n=t.currentTimeline,r=t.startOfSegment,e=t.buffered,t.overrideCheck||i!==n?!(i<n)&&e.length?e.end(e.length-1):r:null;var t,i,n,r},t.earlyAbortWhenNeeded_=function(e){var t,i,n,r,a,s,o,u,l,c,d,h,p;!this.vhs_.tech_.paused()&&this.xhrOptions_.timeout&&this.playlist_.attributes.BANDWIDTH&&(Date.now()-(e.firstBytesReceivedAt||Date.now())<1e3||(t=this.currentTime_(),r=e.bandwidth,a=this.pendingSegment_.duration,p=Qu.estimateSegmentRequestTime(a,r,this.playlist_,e.bytesReceived),i=this.buffered_(),n=t,void 0===(e=this.vhs_.tech_.playbackRate())&&(e=1),p<=(e=((i.length?i.end(i.length-1):0)-n)/e-1)||(r={master:this.vhs_.playlists.master,currentTime:t,bandwidth:r,duration:this.duration_(),segmentDuration:a,timeUntilRebuffer:e,currentTimeline:this.currentTimeline_,syncController:this.syncController_},a=r.master,s=r.currentTime,o=r.bandwidth,u=r.duration,l=r.segmentDuration,c=r.timeUntilRebuffer,d=r.currentTimeline,h=r.syncController,a=(r=(a=!(a=(r=a.playlists.filter(function(e){return!Qu.isIncompatible(e)})).filter(Qu.isEnabled)).length?r.filter(function(e){return!Qu.isDisabled(e)}):a).filter(Qu.hasAttribute.bind(null,"BANDWIDTH")).map(function(e){var t=h.getSyncPoint(e,u,d,s)?1:2;return{playlist:e,rebufferingImpact:Qu.estimateSegmentRequestTime(l,o,e)*t-c}})).filter(function(e){return e.rebufferingImpact<=0}),Ru(a,function(e,t){return Mu(t.playlist,e.playlist)}),(r=a.length?a[0]:(Ru(r,function(e,t){return e.rebufferingImpact-t.rebufferingImpact}),r[0]||null))&&(p=p-e-r.rebufferingImpact,!r.playlist||r.playlist.uri===this.playlist_.uri||p<(e<=Ku?1:.5)||(this.bandwidth=r.playlist.attributes.BANDWIDTH*rl.BANDWIDTH_VARIANCE+1,this.trigger("earlyabort"))))))},t.handleAbort_=function(e){this.logger_("Aborting "+ju(e)),this.mediaRequestsAborted+=1},t.handleProgress_=function(e,t){this.earlyAbortWhenNeeded_(t.stats),this.checkForAbort_(t.requestId)||this.trigger("progress")},t.handleTrackInfo_=function(e,t){this.earlyAbortWhenNeeded_(e.stats),this.checkForAbort_(e.requestId)||this.checkForIllegalMediaSwitch(t)||(function(e,t){if(!e&&!t||!e&&t||e&&!t)return!1;if(e===t)return!0;var i=Object.keys(e).sort(),n=Object.keys(t).sort();if(i.length!==n.length)return!1;for(var r=0;r<i.length;r++){var a=i[r];if(a!==n[r])return!1;if(e[a]!==t[a])return!1}return!0}(this.currentMediaInfo_,t=t||{})||(this.appendInitSegment_={audio:!0,video:!0},this.startingMediaInfo_=t,this.currentMediaInfo_=t,this.logger_("trackinfo update",t),this.trigger("trackinfo")),this.checkForAbort_(e.requestId)||(this.pendingSegment_.trackInfo=t,this.hasEnoughInfoToAppend_()&&this.processCallQueue_()))},t.handleTimingInfo_=function(e,t,i,n){var r;this.earlyAbortWhenNeeded_(e.stats),this.checkForAbort_(e.requestId)||((r=this.pendingSegment_)[e=Hu(t)]=r[e]||{},r[e][i]=n,this.logger_("timinginfo: "+t+" - "+i+" - "+n),this.hasEnoughInfoToAppend_()&&this.processCallQueue_())},t.handleCaptions_=function(e,t){var g,y,v=this;this.earlyAbortWhenNeeded_(e.stats),this.checkForAbort_(e.requestId)||(0!==t.length?this.pendingSegment_.hasAppendedData_?(g=null===this.sourceUpdater_.videoTimestampOffset()?this.sourceUpdater_.audioTimestampOffset():this.sourceUpdater_.videoTimestampOffset(),y={},t.forEach(function(e){y[e.stream]=y[e.stream]||{startTime:1/0,captions:[],endTime:0};var t=y[e.stream];t.startTime=Math.min(t.startTime,e.startTime+g),t.endTime=Math.max(t.endTime,e.endTime+g),t.captions.push(e)}),Object.keys(y).forEach(function(e){var t,i,n,r,a,s,o,u,l,c,d=y[e],h=d.startTime,p=d.endTime,f=d.captions,m=v.inbandTextTracks_;v.logger_("adding cues from "+h+" -> "+p+" for "+e),t=m,i=v.vhs_.tech_,t[n=e]||(i.trigger({type:"usage",name:"vhs-608"}),i.trigger({type:"usage",name:"hls-608"}),/^cc708_/.test(r=n)&&(r="SERVICE"+n.split("_")[1]),(o=i.textTracks().getTrackById(r))?t[n]=o:(s=a=n,d=!1,(o=(i.options_.vhs&&i.options_.vhs.captionServices||{})[r])&&(a=o.label,s=o.language,d=o.default),t[n]=i.addRemoteTextTrack({kind:"captions",id:r,default:d,label:a,language:s},!1).track)),Bu(h,p,m[e]),l=(f={captionArray:f,inbandTextTracks:m,timestampOffset:g}).inbandTextTracks,m=f.captionArray,c=f.timestampOffset,m&&(u=_.WebKitDataCue||_.VTTCue,m.forEach(function(e){var t=e.stream;l[t].addCue(new u(e.startTime+c,e.endTime+c,e.text))}))}),this.transmuxer_&&this.transmuxer_.postMessage({action:"clearParsedMp4Captions"})):this.metadataQueue_.caption.push(this.handleCaptions_.bind(this,e,t)):this.logger_("SegmentLoader received no captions from a caption event"))},t.handleId3_=function(e,t,i){var n,r,a,s;this.earlyAbortWhenNeeded_(e.stats),this.checkForAbort_(e.requestId)||(this.pendingSegment_.hasAppendedData_?(n=null===this.sourceUpdater_.videoTimestampOffset()?this.sourceUpdater_.audioTimestampOffset():this.sourceUpdater_.videoTimestampOffset(),r=this.inbandTextTracks_,a=i,s=this.vhs_.tech_,r.metadataTrack_||(r.metadataTrack_=s.addRemoteTextTrack({kind:"metadata",label:"Timed Metadata"},!1).track,r.metadataTrack_.inBandMetadataTrackDispatchType=a),Uu({inbandTextTracks:this.inbandTextTracks_,metadataArray:t,timestampOffset:n,videoDuration:this.duration_()})):this.metadataQueue_.id3.push(this.handleId3_.bind(this,e,t,i)))},t.processMetadataQueue_=function(){this.metadataQueue_.id3.forEach(function(e){return e()}),this.metadataQueue_.caption.forEach(function(e){return e()}),this.metadataQueue_.id3=[],this.metadataQueue_.caption=[]},t.processCallQueue_=function(){var e=this.callQueue_;this.callQueue_=[],e.forEach(function(e){return e()})},t.processLoadQueue_=function(){var e=this.loadQueue_;this.loadQueue_=[],e.forEach(function(e){return e()})},t.hasEnoughInfoToLoad_=function(){if("audio"!==this.loaderType_)return!0;var e=this.pendingSegment_;return!!e&&(!this.getCurrentMediaInfo_()||!qu({timelineChangeController:this.timelineChangeController_,currentTimeline:this.currentTimeline_,segmentTimeline:e.timeline,loaderType:this.loaderType_,audioDisabled:this.audioDisabled_}))},t.getCurrentMediaInfo_=function(e){return(e=void 0===e?this.pendingSegment_:e)&&e.trackInfo||this.currentMediaInfo_},t.getMediaInfo_=function(e){return void 0===e&&(e=this.pendingSegment_),this.getCurrentMediaInfo_(e)||this.startingMediaInfo_},t.hasEnoughInfoToAppend_=function(){if(!this.sourceUpdater_.ready())return!1;if(this.waitingOnRemove_||this.quotaExceededErrorRetryTimeout_)return!1;var e=this.pendingSegment_,t=this.getCurrentMediaInfo_();if(!e||!t)return!1;var i=t.hasAudio,n=t.hasVideo,t=t.isMuxed;return!(n&&!e.videoTimingInfo)&&(!(i&&!this.audioDisabled_&&!t&&!e.audioTimingInfo)&&!qu({timelineChangeController:this.timelineChangeController_,currentTimeline:this.currentTimeline_,segmentTimeline:e.timeline,loaderType:this.loaderType_,audioDisabled:this.audioDisabled_}))},t.handleData_=function(e,t){if(this.earlyAbortWhenNeeded_(e.stats),!this.checkForAbort_(e.requestId))if(!this.callQueue_.length&&this.hasEnoughInfoToAppend_()){var i,n=this.pendingSegment_;if(this.setTimeMapping_(n.timeline),this.updateMediaSecondsLoaded_(n.segment),"closed"!==this.mediaSource_.readyState){if(e.map&&(e.map=this.initSegmentForMap(e.map,!0),n.segment.map=e.map),e.key&&this.segmentKey(e.key,!0),n.isFmp4=e.isFmp4,n.timingInfo=n.timingInfo||{},n.isFmp4?(this.trigger("fmp4"),n.timingInfo.start=n[Hu(t.type)].start):(i=this.getCurrentMediaInfo_(),(i="main"===this.loaderType_&&i&&i.hasVideo)&&(r=n.videoTimingInfo.start),n.timingInfo.start=this.trueSegmentStart_({currentStart:n.timingInfo.start,playlist:n.playlist,mediaIndex:n.mediaIndex,currentVideoTimestampOffset:this.sourceUpdater_.videoTimestampOffset(),useVideoTimingInfo:i,firstVideoFrameTimeForData:r,videoTimingInfo:n.videoTimingInfo,audioTimingInfo:n.audioTimingInfo})),this.updateAppendInitSegmentStatus(n,t.type),this.updateSourceBufferTimestampOffset_(n),n.isSyncRequest){this.updateTimingInfoEnd_(n),this.syncController_.saveSegmentTimingInfo({segmentInfo:n,shouldSaveTimelineMapping:"main"===this.loaderType_});var r=this.chooseNextRequest_();if(r.mediaIndex!==n.mediaIndex||r.partIndex!==n.partIndex)return void this.logger_("sync segment was incorrect, not appending");this.logger_("sync segment was correct, appending")}n.hasAppendedData_=!0,this.processMetadataQueue_(),this.appendData_(n,t)}}else this.callQueue_.push(this.handleData_.bind(this,e,t))},t.updateAppendInitSegmentStatus=function(e,t){"main"!==this.loaderType_||"number"!=typeof e.timestampOffset||e.changedTimestampOffset||(this.appendInitSegment_={audio:!0,video:!0}),this.playlistOfLastInitSegment_[t]!==e.playlist&&(this.appendInitSegment_[t]=!0)},t.getInitSegmentAndUpdateState_=function(e){var t=e.type,i=e.initSegment,n=e.map,r=e.playlist;if(n){e=iu(n);if(this.activeInitSegmentId_===e)return null;i=this.initSegmentForMap(n,!0).bytes,this.activeInitSegmentId_=e}return i&&this.appendInitSegment_[t]?(this.playlistOfLastInitSegment_[t]=r,this.appendInitSegment_[t]=!1,this.activeInitSegmentId_=null,i):null},t.handleQuotaExceededError_=function(e,t){var i=this,n=e.segmentInfo,r=e.type,a=e.bytes,s=this.sourceUpdater_.audioBuffered(),o=this.sourceUpdater_.videoBuffered();1<s.length&&this.logger_("On QUOTA_EXCEEDED_ERR, found gaps in the audio buffer: "+So(s).join(", ")),1<o.length&&this.logger_("On QUOTA_EXCEEDED_ERR, found gaps in the video buffer: "+So(o).join(", "));var u=s.length?s.start(0):0,l=s.length?s.end(s.length-1):0,c=o.length?o.start(0):0,e=o.length?o.end(o.length-1):0;if(l-u<=1&&e-c<=1)return this.logger_("On QUOTA_EXCEEDED_ERR, single segment too large to append to buffer, triggering an error. Appended byte length: "+a.byteLength+", audio buffer: "+So(s).join(", ")+", video buffer: "+So(o).join(", ")+", "),this.error({message:"Quota exceeded error with append of a single segment of content",excludeUntil:1/0}),void this.trigger("error");this.waitingOnRemove_=!0,this.callQueue_.push(this.appendToSourceBuffer_.bind(this,{segmentInfo:n,type:r,bytes:a}));a=this.currentTime_()-1;this.logger_("On QUOTA_EXCEEDED_ERR, removing audio/video from 0 to "+a),this.remove(0,a,function(){i.logger_("On QUOTA_EXCEEDED_ERR, retrying append in 1s"),i.waitingOnRemove_=!1,i.quotaExceededErrorRetryTimeout_=_.setTimeout(function(){i.logger_("On QUOTA_EXCEEDED_ERR, re-processing call queue"),i.quotaExceededErrorRetryTimeout_=null,i.processCallQueue_()},1e3)},!0)},t.handleAppendError_=function(e,t){var i=e.segmentInfo,n=e.type,e=e.bytes;t&&(22!==t.code?(this.logger_("Received non QUOTA_EXCEEDED_ERR on append",t),this.error(n+" append of "+e.length+"b failed for segment #"+i.mediaIndex+" in playlist "+i.playlist.id),this.trigger("appenderror")):this.handleQuotaExceededError_({segmentInfo:i,type:n,bytes:e}))},t.appendToSourceBuffer_=function(e){var t,i,n=e.segmentInfo,r=e.type,a=e.initSegment,s=e.data,o=e.bytes;o||(e=[s],s=s.byteLength,a&&(e.unshift(a),s+=a.byteLength),i=0,(e={bytes:s,segments:e}).bytes&&(t=new Uint8Array(e.bytes),e.segments.forEach(function(e){t.set(e,i),i+=e.byteLength})),o=t),this.sourceUpdater_.appendBuffer({segmentInfo:n,type:r,bytes:o},this.handleAppendError_.bind(this,{segmentInfo:n,type:r,bytes:o}))},t.handleSegmentTimingInfo_=function(e,t,i){this.pendingSegment_&&t===this.pendingSegment_.requestId&&((t=this.pendingSegment_.segment)[e=e+"TimingInfo"]||(t[e]={}),t[e].transmuxerPrependedSeconds=i.prependedContentDuration||0,t[e].transmuxedPresentationStart=i.start.presentation,t[e].transmuxedDecodeStart=i.start.decode,t[e].transmuxedPresentationEnd=i.end.presentation,t[e].transmuxedDecodeEnd=i.end.decode,t[e].baseMediaDecodeTime=i.baseMediaDecodeTime)},t.appendData_=function(e,t){var i=t.type,n=t.data;n&&n.byteLength&&("audio"===i&&this.audioDisabled_||(t=this.getInitSegmentAndUpdateState_({type:i,initSegment:t.initSegment,playlist:e.playlist,map:e.isFmp4?e.segment.map:null}),this.appendToSourceBuffer_({segmentInfo:e,type:i,initSegment:t,data:n})))},t.loadSegment_=function(t){var i=this;this.state="WAITING",this.pendingSegment_=t,this.trimBackBuffer_(t),"number"==typeof t.timestampOffset&&this.transmuxer_&&this.transmuxer_.postMessage({action:"clearAllMp4Captions"}),this.hasEnoughInfoToLoad_()?this.updateTransmuxerAndRequestSegment_(t):this.loadQueue_.push(function(){var e=b({},t,{forceTimestampOffset:!0});b(t,i.generateSegmentInfo_(e)),i.isPendingTimestampOffset_=!1,i.updateTransmuxerAndRequestSegment_(t)})},t.updateTransmuxerAndRequestSegment_=function(n){var r=this;this.shouldUpdateTransmuxerTimestampOffset_(n.timestampOffset)&&(this.gopBuffer_.length=0,n.gopsToAlignWith=[],this.timeMapping_=0,this.transmuxer_.postMessage({action:"reset"}),this.transmuxer_.postMessage({action:"setTimestampOffset",timestampOffset:n.timestampOffset}));var e=this.createSimplifiedSegmentObj_(n),t=this.isEndOfStream_(n.mediaIndex,n.playlist,n.partIndex),i=null!==this.mediaIndex,a=n.timeline!==this.currentTimeline_&&0<n.timeline,a=t||i&&a;this.logger_("Requesting "+ju(n)),e.map&&!e.map.bytes&&(this.logger_("going to request init segment."),this.appendInitSegment_={video:!0,audio:!0}),n.abortRequests=Iu({xhr:this.vhs_.xhr,xhrOptions:this.xhrOptions_,decryptionWorker:this.decrypter_,segment:e,abortFn:this.handleAbort_.bind(this,n),progressFn:this.handleProgress_.bind(this),trackInfoFn:this.handleTrackInfo_.bind(this),timingInfoFn:this.handleTimingInfo_.bind(this),videoSegmentTimingInfoFn:this.handleSegmentTimingInfo_.bind(this,"video",n.requestId),audioSegmentTimingInfoFn:this.handleSegmentTimingInfo_.bind(this,"audio",n.requestId),captionsFn:this.handleCaptions_.bind(this),isEndOfTimeline:a,endedTimelineFn:function(){r.logger_("received endedtimeline callback")},id3Fn:this.handleId3_.bind(this),dataFn:this.handleData_.bind(this),doneFn:this.segmentRequestFinished_.bind(this),onTransmuxerLog:function(e){var t=e.message,i=e.level,e=e.stream;r.logger_(ju(n)+" logged from transmuxer stream "+e+" as a "+i+": "+t)}})},t.trimBackBuffer_=function(e){var t,i,n,r,r=(t=this.seekable_(),i=this.currentTime_(),n=this.playlist_.targetDuration||10,r=i-rl.BACK_BUFFER_LENGTH,t.length&&(r=Math.max(r,t.start(0))),Math.min(i-n,r));0<r&&this.remove(0,r)},t.createSimplifiedSegmentObj_=function(e){var t=e.segment,i=e.part,n={resolvedUri:(i||t).resolvedUri,byterange:(i||t).byterange,requestId:e.requestId,transmuxer:e.transmuxer,audioAppendStart:e.audioAppendStart,gopsToAlignWith:e.gopsToAlignWith,part:e.part},i=e.playlist.segments[e.mediaIndex-1];return i&&i.timeline===t.timeline&&(i.videoTimingInfo?n.baseStartTime=i.videoTimingInfo.transmuxedDecodeEnd:i.audioTimingInfo&&(n.baseStartTime=i.audioTimingInfo.transmuxedDecodeEnd)),t.key&&(e=t.key.iv||new Uint32Array([0,0,0,e.mediaIndex+e.playlist.mediaSequence]),n.key=this.segmentKey(t.key),n.key.iv=e),t.map&&(n.map=this.initSegmentForMap(t.map)),n},t.saveTransferStats_=function(e){this.mediaRequests+=1,e&&(this.mediaBytesTransferred+=e.bytesReceived,this.mediaTransferDuration+=e.roundTripTime)},t.saveBandwidthRelatedStats_=function(e,t){this.pendingSegment_.byteLength=t.bytesReceived,e<1/60?this.logger_("Ignoring segment's bandwidth because its duration of "+e+" is less than the min to record "+1/60):(this.bandwidth=t.bandwidth,this.roundTrip=t.roundTripTime)},t.handleTimeout_=function(){this.mediaRequestsTimedout+=1,this.bandwidth=1,this.roundTrip=NaN,this.trigger("bandwidthupdate")},t.segmentRequestFinished_=function(e,t,i){if(this.callQueue_.length)this.callQueue_.push(this.segmentRequestFinished_.bind(this,e,t,i));else if(this.saveTransferStats_(t.stats),this.pendingSegment_&&t.requestId===this.pendingSegment_.requestId){if(e)return this.pendingSegment_=null,this.state="READY",e.code===dl?void 0:(this.pause(),e.code===cl?void this.handleTimeout_():(this.mediaRequestsErrored+=1,this.error(e),void this.trigger("error")));e=this.pendingSegment_;this.saveBandwidthRelatedStats_(e.duration,t.stats),e.endOfAllRequests=t.endOfAllRequests,i.gopInfo&&(this.gopBuffer_=function(e,t,i){if(!t.length)return e;if(i)return t.slice();for(var n=t[0].pts,r=0;r<e.length&&!(e[r].pts>=n);r++);return e.slice(0,r).concat(t)}(this.gopBuffer_,i.gopInfo,this.safeAppend_)),this.state="APPENDING",this.trigger("appending"),this.waitForAppendsToComplete_(e)}},t.setTimeMapping_=function(e){e=this.syncController_.mappingForTimeline(e);null!==e&&(this.timeMapping_=e)},t.updateMediaSecondsLoaded_=function(e){"number"==typeof e.start&&"number"==typeof e.end?this.mediaSecondsLoaded+=e.end-e.start:this.mediaSecondsLoaded+=e.duration},t.shouldUpdateTransmuxerTimestampOffset_=function(e){return null!==e&&("main"===this.loaderType_&&e!==this.sourceUpdater_.videoTimestampOffset()||!this.audioDisabled_&&e!==this.sourceUpdater_.audioTimestampOffset())},t.trueSegmentStart_=function(e){var t=e.currentStart,i=e.playlist,n=e.mediaIndex,r=e.firstVideoFrameTimeForData,a=e.currentVideoTimestampOffset,s=e.useVideoTimingInfo,o=e.videoTimingInfo,e=e.audioTimingInfo;if("undefined"!=typeof t)return t;if(!s)return e.start;i=i.segments[n-1];return 0!==n&&i&&"undefined"!=typeof i.start&&i.end===r+a?o.start:r},t.waitForAppendsToComplete_=function(e){var t=this.getCurrentMediaInfo_(e);if(!t)return this.error({message:"No starting media returned, likely due to an unsupported media format.",blacklistDuration:1/0}),void this.trigger("error");var i=t.hasAudio,n=t.hasVideo,t=t.isMuxed,n="main"===this.loaderType_&&n,t=!this.audioDisabled_&&i&&!t;if(e.waitingOnAppends=0,!e.hasAppendedData_)return e.timingInfo||"number"!=typeof e.timestampOffset||(this.isPendingTimestampOffset_=!0),e.timingInfo={start:0},e.waitingOnAppends++,this.isPendingTimestampOffset_||(this.updateSourceBufferTimestampOffset_(e),this.processMetadataQueue_()),void this.checkAppendsDone_(e);n&&e.waitingOnAppends++,t&&e.waitingOnAppends++,n&&this.sourceUpdater_.videoQueueCallback(this.checkAppendsDone_.bind(this,e)),t&&this.sourceUpdater_.audioQueueCallback(this.checkAppendsDone_.bind(this,e))},t.checkAppendsDone_=function(e){this.checkForAbort_(e.requestId)||(e.waitingOnAppends--,0===e.waitingOnAppends&&this.handleAppendsDone_())},t.checkForIllegalMediaSwitch=function(e){var t,i,e=(t=this.loaderType_,i=this.getCurrentMediaInfo_(),e=e,"main"===t&&i&&e?e.hasAudio||e.hasVideo?i.hasVideo&&!e.hasVideo?"Only audio found in segment when we expected video. We can't switch to audio only from a stream that had video. To get rid of this message, please add codec information to the manifest.":!i.hasVideo&&e.hasVideo?"Video found in segment when we expected only audio. We can't switch to a stream with video from an audio only stream. To get rid of this message, please add codec information to the manifest.":null:"Neither audio nor video found in segment.":null);return!!e&&(this.error({message:e,blacklistDuration:1/0}),this.trigger("error"),!0)},t.updateSourceBufferTimestampOffset_=function(e){var t;null===e.timestampOffset||"number"!=typeof e.timingInfo.start||e.changedTimestampOffset||"main"!==this.loaderType_||(t=!1,e.timestampOffset-=e.timingInfo.start,e.changedTimestampOffset=!0,e.timestampOffset!==this.sourceUpdater_.videoTimestampOffset()&&(this.sourceUpdater_.videoTimestampOffset(e.timestampOffset),t=!0),e.timestampOffset!==this.sourceUpdater_.audioTimestampOffset()&&(this.sourceUpdater_.audioTimestampOffset(e.timestampOffset),t=!0),t&&this.trigger("timestampoffset"))},t.updateTimingInfoEnd_=function(e){e.timingInfo=e.timingInfo||{};var t=this.getMediaInfo_(),t="main"===this.loaderType_&&t&&t.hasVideo&&e.videoTimingInfo?e.videoTimingInfo:e.audioTimingInfo;t&&(e.timingInfo.end="number"==typeof t.end?t.end:t.start+e.duration)},t.handleAppendsDone_=function(){if(this.pendingSegment_&&this.trigger("appendsdone"),!this.pendingSegment_)return this.state="READY",void(this.paused()||this.monitorBuffer_());var e=this.pendingSegment_;this.updateTimingInfoEnd_(e),this.shouldSaveSegmentTimingInfo_&&this.syncController_.saveSegmentTimingInfo({segmentInfo:e,shouldSaveTimelineMapping:"main"===this.loaderType_});var t=Wu(e,this.sourceType_);t&&("warn"===t.severity?ir.log.warn(t.message):this.logger_(t.message)),this.recordThroughput_(e),this.pendingSegment_=null,this.state="READY",!e.isSyncRequest||(this.trigger("syncinfoupdate"),e.hasAppendedData_)?(this.logger_("Appended "+ju(e)),this.addSegmentMetadataCue_(e),this.fetchAtBuffer_=!0,this.currentTimeline_!==e.timeline&&(this.timelineChangeController_.lastTimelineChange({type:this.loaderType_,from:this.currentTimeline_,to:e.timeline}),"main"!==this.loaderType_||this.audioDisabled_||this.timelineChangeController_.lastTimelineChange({type:"audio",from:this.currentTimeline_,to:e.timeline})),this.currentTimeline_=e.timeline,this.trigger("syncinfoupdate"),(t=e.segment).end&&this.currentTime_()-t.end>3*e.playlist.targetDuration?this.resetEverything():(null!==this.mediaIndex&&this.trigger("bandwidthupdate"),this.trigger("progress"),this.mediaIndex=e.mediaIndex,this.partIndex=e.partIndex,this.isEndOfStream_(e.mediaIndex,e.playlist,e.partIndex)&&this.endOfStream(),this.trigger("appended"),e.hasAppendedData_&&this.mediaAppends++,this.paused()||this.monitorBuffer_())):this.logger_("Throwing away un-appended sync request "+ju(e))},t.recordThroughput_=function(e){var t,i;e.duration<1/60?this.logger_("Ignoring segment's throughput because its duration of "+e.duration+" is less than the min to record "+1/60):(t=this.throughput.rate,i=Date.now()-e.endOfAllRequests+1,i=Math.floor(e.byteLength/i*8*1e3),this.throughput.rate+=(i-t)/++this.throughput.count)},t.addSegmentMetadataCue_=function(e){var t,i,n,r;this.segmentMetadataTrack_&&(i=(t=e.segment).start,r=t.end,Fu(i)&&Fu(r)&&(Bu(i,r,this.segmentMetadataTrack_),n=_.WebKitDataCue||_.VTTCue,e={custom:t.custom,dateTimeObject:t.dateTimeObject,dateTimeString:t.dateTimeString,bandwidth:e.playlist.attributes.BANDWIDTH,resolution:e.playlist.attributes.RESOLUTION,codecs:e.playlist.attributes.CODECS,byteLength:e.byteLength,uri:e.uri,timeline:e.timeline,playlist:e.playlist.id,start:i,end:r},(r=new n(i,r,JSON.stringify(e))).value=e,this.segmentMetadataTrack_.addCue(r)))},e}(ir.EventTarget);function ml(){}function gl(e){return"string"!=typeof e?e:e.replace(/./,function(e){return e.toUpperCase()})}function yl(e,t){var i=t[e+"Buffer"];return i&&i.updating||t.queuePending[e]}function vl(e,t){if(0!==t.queue.length){var i=0,n=t.queue[i];if("mediaSource"!==n.type){if("mediaSource"!==e&&t.ready()&&"closed"!==t.mediaSource.readyState&&!yl(e,t)){if(n.type!==e){if(null===(i=function(e,t){for(var i=0;i<t.length;i++){var n=t[i];if("mediaSource"===n.type)return null;if(n.type===e)return i}return null}(e,t.queue)))return;n=t.queue[i]}t.queue.splice(i,1),(t.queuePending[e]=n).action(e,t),n.doneFn||(t.queuePending[e]=null,vl(e,t))}}else t.updating()||"closed"===t.mediaSource.readyState||(t.queue.shift(),n.action(t),n.doneFn&&n.doneFn(),vl("audio",t),vl("video",t))}}function _l(e,t){var i=t[e+"Buffer"],n=gl(e);i&&(i.removeEventListener("updateend",t["on"+n+"UpdateEnd_"]),i.removeEventListener("error",t["on"+n+"Error_"]),t.codecs[e]=null,t[e+"Buffer"]=null)}function bl(e,t){return e&&t&&-1!==Array.prototype.indexOf.call(e.sourceBuffers,t)}function Tl(e){var t=e.type,i=e.sourceUpdater,n=e.action,r=e.doneFn,e=e.name;i.queue.push({type:t,action:n,doneFn:r,name:e}),vl(t,i)}function Sl(i,n){return function(e){var t;n.queuePending[i]&&(t=n.queuePending[i].doneFn,n.queuePending[i]=null,t&&t(n[i+"Error_"])),vl(i,n)}}function El(e){return decodeURIComponent(escape(String.fromCharCode.apply(null,e)))}function kl(e,t){e.abort(),e.pause(),t&&t.activePlaylistLoader&&(t.activePlaylistLoader.pause(),t.activePlaylistLoader=null)}function Cl(e,t){(t.activePlaylistLoader=e).load()}function wl(e,t){for(var i=0;i<e.length;i++){if(Uo(t,e[i]))return!0;if(e[i].playlists&&wl(e[i].playlists,t))return!0}return!1}function Il(a){["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach(function(e){$l[e](e,a)});var e,s=a.mediaTypes,t=a.masterPlaylistLoader,i=a.tech,n=a.vhs,r=a.segmentLoaders,o=r.AUDIO,u=r.main;function l(){s.AUDIO.onTrackChanged(),i.trigger({type:"usage",name:"vhs-audio-change"}),i.trigger({type:"usage",name:"hls-audio-change"})}for(e in["AUDIO","SUBTITLES"].forEach(function(e){var u,l,o,c,t,i,d,h,n,r;s[e].activeGroup=(u=e,l=a,function(t){var e=l.masterPlaylistLoader,i=l.mediaTypes[u].groups,n=e.media();if(!n)return null;var r=null;n.attributes[u]&&(r=i[n.attributes[u]]);var a=Object.keys(i);if(!r)if("AUDIO"===u&&1<a.length&&Fo(l.master))for(var s=0;s<a.length;s++){var o=i[a[s]];if(wl(o,n)){r=o;break}}else i.main?r=i.main:1===a.length&&(r=i[a[0]]);return"undefined"==typeof t?r:null!==t&&r&&r.filter(function(e){return e.id===t.id})[0]||null}),s[e].activeTrack=Jl[e](e,a),s[e].onGroupChanged=(o=e,c=a,function(){var e=c.segmentLoaders,t=e[o],i=e.main,n=c.mediaTypes[o],r=n.activeTrack(),a=n.getActiveGroup(),s=n.activePlaylistLoader,e=n.lastGroup_;a&&e&&a.id===e.id||(n.lastGroup_=a,n.lastTrack_=r,kl(t,n),a&&!a.isMasterPlaylist&&(a.playlistLoader?(t.resyncLoader(),Cl(a.playlistLoader,n)):s&&i.resetEverything()))}),s[e].onGroupChanging=(t=e,i=a,function(){var e=i.segmentLoaders[t];i.mediaTypes[t].lastGroup_=null,e.abort(),e.pause()}),s[e].onTrackChanged=(d=e,h=a,function(){var e=h.masterPlaylistLoader,t=h.segmentLoaders,i=t[d],n=t.main,r=h.mediaTypes[d],a=r.activeTrack(),s=r.getActiveGroup(),o=r.activePlaylistLoader,u=r.lastTrack_;if((!u||!a||u.id!==a.id)&&(r.lastGroup_=s,r.lastTrack_=a,kl(i,r),s)){if(s.isMasterPlaylist){if(!a||!u||a.id===u.id)return;var l=h.vhs.masterPlaylistController_,t=l.selectPlaylist();return l.media()===t?void 0:(r.logger_("track change. Switching master audio from "+u.id+" to "+a.id),e.pause(),n.resetEverything(),void l.fastQualityChange_(t))}if("AUDIO"===d){if(!s.playlistLoader)return n.setAudio(!0),void n.resetEverything();i.setAudio(!0),n.setAudio(!1)}o!==s.playlistLoader&&(i.track&&i.track(a),i.resetEverything()),Cl(s.playlistLoader,r)}}),s[e].getActiveGroup=(n=e,r=a.mediaTypes,function(){var e=r[n].activeTrack();return e?r[n].activeGroup(e):null})}),(r=s.AUDIO.activeGroup())&&(r=(r.filter(function(e){return e.default})[0]||r[0]).id,s.AUDIO.tracks[r].enabled=!0,s.AUDIO.onGroupChanged(),s.AUDIO.onTrackChanged(),s.AUDIO.getActiveGroup().playlistLoader?(u.setAudio(!1),o.setAudio(!0)):u.setAudio(!0)),t.on("mediachange",function(){["AUDIO","SUBTITLES"].forEach(function(e){return s[e].onGroupChanged()})}),t.on("mediachanging",function(){["AUDIO","SUBTITLES"].forEach(function(e){return s[e].onGroupChanging()})}),i.audioTracks().addEventListener("change",l),i.remoteTextTracks().addEventListener("change",s.SUBTITLES.onTrackChanged),n.on("dispose",function(){i.audioTracks().removeEventListener("change",l),i.remoteTextTracks().removeEventListener("change",s.SUBTITLES.onTrackChanged)}),i.clearTracks("audio"),s.AUDIO.tracks)i.audioTracks().addTrack(s.AUDIO.tracks[e])}function xl(e,t,i){var n,r,a,s,o=e.masterPlaylistController_,u=o[(e.options_.smoothQualityChange?"smooth":"fast")+"QualityChange_"].bind(o);t.attributes&&(n=t.attributes.RESOLUTION,this.width=n&&n.width,this.height=n&&n.height,this.bandwidth=t.attributes.BANDWIDTH),this.codecs=Lu(o.master(),t),this.playlist=t,this.id=i,this.enabled=(r=e.playlists,a=t.id,s=u,function(e){var t=r.master.playlists[a],i=Oo(t),n=Ro(t);return"undefined"==typeof e?n:(e?delete t.disabled:t.disabled=!0,e===n||i||(s(),e?r.trigger("renditionenabled"):r.trigger("renditiondisabled")),e)})}function Al(t,e){var i=0,n=0,r=ir.mergeOptions(nc,e);function a(){n&&t.currentTime(n)}function s(e){null!=e&&(n=t.duration()!==1/0&&t.currentTime()||0,t.one("loadedmetadata",a),t.src(e),t.trigger({type:"usage",name:"vhs-error-reload"}),t.trigger({type:"usage",name:"hls-error-reload"}),t.play())}function o(){return Date.now()-i<1e3*r.errorInterval?(t.trigger({type:"usage",name:"vhs-error-reload-canceled"}),void t.trigger({type:"usage",name:"hls-error-reload-canceled"})):r.getSource&&"function"==typeof r.getSource?(i=Date.now(),r.getSource.call(t,s)):void ir.log.error("ERROR: reloadSourceOnError - The option getSource must be a function!")}function u(){t.off("loadedmetadata",a),t.off("error",o),t.off("dispose",u)}t.ready(function(){t.trigger({type:"usage",name:"vhs-error-reload-initialized"}),t.trigger({type:"usage",name:"hls-error-reload-initialized"})}),t.on("error",o),t.on("dispose",u),t.reloadSourceOnError=function(e){u(),Al(t,e)}}var Pl,Ll=["video","audio"],Dl=function(n,r,a){return function(t,i){var e=i[t+"Buffer"];if(bl(i.mediaSource,e)){i.logger_("Appending segment "+r.mediaIndex+"'s "+n.length+" bytes to "+t+"Buffer");try{e.appendBuffer(n)}catch(e){i.logger_("Error with code "+e.code+" "+(22===e.code?"(QUOTA_EXCEEDED_ERR) ":"")+"when appending segment "+r.mediaIndex+" to "+t+"Buffer"),i.queuePending[t]=null,a(e)}}}},Ol=function(n,r){return function(t,i){var e=i[t+"Buffer"];if(bl(i.mediaSource,e)){i.logger_("Removing "+n+" to "+r+" from "+t+"Buffer");try{e.remove(n,r)}catch(e){i.logger_("Remove "+n+" to "+r+" from "+t+"Buffer failed")}}}},Rl=function(n){return function(e,t){var i=t[e+"Buffer"];bl(t.mediaSource,i)&&(t.logger_("Setting "+e+"timestampOffset to "+n),i.timestampOffset=n)}},Ml=function(i){return function(e,t){i()}},Nl=function(t){return function(e){if("open"===e.mediaSource.readyState){e.logger_("Calling mediaSource endOfStream("+(t||"")+")");try{e.mediaSource.endOfStream(t)}catch(e){ir.log.warn("Failed to call media source endOfStream",e)}}}},Ul=function(t){return function(e){e.logger_("Setting mediaSource duration to "+t);try{e.mediaSource.duration=t}catch(e){ir.log.warn("Failed to set media source duration",e)}}},Bl=function(){return function(t,e){if("open"===e.mediaSource.readyState){var i=e[t+"Buffer"];if(bl(e.mediaSource,i)){e.logger_("calling abort on "+t+"Buffer");try{i.abort()}catch(e){ir.log.warn("Failed to abort on "+t+"Buffer",e)}}}}},Fl=function(n,r){return function(e){var t=gl(n),i=gr(r);e.logger_("Adding "+n+"Buffer with codec "+r+" to mediaSource");i=e.mediaSource.addSourceBuffer(i);i.addEventListener("updateend",e["on"+t+"UpdateEnd_"]),i.addEventListener("error",e["on"+t+"Error_"]),e.codecs[n]=r,e[n+"Buffer"]=i}},jl=function(i){return function(e){var t=e[i+"Buffer"];if(_l(i,e),bl(e.mediaSource,t)){e.logger_("Removing "+i+"Buffer with codec "+e.codecs[i]+" from mediaSource");try{e.mediaSource.removeSourceBuffer(t)}catch(e){ir.log.warn("Failed to removeSourceBuffer "+i+"Buffer",e)}}}},Hl=function(r){return function(e,t){var i=t[e+"Buffer"],n=gr(r);bl(t.mediaSource,i)&&t.codecs[e]!==r&&(t.logger_("changing "+e+"Buffer codec from "+t.codecs[e]+" to "+r),i.changeType(n),t.codecs[e]=r)}},ql=function(i){function e(e){var t=i.call(this)||this;return t.mediaSource=e,t.sourceopenListener_=function(){return vl("mediaSource",yt(t))},t.mediaSource.addEventListener("sourceopen",t.sourceopenListener_),t.logger_=yo("SourceUpdater"),t.audioTimestampOffset_=0,t.videoTimestampOffset_=0,t.queue=[],t.queuePending={audio:null,video:null},t.delayedAudioAppendQueue_=[],t.videoAppendQueued_=!1,t.codecs={},t.onVideoUpdateEnd_=Sl("video",yt(t)),t.onAudioUpdateEnd_=Sl("audio",yt(t)),t.onVideoError_=function(e){t.videoError_=e},t.onAudioError_=function(e){t.audioError_=e},t.createdSourceBuffers_=!1,t.initializedEme_=!1,t.triggeredReady_=!1,t}vt(e,i);var t=e.prototype;return t.initializedEme=function(){this.initializedEme_=!0,this.triggerReady()},t.hasCreatedSourceBuffers=function(){return this.createdSourceBuffers_},t.hasInitializedAnyEme=function(){return this.initializedEme_},t.ready=function(){return this.hasCreatedSourceBuffers()&&this.hasInitializedAnyEme()},t.createSourceBuffers=function(e){this.hasCreatedSourceBuffers()||(this.addOrChangeSourceBuffers(e),this.createdSourceBuffers_=!0,this.trigger("createdsourcebuffers"),this.triggerReady())},t.triggerReady=function(){this.ready()&&!this.triggeredReady_&&(this.triggeredReady_=!0,this.trigger("ready"))},t.addSourceBuffer=function(e,t){Tl({type:"mediaSource",sourceUpdater:this,action:Fl(e,t),name:"addSourceBuffer"})},t.abort=function(e){Tl({type:e,sourceUpdater:this,action:Bl(e),name:"abort"})},t.removeSourceBuffer=function(e){this.canRemoveSourceBuffer()?Tl({type:"mediaSource",sourceUpdater:this,action:jl(e),name:"removeSourceBuffer"}):ir.log.error("removeSourceBuffer is not supported!")},t.canRemoveSourceBuffer=function(){return!ir.browser.IE_VERSION&&!ir.browser.IS_FIREFOX&&_.MediaSource&&_.MediaSource.prototype&&"function"==typeof _.MediaSource.prototype.removeSourceBuffer},e.canChangeType=function(){return _.SourceBuffer&&_.SourceBuffer.prototype&&"function"==typeof _.SourceBuffer.prototype.changeType},t.canChangeType=function(){return this.constructor.canChangeType()},t.changeType=function(e,t){this.canChangeType()?Tl({type:e,sourceUpdater:this,action:Hl(t),name:"changeType"}):ir.log.error("changeType is not supported!")},t.addOrChangeSourceBuffers=function(i){var n=this;if(!i||"object"!=typeof i||0===Object.keys(i).length)throw new Error("Cannot addOrChangeSourceBuffers to undefined codecs");Object.keys(i).forEach(function(e){var t=i[e];if(!n.hasCreatedSourceBuffers())return n.addSourceBuffer(e,t);n.canChangeType()&&n.changeType(e,t)})},t.appendBuffer=function(e,t){var i=this,n=e.segmentInfo,r=e.type,a=e.bytes;if(this.processedAppend_=!0,"audio"===r&&this.videoBuffer&&!this.videoAppendQueued_)return this.delayedAudioAppendQueue_.push([e,t]),void this.logger_("delayed audio append of "+a.length+" until video append");Tl({type:r,sourceUpdater:this,action:Dl(a,n||{mediaIndex:-1},t),doneFn:t,name:"appendBuffer"}),"video"===r&&(this.videoAppendQueued_=!0,this.delayedAudioAppendQueue_.length&&(r=this.delayedAudioAppendQueue_.slice(),this.logger_("queuing delayed audio "+r.length+" appendBuffers"),this.delayedAudioAppendQueue_.length=0,r.forEach(function(e){i.appendBuffer.apply(i,e)})))},t.audioBuffered=function(){return bl(this.mediaSource,this.audioBuffer)&&this.audioBuffer.buffered||ir.createTimeRange()},t.videoBuffered=function(){return bl(this.mediaSource,this.videoBuffer)&&this.videoBuffer.buffered||ir.createTimeRange()},t.buffered=function(){var e=bl(this.mediaSource,this.videoBuffer)?this.videoBuffer:null,t=bl(this.mediaSource,this.audioBuffer)?this.audioBuffer:null;return t&&!e?this.audioBuffered():e&&!t?this.videoBuffered():function(e,t){var i=null,n=null,r=0,a=[],s=[];if(!(e&&e.length&&t&&t.length))return ir.createTimeRange();for(var o=e.length;o--;)a.push({time:e.start(o),type:"start"}),a.push({time:e.end(o),type:"end"});for(o=t.length;o--;)a.push({time:t.start(o),type:"start"}),a.push({time:t.end(o),type:"end"});for(a.sort(function(e,t){return e.time-t.time}),o=0;o<a.length;o++)"start"===a[o].type?2===++r&&(i=a[o].time):"end"===a[o].type&&1===--r&&(n=a[o].time),null!==i&&null!==n&&(s.push([i,n]),n=i=null);return ir.createTimeRanges(s)}(this.audioBuffered(),this.videoBuffered())},t.setDuration=function(e,t){void 0===t&&(t=ml),Tl({type:"mediaSource",sourceUpdater:this,action:Ul(e),name:"duration",doneFn:t})},t.endOfStream=function(e,t){void 0===t&&(t=ml),Tl({type:"mediaSource",sourceUpdater:this,action:Nl(e="string"!=typeof(e=void 0===e?null:e)?void 0:e),name:"endOfStream",doneFn:t})},t.removeAudio=function(e,t,i){void 0===i&&(i=ml),this.audioBuffered().length&&0!==this.audioBuffered().end(0)?Tl({type:"audio",sourceUpdater:this,action:Ol(e,t),doneFn:i,name:"remove"}):i()},t.removeVideo=function(e,t,i){void 0===i&&(i=ml),this.videoBuffered().length&&0!==this.videoBuffered().end(0)?Tl({type:"video",sourceUpdater:this,action:Ol(e,t),doneFn:i,name:"remove"}):i()},t.updating=function(){return!(!yl("audio",this)&&!yl("video",this))},t.audioTimestampOffset=function(e){return"undefined"!=typeof e&&this.audioBuffer&&this.audioTimestampOffset_!==e&&(Tl({type:"audio",sourceUpdater:this,action:Rl(e),name:"timestampOffset"}),this.audioTimestampOffset_=e),this.audioTimestampOffset_},t.videoTimestampOffset=function(e){return"undefined"!=typeof e&&this.videoBuffer&&this.videoTimestampOffset!==e&&(Tl({type:"video",sourceUpdater:this,action:Rl(e),name:"timestampOffset"}),this.videoTimestampOffset_=e),this.videoTimestampOffset_},t.audioQueueCallback=function(e){this.audioBuffer&&Tl({type:"audio",sourceUpdater:this,action:Ml(e),name:"callback"})},t.videoQueueCallback=function(e){this.videoBuffer&&Tl({type:"video",sourceUpdater:this,action:Ml(e),name:"callback"})},t.dispose=function(){var t=this;this.trigger("dispose"),Ll.forEach(function(e){t.abort(e),t.canRemoveSourceBuffer()?t.removeSourceBuffer(e):t[e+"QueueCallback"](function(){return _l(e,t)})}),this.videoAppendQueued_=!1,this.delayedAudioAppendQueue_.length=0,this.sourceopenListener_&&this.mediaSource.removeEventListener("sourceopen",this.sourceopenListener_),this.off()},e}(ir.EventTarget),Vl=new Uint8Array("\n\n".split("").map(function(e){return e.charCodeAt(0)})),Wl=function(i){function e(e,t){return(t=i.call(this,e,t=void 0===t?{}:t)||this).mediaSource_=null,t.subtitlesTrack_=null,t.loaderType_="subtitle",t.featuresNativeTextTracks_=e.featuresNativeTextTracks,t.shouldSaveSegmentTimingInfo_=!1,t}vt(e,i);var t=e.prototype;return t.createTransmuxer_=function(){return null},t.buffered_=function(){if(!this.subtitlesTrack_||!this.subtitlesTrack_.cues||!this.subtitlesTrack_.cues.length)return ir.createTimeRanges();var e=this.subtitlesTrack_.cues,t=e[0].startTime,e=e[e.length-1].startTime;return ir.createTimeRanges([[t,e]])},t.initSegmentForMap=function(e,t){if(void 0===t&&(t=!1),!e)return null;var i=iu(e),n=this.initSegments_[i];return t&&!n&&e.bytes&&(t=Vl.byteLength+e.bytes.byteLength,(t=new Uint8Array(t)).set(e.bytes),t.set(Vl,e.bytes.byteLength),this.initSegments_[i]=n={resolvedUri:e.resolvedUri,byterange:e.byterange,bytes:t}),n||e},t.couldBeginLoading_=function(){return this.playlist_&&this.subtitlesTrack_&&!this.paused()},t.init_=function(){return this.state="READY",this.resetEverything(),this.monitorBuffer_()},t.track=function(e){return"undefined"==typeof e||(this.subtitlesTrack_=e,"INIT"===this.state&&this.couldBeginLoading_()&&this.init_()),this.subtitlesTrack_},t.remove=function(e,t){Bu(e,t,this.subtitlesTrack_)},t.fillBuffer_=function(){var e=this,t=this.chooseNextRequest_();if(t){if(null===this.syncController_.timestampOffsetForTimeline(t.timeline))return this.syncController_.one("timestampoffset",function(){e.state="READY",e.paused()||e.monitorBuffer_()}),void(this.state="WAITING_ON_TIMELINE");this.loadSegment_(t)}},t.timestampOffsetForSegment_=function(){return null},t.chooseNextRequest_=function(){return this.skipEmptySegments_(i.prototype.chooseNextRequest_.call(this))},t.skipEmptySegments_=function(e){for(;e&&e.segment.empty;){if(e.mediaIndex+1>=e.playlist.segments.length){e=null;break}e=this.generateSegmentInfo_({playlist:e.playlist,mediaIndex:e.mediaIndex+1,startOfSegment:e.startOfSegment+e.duration,isSyncRequest:e.isSyncRequest})}return e},t.stopForError=function(e){this.error(e),this.state="READY",this.pause(),this.trigger("error")},t.segmentRequestFinished_=function(e,t,i){var n=this;if(this.subtitlesTrack_){if(this.saveTransferStats_(t.stats),!this.pendingSegment_)return this.state="READY",void(this.mediaRequestsAborted+=1);if(e)return e.code===cl&&this.handleTimeout_(),e.code===dl?this.mediaRequestsAborted+=1:this.mediaRequestsErrored+=1,void this.stopForError(e);var r=this.pendingSegment_;this.saveBandwidthRelatedStats_(r.duration,t.stats),this.state="APPENDING",this.trigger("appending");var a=r.segment;if(a.map&&(a.map.bytes=t.map.bytes),r.bytes=t.bytes,"function"!=typeof _.WebVTT&&this.subtitlesTrack_&&this.subtitlesTrack_.tech_){var s=function(){n.subtitlesTrack_.tech_.off("vttjsloaded",o),n.stopForError({message:"Error loading vtt.js"})},o=function(){n.subtitlesTrack_.tech_.off("vttjserror",s),n.segmentRequestFinished_(e,t,i)};return this.state="WAITING_ON_VTTJS",this.subtitlesTrack_.tech_.one("vttjsloaded",o),void this.subtitlesTrack_.tech_.one("vttjserror",s)}a.requested=!0;try{this.parseVTTCues_(r)}catch(e){return void this.stopForError({message:e.message})}if(this.updateTimeMapping_(r,this.syncController_.timelines[r.timeline],this.playlist_),r.cues.length?r.timingInfo={start:r.cues[0].startTime,end:r.cues[r.cues.length-1].endTime}:r.timingInfo={start:r.startOfSegment,end:r.startOfSegment+r.duration},r.isSyncRequest)return this.trigger("syncinfoupdate"),this.pendingSegment_=null,void(this.state="READY");r.byteLength=r.bytes.byteLength,this.mediaSecondsLoaded+=a.duration,r.cues.forEach(function(e){n.subtitlesTrack_.addCue(n.featuresNativeTextTracks_?new _.VTTCue(e.startTime,e.endTime,e.text):e)}),function(t){var e=t.cues;if(e)for(var i=0;i<e.length;i++){for(var n=[],r=0,a=0;a<e.length;a++)e[i].startTime===e[a].startTime&&e[i].endTime===e[a].endTime&&e[i].text===e[a].text&&1<++r&&n.push(e[a]);n.length&&n.forEach(function(e){return t.removeCue(e)})}}(this.subtitlesTrack_),this.handleAppendsDone_()}else this.state="READY"},t.handleData_=function(){},t.updateTimingInfoEnd_=function(){},t.parseVTTCues_=function(t){var e=!1;"function"==typeof _.TextDecoder?i=new _.TextDecoder("utf8"):(i=_.WebVTT.StringDecoder(),e=!0);var i=new _.WebVTT.Parser(_,_.vttjs,i);t.cues=[],t.timestampmap={MPEGTS:0,LOCAL:0},i.oncue=t.cues.push.bind(t.cues),i.ontimestampmap=function(e){t.timestampmap=e},i.onparsingerror=function(e){ir.log.warn("Error encountered when parsing cues: "+e.message)},t.segment.map&&(n=t.segment.map.bytes,e&&(n=El(n)),i.parse(n));var n=t.bytes;e&&(n=El(n)),i.parse(n),i.flush()},t.updateTimeMapping_=function(e,t,i){var n,r,a=e.segment;t&&(e.cues.length?(r=e.timestampmap,n=r.MPEGTS/Gu-r.LOCAL+t.mapping,e.cues.forEach(function(e){e.startTime+=n,e.endTime+=n}),i.syncInfo||(r=e.cues[0].startTime,t=e.cues[e.cues.length-1].startTime,i.syncInfo={mediaSequence:i.mediaSequence+e.mediaIndex,time:Math.min(r,t-a.duration)})):a.empty=!0)},e}(fl),zl=[{name:"VOD",run:function(e,t,i,n,r){if(i===1/0)return null;return{time:0,segmentIndex:0,partIndex:null}}},{name:"ProgramDateTime",run:function(e,t,i,n,r){if(!Object.keys(e.timelineToDatetimeMappings).length)return null;var a=null,s=null,o=ko(t);r=r||0;for(var u=0;u<o.length;u++){var l=o[t.endList||0===r?u:o.length-(u+1)],c=l.segment,d=e.timelineToDatetimeMappings[c.timeline];if(d&&c.dateTimeObject){var h=c.dateTimeObject.getTime()/1e3+d;if(c.parts&&"number"==typeof l.partIndex)for(var p=0;p<l.partIndex;p++)h+=c.parts[p].duration;d=Math.abs(r-h);if(null!==s&&(0===d||s<d))break;s=d,a={time:h,segmentIndex:l.segmentIndex,partIndex:l.partIndex}}}return a}},{name:"Segment",run:function(e,t,i,n,r){var a=null,s=null;r=r||0;for(var o=ko(t),u=0;u<o.length;u++){var l=o[t.endList||0===r?u:o.length-(u+1)],c=l.segment,d=l.part&&l.part.start||c&&c.start;if(c.timeline===n&&"undefined"!=typeof d){c=Math.abs(r-d);if(null!==s&&s<c)break;(!a||null===s||c<=s)&&(s=c,a={time:d,segmentIndex:l.segmentIndex,partIndex:l.partIndex})}}return a}},{name:"Discontinuity",run:function(e,t,i,n,r){var a=null;if(r=r||0,t.discontinuityStarts&&t.discontinuityStarts.length)for(var s=null,o=0;o<t.discontinuityStarts.length;o++){var u=t.discontinuityStarts[o],l=t.discontinuitySequence+o+1,c=e.discontinuities[l];if(c){l=Math.abs(r-c.time);if(null!==s&&s<l)break;(!a||null===s||l<=s)&&(s=l,a={time:c.time,segmentIndex:u,partIndex:null})}}return a}},{name:"Playlist",run:function(e,t,i,n,r){return t.syncInfo?{time:t.syncInfo.time,segmentIndex:t.syncInfo.mediaSequence-t.mediaSequence,partIndex:null}:null}}],Gl=function(i){function e(e){var t=i.call(this)||this;return t.timelines=[],t.discontinuities=[],t.timelineToDatetimeMappings={},t.logger_=yo("SyncController"),t}vt(e,i);var t=e.prototype;return t.getSyncPoint=function(e,t,i,n){i=this.runStrategies_(e,t,i,n);return i.length?this.selectSyncPoint_(i,{key:"time",value:n}):null},t.getExpiredTime=function(e,t){if(!e||!e.segments)return null;t=this.runStrategies_(e,t,e.discontinuitySequence,0);if(!t.length)return null;t=this.selectSyncPoint_(t,{key:"segmentIndex",value:0});return 0<t.segmentIndex&&(t.time*=-1),Math.abs(t.time+Po({defaultDuration:e.targetDuration,durationList:e.segments,startIndex:t.segmentIndex,endIndex:0}))},t.runStrategies_=function(e,t,i,n){for(var r=[],a=0;a<zl.length;a++){var s=zl[a],o=s.run(this,e,t,i,n);o&&(o.strategy=s.name,r.push({strategy:s.name,syncPoint:o}))}return r},t.selectSyncPoint_=function(e,t){for(var i=e[0].syncPoint,n=Math.abs(e[0].syncPoint[t.key]-t.value),r=e[0].strategy,a=1;a<e.length;a++){var s=Math.abs(e[a].syncPoint[t.key]-t.value);s<n&&(n=s,i=e[a].syncPoint,r=e[a].strategy)}return this.logger_("syncPoint for ["+t.key+": "+t.value+"] chosen with strategy ["+r+"]: [time:"+i.time+", segmentIndex:"+i.segmentIndex+("number"==typeof i.partIndex?",partIndex:"+i.partIndex:"")+"]"),i},t.saveExpiredSegmentInfo=function(e,t){for(var i=t.mediaSequence-e.mediaSequence-1;0<=i;i--){var n=e.segments[i];if(n&&"undefined"!=typeof n.start){t.syncInfo={mediaSequence:e.mediaSequence+i,time:n.start},this.logger_("playlist refresh sync: [time:"+t.syncInfo.time+", mediaSequence: "+t.syncInfo.mediaSequence+"]"),this.trigger("syncinfoupdate");break}}},t.setDateTimeMappingForStart=function(e){var t;this.timelineToDatetimeMappings={},e.segments&&e.segments.length&&e.segments[0].dateTimeObject&&(e=(t=e.segments[0]).dateTimeObject.getTime()/1e3,this.timelineToDatetimeMappings[t.timeline]=-e)},t.saveSegmentTimingInfo=function(e){var t=e.segmentInfo,i=e.shouldSaveTimelineMapping,n=this.calculateSegmentTimeMapping_(t,t.timingInfo,i),e=t.segment;n&&(this.saveDiscontinuitySyncInfo_(t),t.playlist.syncInfo||(t.playlist.syncInfo={mediaSequence:t.playlist.mediaSequence+t.mediaIndex,time:e.start}));t=e.dateTimeObject;e.discontinuity&&i&&t&&(this.timelineToDatetimeMappings[e.timeline]=-t.getTime()/1e3)},t.timestampOffsetForTimeline=function(e){return"undefined"==typeof this.timelines[e]?null:this.timelines[e].time},t.mappingForTimeline=function(e){return"undefined"==typeof this.timelines[e]?null:this.timelines[e].mapping},t.calculateSegmentTimeMapping_=function(e,t,i){var n,r,a=e.segment,s=e.part,o=this.timelines[e.timeline];if("number"==typeof e.timestampOffset)o={time:e.startOfSegment,mapping:e.startOfSegment-t.start},i&&(this.timelines[e.timeline]=o,this.trigger("timestampoffset"),this.logger_("time mapping for timeline "+e.timeline+": [time: "+o.time+"] [mapping: "+o.mapping+"]")),n=e.startOfSegment,r=t.end+o.mapping;else{if(!o)return!1;n=t.start+o.mapping,r=t.end+o.mapping}return s&&(s.start=n,s.end=r),(!a.start||n<a.start)&&(a.start=n),a.end=r,!0},t.saveDiscontinuitySyncInfo_=function(e){var t=e.playlist,i=e.segment;if(i.discontinuity)this.discontinuities[i.timeline]={time:i.start,accuracy:0};else if(t.discontinuityStarts&&t.discontinuityStarts.length)for(var n=0;n<t.discontinuityStarts.length;n++){var r,a=t.discontinuityStarts[n],s=t.discontinuitySequence+n+1,o=a-e.mediaIndex,u=Math.abs(o);(!this.discontinuities[s]||this.discontinuities[s].accuracy>u)&&(r=void 0,r=o<0?i.start-Po({defaultDuration:t.targetDuration,durationList:t.segments,startIndex:e.mediaIndex,endIndex:a}):i.end+Po({defaultDuration:t.targetDuration,durationList:t.segments,startIndex:e.mediaIndex+1,endIndex:a}),this.discontinuities[s]={time:r,accuracy:u})}},t.dispose=function(){this.trigger("dispose"),this.off()},e}(ir.EventTarget),Xl=function(t){function e(){var e=t.call(this)||this;return e.pendingTimelineChanges_={},e.lastTimelineChanges_={},e}vt(e,t);var i=e.prototype;return i.clearPendingTimelineChange=function(e){this.pendingTimelineChanges_[e]=null,this.trigger("pendingtimelinechange")},i.pendingTimelineChange=function(e){var t=e.type,i=e.from,e=e.to;return"number"==typeof i&&"number"==typeof e&&(this.pendingTimelineChanges_[t]={type:t,from:i,to:e},this.trigger("pendingtimelinechange")),this.pendingTimelineChanges_[t]},i.lastTimelineChange=function(e){var t=e.type,i=e.from,e=e.to;return"number"==typeof i&&"number"==typeof e&&(this.lastTimelineChanges_[t]={type:t,from:i,to:e},delete this.pendingTimelineChanges_[t],this.trigger("timelinechange")),this.lastTimelineChanges_[t]},i.dispose=function(){this.trigger("dispose"),this.pendingTimelineChanges_={},this.lastTimelineChanges_={},this.off()},e}(ir.EventTarget),Kl=si(sr(K(function(){function e(e,t,i){return e(i={path:t,exports:{},require:function(e,t){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==t&&i.path)}},i.exports),i.exports}var t=e(function(e){function n(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}e.exports=function(e,t,i){return t&&n(e.prototype,t),i&&n(e,i),e},e.exports.default=e.exports,e.exports.__esModule=!0}),i=e(function(i){function n(e,t){return i.exports=n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},i.exports.default=i.exports,i.exports.__esModule=!0,n(e,t)}i.exports=n,i.exports.default=i.exports,i.exports.__esModule=!0}),n=e(function(e){e.exports=function(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,i(e,t)},e.exports.default=e.exports,e.exports.__esModule=!0}),r=function(){function e(){this.listeners={}}var t=e.prototype;return t.on=function(e,t){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)},t.off=function(e,t){if(!this.listeners[e])return!1;t=this.listeners[e].indexOf(t);return this.listeners[e]=this.listeners[e].slice(0),this.listeners[e].splice(t,1),-1<t},t.trigger=function(e){var t=this.listeners[e];if(t)if(2===arguments.length)for(var i=t.length,n=0;n<i;++n)t[n].call(this,arguments[1]);else for(var r=Array.prototype.slice.call(arguments,1),a=t.length,s=0;s<a;++s)t[s].apply(this,r)},t.dispose=function(){this.listeners={}},t.pipe=function(t){this.on("data",function(e){t.push(e)})},e}();
+/*! @name aes-decrypter @version 3.1.2 @license Apache-2.0 */
+var c=null,m=function(){function e(e){var t,i,n;c=c||function(){for(var e,t,i,n,r,a,s,o=[[[],[],[],[],[]],[[],[],[],[],[]]],u=o[0],l=o[1],c=u[4],d=l[4],h=[],p=[],f=0;f<256;f++)p[(h[f]=f<<1^283*(f>>7))^f]=f;for(e=t=0;!c[e];e^=i||1,t=p[t]||1)for(s=16843009*h[n=h[i=h[d[c[e]=r=(r=t^t<<1^t<<2^t<<3^t<<4)>>8^255&r^99]=e]]]^65537*n^257*i^16843008*e,a=257*h[r]^16843008*r,f=0;f<4;f++)u[f][e]=a=a<<24^a>>>8,l[f][r]=s=s<<24^s>>>8;for(f=0;f<5;f++)u[f]=u[f].slice(0),l[f]=l[f].slice(0);return o}(),this._tables=[[c[0][0].slice(),c[0][1].slice(),c[0][2].slice(),c[0][3].slice(),c[0][4].slice()],[c[1][0].slice(),c[1][1].slice(),c[1][2].slice(),c[1][3].slice(),c[1][4].slice()]];var r=this._tables[0][4],a=this._tables[1],s=e.length,o=1;if(4!==s&&6!==s&&8!==s)throw new Error("Invalid aes key size");var u=e.slice(0),l=[];for(this._key=[u,l],t=s;t<4*s+28;t++)n=u[t-1],(t%s==0||8===s&&t%s==4)&&(n=r[n>>>24]<<24^r[n>>16&255]<<16^r[n>>8&255]<<8^r[255&n],t%s==0&&(n=n<<8^n>>>24^o<<24,o=o<<1^283*(o>>7))),u[t]=u[t-s]^n;for(i=0;t;i++,t--)n=u[3&i?t:t-4],l[i]=t<=4||i<4?n:a[0][r[n>>>24]]^a[1][r[n>>16&255]]^a[2][r[n>>8&255]]^a[3][r[255&n]]}return e.prototype.decrypt=function(e,t,i,n,r,a){for(var s,o,u,l=this._key[1],c=e^l[0],d=n^l[1],h=i^l[2],p=t^l[3],f=l.length/4-2,m=4,t=this._tables[1],g=t[0],y=t[1],v=t[2],_=t[3],b=t[4],T=0;T<f;T++)s=g[c>>>24]^y[d>>16&255]^v[h>>8&255]^_[255&p]^l[m],o=g[d>>>24]^y[h>>16&255]^v[p>>8&255]^_[255&c]^l[m+1],u=g[h>>>24]^y[p>>16&255]^v[c>>8&255]^_[255&d]^l[m+2],p=g[p>>>24]^y[c>>16&255]^v[d>>8&255]^_[255&h]^l[m+3],m+=4,c=s,d=o,h=u;for(T=0;T<4;T++)r[(3&-T)+a]=b[c>>>24]<<24^b[d>>16&255]<<16^b[h>>8&255]<<8^b[255&p]^l[m++],s=c,c=d,d=h,h=p,p=s},e}(),l=function(t){function e(){var e=t.call(this,r)||this;return e.jobs=[],e.delay=1,e.timeout_=null,e}n(e,t);var i=e.prototype;return i.processJob_=function(){this.jobs.shift()(),this.jobs.length?this.timeout_=setTimeout(this.processJob_.bind(this),this.delay):this.timeout_=null},i.push=function(e){this.jobs.push(e),this.timeout_||(this.timeout_=setTimeout(this.processJob_.bind(this),this.delay))},e}(r),g=function(e){return e<<24|(65280&e)<<8|(16711680&e)>>8|e>>>24},a=function(){function u(e,t,i,n){var r=u.STEP,a=new Int32Array(e.buffer),s=new Uint8Array(e.byteLength),o=0;for(this.asyncStream_=new l,this.asyncStream_.push(this.decryptChunk_(a.subarray(o,o+r),t,i,s)),o=r;o<a.length;o+=r)i=new Uint32Array([g(a[o-4]),g(a[o-3]),g(a[o-2]),g(a[o-1])]),this.asyncStream_.push(this.decryptChunk_(a.subarray(o,o+r),t,i,s));this.asyncStream_.push(function(){
+/*! @name pkcs7 @version 1.0.4 @license Apache-2.0 */
+var e;n(null,(e=s).subarray(0,e.byteLength-e[e.byteLength-1]))})}return u.prototype.decryptChunk_=function(t,i,n,r){return function(){var e=function(e,t,i){for(var n,r,a,s,o=new Int32Array(e.buffer,e.byteOffset,e.byteLength>>2),u=new m(Array.prototype.slice.call(t)),e=new Uint8Array(e.byteLength),l=new Int32Array(e.buffer),c=i[0],d=i[1],h=i[2],p=i[3],f=0;f<o.length;f+=4)n=g(o[f]),r=g(o[f+1]),a=g(o[f+2]),s=g(o[f+3]),u.decrypt(n,r,a,s,l,f),l[f]=g(l[f]^c),l[f+1]=g(l[f+1]^d),l[f+2]=g(l[f+2]^h),l[f+3]=g(l[f+3]^p),c=n,d=r,h=a,p=s;return e}(t,i,n);r.set(e,t.byteOffset)}},t(u,null,[{key:"STEP",get:function(){return 32e3}}]),u}();self.onmessage=function(e){var r=e.data,t=new Uint8Array(r.encrypted.bytes,r.encrypted.byteOffset,r.encrypted.byteLength),i=new Uint32Array(r.key.bytes,r.key.byteOffset,r.key.byteLength/4),e=new Uint32Array(r.iv.bytes,r.iv.byteOffset,r.iv.byteLength/4);new a(t,i,e,function(e,t){var i,n;self.postMessage((i={source:r.source,decrypted:t},n={},Object.keys(i).forEach(function(e){var t=i[e];ArrayBuffer.isView(t)?n[e]={bytes:t.buffer,byteOffset:t.byteOffset,byteLength:t.byteLength}:n[e]=t}),n),[t.buffer])})}}))),Yl={AUDIO:function(s,o){return function(){var e=o.segmentLoaders[s],t=o.mediaTypes[s],i=o.blacklistCurrentPlaylist;kl(e,t);var n=t.activeTrack(),e=t.activeGroup(),e=(e.filter(function(e){return e.default})[0]||e[0]).id,r=t.tracks[e];if(n!==r){for(var a in ir.log.warn("Problem encountered loading the alternate audio track.Switching back to default."),t.tracks)t.tracks[a].enabled=t.tracks[a]===r;t.onTrackChanged()}else i({message:"Problem encountered loading the default audio track."})}},SUBTITLES:function(i,n){return function(){var e=n.segmentLoaders[i],t=n.mediaTypes[i];ir.log.warn("Problem encountered loading the subtitle track.Disabling subtitle track."),kl(e,t);e=t.activeTrack();e&&(e.mode="disabled"),t.onTrackChanged()}}},Ql={AUDIO:function(e,t,i){var n,r,a;t&&(n=i.tech,r=i.requestOptions,a=i.segmentLoaders[e],t.on("loadedmetadata",function(){var e=t.media();a.playlist(e,r),(!n.paused()||e.endList&&"none"!==n.preload())&&a.load()}),t.on("loadedplaylist",function(){a.playlist(t.media(),r),n.paused()||a.load()}),t.on("error",Yl[e](e,i)))},SUBTITLES:function(e,t,i){var n=i.tech,r=i.requestOptions,a=i.segmentLoaders[e],s=i.mediaTypes[e];t.on("loadedmetadata",function(){var e=t.media();a.playlist(e,r),a.track(s.activeTrack()),(!n.paused()||e.endList&&"none"!==n.preload())&&a.load()}),t.on("loadedplaylist",function(){a.playlist(t.media(),r),n.paused()||a.load()}),t.on("error",Yl[e](e,i))}},$l={AUDIO:function(e,t){var i,n,r=t.vhs,a=t.sourceType,s=t.segmentLoaders[e],o=t.requestOptions,u=t.master.mediaGroups,l=t.mediaTypes[e],c=l.groups,d=l.tracks,h=l.logger_,p=t.masterPlaylistLoader,f=Fo(p.master);for(i in u[e]&&0!==Object.keys(u[e]).length||(u[e]={main:{default:{default:!0}}},f&&(u[e].main.default.playlists=p.master.playlists)),u[e])for(var m in c[i]||(c[i]=[]),u[e][i]){var g=u[e][i][m],y=void 0,y=f?(h("AUDIO group '"+i+"' label '"+m+"' is a master playlist"),g.isMasterPlaylist=!0,null):"vhs-json"===a&&g.playlists?new Zu(g.playlists[0],r,o):g.resolvedUri?new Zu(g.resolvedUri,r,o):g.playlists&&"dash"===a?new nl(g.playlists[0],r,o,p):null,g=ir.mergeOptions({id:m,playlistLoader:y},g);Ql[e](e,g.playlistLoader,t),c[i].push(g),"undefined"==typeof d[m]&&(g=new ir.AudioTrack({id:m,kind:(n=void 0,n=(y=g).default?"main":"alternative",n=y.characteristics&&0<=y.characteristics.indexOf("public.accessibility.describes-video")?"main-desc":n),enabled:!1,language:g.language,default:g.default,label:m}),d[m]=g)}s.on("error",Yl[e](e,t))},SUBTITLES:function(e,t){var i,n=t.tech,r=t.vhs,a=t.sourceType,s=t.segmentLoaders[e],o=t.requestOptions,u=t.master.mediaGroups,l=t.mediaTypes[e],c=l.groups,d=l.tracks,h=t.masterPlaylistLoader;for(i in u[e])for(var p in c[i]||(c[i]=[]),u[e][i])if(!u[e][i][p].forced){var f=u[e][i][p],m=void 0;if("hls"===a)m=new Zu(f.resolvedUri,r,o);else if("dash"===a){if(!f.playlists.filter(function(e){return e.excludeUntil!==1/0}).length)return;m=new nl(f.playlists[0],r,o,h)}else"vhs-json"===a&&(m=new Zu(f.playlists?f.playlists[0]:f.resolvedUri,r,o));f=ir.mergeOptions({id:p,playlistLoader:m},f),Ql[e](e,f.playlistLoader,t),c[i].push(f),"undefined"==typeof d[p]&&(f=n.addRemoteTextTrack({id:p,kind:"subtitles",default:f.default&&f.autoselect,language:f.language,label:p},!1).track,d[p]=f)}s.on("error",Yl[e](e,t))},"CLOSED-CAPTIONS":function(e,t){var i,n=t.tech,r=t.master.mediaGroups,t=t.mediaTypes[e],a=t.groups,s=t.tracks;for(i in r[e])for(var o in a[i]||(a[i]=[]),r[e][i]){var u,l,c=r[e][i][o];/^(?:CC|SERVICE)/.test(c.instreamId)&&(void 0===(l=(u=n.options_.vhs&&n.options_.vhs.captionServices||{})[(l={label:o,language:c.language,instreamId:c.instreamId,default:c.default&&c.autoselect}).instreamId]?ir.mergeOptions(l,u[l.instreamId]):l).default&&delete l.default,a[i].push(ir.mergeOptions({id:o},c)),"undefined"==typeof s[o]&&(l=n.addRemoteTextTrack({id:l.instreamId,kind:"captions",default:l.default,language:l.language,label:l.label},!1).track,s[o]=l))}}},Jl={AUDIO:function(i,n){return function(){var e,t=n.mediaTypes[i].tracks;for(e in t)if(t[e].enabled)return t[e];return null}},SUBTITLES:function(i,n){return function(){var e,t=n.mediaTypes[i].tracks;for(e in t)if("showing"===t[e].mode||"hidden"===t[e].mode)return t[e];return null}}},Zl=["mediaRequests","mediaRequestsAborted","mediaRequestsTimedout","mediaRequestsErrored","mediaTransferDuration","mediaBytesTransferred","mediaAppends"],ec=function(y){function e(e){var t=y.call(this)||this,i=e.src,n=e.handleManifestRedirects,r=e.withCredentials,a=e.tech,s=e.bandwidth,o=e.externVhs,u=e.useCueTags,l=e.blacklistDuration,c=e.enableLowInitialPlaylist,d=e.sourceType,h=e.cacheEncryptionKeys,p=e.experimentalBufferBasedABR,f=e.experimentalLeastPixelDiffSelector;if(!i)throw new Error("A non-empty playlist URL or JSON manifest string is required");var m,g=e.maxPlaylistRetries;null!==g&&"undefined"!=typeof g||(g=1/0),Pl=o,t.experimentalBufferBasedABR=Boolean(p),t.experimentalLeastPixelDiffSelector=Boolean(f),t.withCredentials=r,t.tech_=a,t.vhs_=a.vhs,t.sourceType_=d,t.useCueTags_=u,t.blacklistDuration=l,t.maxPlaylistRetries=g,t.enableLowInitialPlaylist=c,t.useCueTags_&&(t.cueTagsTrack_=t.tech_.addTextTrack("metadata","ad-cues"),t.cueTagsTrack_.inBandMetadataTrackDispatchType=""),t.requestOptions_={withCredentials:r,handleManifestRedirects:n,maxPlaylistRetries:g,timeout:null},t.on("error",t.pauseLoading),t.mediaTypes_=(m={},["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach(function(e){m[e]={groups:{},tracks:{},activePlaylistLoader:null,activeGroup:ml,activeTrack:ml,getActiveGroup:ml,onGroupChanged:ml,onTrackChanged:ml,lastTrack_:null,logger_:yo("MediaGroups["+e+"]")}}),m),t.mediaSource=new _.MediaSource,t.handleDurationChange_=t.handleDurationChange_.bind(yt(t)),t.handleSourceOpen_=t.handleSourceOpen_.bind(yt(t)),t.handleSourceEnded_=t.handleSourceEnded_.bind(yt(t)),t.mediaSource.addEventListener("durationchange",t.handleDurationChange_),t.mediaSource.addEventListener("sourceopen",t.handleSourceOpen_),t.mediaSource.addEventListener("sourceended",t.handleSourceEnded_),t.seekable_=ir.createTimeRanges(),t.hasPlayed_=!1,t.syncController_=new Gl(e),t.segmentMetadataTrack_=a.addRemoteTextTrack({kind:"metadata",label:"segment-metadata"},!1).track,t.decrypter_=new Kl,t.sourceUpdater_=new ql(t.mediaSource),t.inbandTextTracks_={},t.timelineChangeController_=new Xl;h={vhs:t.vhs_,parse708captions:e.parse708captions,mediaSource:t.mediaSource,currentTime:t.tech_.currentTime.bind(t.tech_),seekable:function(){return t.seekable()},seeking:function(){return t.tech_.seeking()},duration:function(){return t.duration()},hasPlayed:function(){return t.hasPlayed_},goalBufferLength:function(){return t.goalBufferLength()},bandwidth:s,syncController:t.syncController_,decrypter:t.decrypter_,sourceType:t.sourceType_,inbandTextTracks:t.inbandTextTracks_,cacheEncryptionKeys:h,sourceUpdater:t.sourceUpdater_,timelineChangeController:t.timelineChangeController_,experimentalExactManifestTimings:e.experimentalExactManifestTimings};t.masterPlaylistLoader_=new("dash"===t.sourceType_?nl:Zu)(i,t.vhs_,t.requestOptions_),t.setupMasterPlaylistLoaderListeners_(),t.mainSegmentLoader_=new fl(ir.mergeOptions(h,{segmentMetadataTrack:t.segmentMetadataTrack_,loaderType:"main"}),e),t.audioSegmentLoader_=new fl(ir.mergeOptions(h,{loaderType:"audio"}),e),t.subtitleSegmentLoader_=new Wl(ir.mergeOptions(h,{loaderType:"vtt",featuresNativeTextTracks:t.tech_.featuresNativeTextTracks}),e),t.setupSegmentLoaderListeners_(),t.experimentalBufferBasedABR&&(t.masterPlaylistLoader_.one("loadedplaylist",function(){return t.startABRTimer_()}),t.tech_.on("pause",function(){return t.stopABRTimer_()}),t.tech_.on("play",function(){return t.startABRTimer_()})),Zl.forEach(function(e){t[e+"_"]=function(e){return this.audioSegmentLoader_[e]+this.mainSegmentLoader_[e]}.bind(yt(t),e)}),t.logger_=yo("MPC"),t.triggeredFmp4Usage=!1,"none"===t.tech_.preload()?(t.loadOnPlay_=function(){t.loadOnPlay_=null,t.masterPlaylistLoader_.load()},t.tech_.one("play",t.loadOnPlay_)):t.masterPlaylistLoader_.load(),t.timeToLoadedData__=-1,t.mainAppendsToLoadedData__=-1,t.audioAppendsToLoadedData__=-1;e="none"===t.tech_.preload()?"play":"loadstart";return t.tech_.one(e,function(){var e=Date.now();t.tech_.one("loadeddata",function(){t.timeToLoadedData__=Date.now()-e,t.mainAppendsToLoadedData__=t.mainSegmentLoader_.mediaAppends,t.audioAppendsToLoadedData__=t.audioSegmentLoader_.mediaAppends})}),t}vt(e,y);var t=e.prototype;return t.mainAppendsToLoadedData_=function(){return this.mainAppendsToLoadedData__},t.audioAppendsToLoadedData_=function(){return this.audioAppendsToLoadedData__},t.appendsToLoadedData_=function(){var e=this.mainAppendsToLoadedData_(),t=this.audioAppendsToLoadedData_();return-1===e||-1===t?-1:e+t},t.timeToLoadedData_=function(){return this.timeToLoadedData__},t.checkABR_=function(){var e=this.selectPlaylist();e&&this.shouldSwitchToMedia_(e)&&this.switchMedia_(e,"abr")},t.switchMedia_=function(e,t,i){var n=this.media(),r=n&&(n.id||n.uri),n=e.id||e.uri;r&&r!==n&&(this.logger_("switch media "+r+" -> "+n+" from "+t),this.tech_.trigger({type:"usage",name:"vhs-rendition-change-"+t})),this.masterPlaylistLoader_.media(e,i)},t.startABRTimer_=function(){var e=this;this.stopABRTimer_(),this.abrTimer_=_.setInterval(function(){return e.checkABR_()},250)},t.stopABRTimer_=function(){this.tech_.scrubbing&&this.tech_.scrubbing()||(_.clearInterval(this.abrTimer_),this.abrTimer_=null)},t.getAudioTrackPlaylists_=function(){var e=this.master(),t=e&&e.playlists||[];if(!e||!e.mediaGroups||!e.mediaGroups.AUDIO)return t;var i,n=e.mediaGroups.AUDIO,r=Object.keys(n);if(Object.keys(this.mediaTypes_.AUDIO.groups).length)i=this.mediaTypes_.AUDIO.activeTrack();else{var a,s=n.main||r.length&&n[r[0]];for(a in s)if(s[a].default){i={label:a};break}}if(!i)return t;var o,u=[];for(o in n)if(n[o][i.label]){var l=n[o][i.label];if(l.playlists&&l.playlists.length)u.push.apply(u,l.playlists);else if(l.uri)u.push(l);else if(e.playlists.length)for(var c=0;c<e.playlists.length;c++){var d=e.playlists[c];d.attributes&&d.attributes.AUDIO&&d.attributes.AUDIO===o&&u.push(d)}}return u.length?u:t},t.setupMasterPlaylistLoaderListeners_=function(){var i=this;this.masterPlaylistLoader_.on("loadedmetadata",function(){var e=i.masterPlaylistLoader_.media(),t=1.5*e.targetDuration*1e3;No(i.masterPlaylistLoader_.master,i.masterPlaylistLoader_.media())?i.requestOptions_.timeout=0:i.requestOptions_.timeout=t,e.endList&&"none"!==i.tech_.preload()&&(i.mainSegmentLoader_.playlist(e,i.requestOptions_),i.mainSegmentLoader_.load()),Il({sourceType:i.sourceType_,segmentLoaders:{AUDIO:i.audioSegmentLoader_,SUBTITLES:i.subtitleSegmentLoader_,main:i.mainSegmentLoader_},tech:i.tech_,requestOptions:i.requestOptions_,masterPlaylistLoader:i.masterPlaylistLoader_,vhs:i.vhs_,master:i.master(),mediaTypes:i.mediaTypes_,blacklistCurrentPlaylist:i.blacklistCurrentPlaylist.bind(i)}),i.triggerPresenceUsage_(i.master(),e),i.setupFirstPlay(),!i.mediaTypes_.AUDIO.activePlaylistLoader||i.mediaTypes_.AUDIO.activePlaylistLoader.media()?i.trigger("selectedinitialmedia"):i.mediaTypes_.AUDIO.activePlaylistLoader.one("loadedmetadata",function(){i.trigger("selectedinitialmedia")})}),this.masterPlaylistLoader_.on("loadedplaylist",function(){i.loadOnPlay_&&i.tech_.off("play",i.loadOnPlay_);var e,t=i.masterPlaylistLoader_.media();if(!t){if(i.excludeUnsupportedVariants_(),!(e=(e=i.enableLowInitialPlaylist?i.selectInitialPlaylist():e)||i.selectPlaylist())||!i.shouldSwitchToMedia_(e))return;if(i.initialMedia_=e,i.switchMedia_(i.initialMedia_,"initial"),!("vhs-json"===i.sourceType_&&i.initialMedia_.segments))return;t=i.initialMedia_}i.handleUpdatedMediaPlaylist(t)}),this.masterPlaylistLoader_.on("error",function(){i.blacklistCurrentPlaylist(i.masterPlaylistLoader_.error)}),this.masterPlaylistLoader_.on("mediachanging",function(){i.mainSegmentLoader_.abort(),i.mainSegmentLoader_.pause()}),this.masterPlaylistLoader_.on("mediachange",function(){var e=i.masterPlaylistLoader_.media(),t=1.5*e.targetDuration*1e3;No(i.masterPlaylistLoader_.master,i.masterPlaylistLoader_.media())?i.requestOptions_.timeout=0:i.requestOptions_.timeout=t,i.mainSegmentLoader_.playlist(e,i.requestOptions_),i.mainSegmentLoader_.load(),i.tech_.trigger({type:"mediachange",bubbles:!0})}),this.masterPlaylistLoader_.on("playlistunchanged",function(){var e=i.masterPlaylistLoader_.media();"playlist-unchanged"!==e.lastExcludeReason_&&i.stuckAtPlaylistEnd_(e)&&(i.blacklistCurrentPlaylist({message:"Playlist no longer updating.",reason:"playlist-unchanged"}),i.tech_.trigger("playliststuck"))}),this.masterPlaylistLoader_.on("renditiondisabled",function(){i.tech_.trigger({type:"usage",name:"vhs-rendition-disabled"}),i.tech_.trigger({type:"usage",name:"hls-rendition-disabled"})}),this.masterPlaylistLoader_.on("renditionenabled",function(){i.tech_.trigger({type:"usage",name:"vhs-rendition-enabled"}),i.tech_.trigger({type:"usage",name:"hls-rendition-enabled"})})},t.handleUpdatedMediaPlaylist=function(e){this.useCueTags_&&this.updateAdCues_(e),this.mainSegmentLoader_.playlist(e,this.requestOptions_),this.updateDuration(!e.endList),this.tech_.paused()||(this.mainSegmentLoader_.load(),this.audioSegmentLoader_&&this.audioSegmentLoader_.load())},t.triggerPresenceUsage_=function(e,t){var i,n=e.mediaGroups||{},r=!0,e=Object.keys(n.AUDIO);for(i in n.AUDIO)for(var a in n.AUDIO[i])n.AUDIO[i][a].uri||(r=!1);r&&(this.tech_.trigger({type:"usage",name:"vhs-demuxed"}),this.tech_.trigger({type:"usage",name:"hls-demuxed"})),Object.keys(n.SUBTITLES).length&&(this.tech_.trigger({type:"usage",name:"vhs-webvtt"}),this.tech_.trigger({type:"usage",name:"hls-webvtt"})),Pl.Playlist.isAes(t)&&(this.tech_.trigger({type:"usage",name:"vhs-aes"}),this.tech_.trigger({type:"usage",name:"hls-aes"})),e.length&&1<Object.keys(n.AUDIO[e[0]]).length&&(this.tech_.trigger({type:"usage",name:"vhs-alternate-audio"}),this.tech_.trigger({type:"usage",name:"hls-alternate-audio"})),this.useCueTags_&&(this.tech_.trigger({type:"usage",name:"vhs-playlist-cue-tags"}),this.tech_.trigger({type:"usage",name:"hls-playlist-cue-tags"}))},t.shouldSwitchToMedia_=function(e){var t=this.masterPlaylistLoader_.media(),i=this.tech_.buffered();return function(e){var t=e.currentPlaylist,i=e.nextPlaylist,n=e.forwardBuffer,r=e.bufferLowWaterLine,a=e.bufferHighWaterLine,s=e.duration,o=e.experimentalBufferBasedABR,u=e.log;if(!i)return ir.log.warn("We received no playlist to switch to. Please check your stream."),!1;var l="allowing switch "+(t&&t.id||"null")+" -> "+i.id;if(!t)return u(l+" as current playlist is not set"),!0;if(i.id===t.id)return!1;if(!t.endList)return u(l+" as current playlist is live"),!0;e=o?rl.EXPERIMENTAL_MAX_BUFFER_LOW_WATER_LINE:rl.MAX_BUFFER_LOW_WATER_LINE;if(s<e)return u(l+" as duration < max low water line ("+s+" < "+e+")"),!0;e=i.attributes.BANDWIDTH,i=t.attributes.BANDWIDTH;if(e<i&&(!o||n<a)){t=l+" as next bandwidth < current bandwidth ("+e+" < "+i+")";return o&&(t+=" and forwardBuffer < bufferHighWaterLine ("+n+" < "+a+")"),u(t),!0}if((!o||i<e)&&r<=n){r=l+" as forwardBuffer >= bufferLowWaterLine ("+n+" >= "+r+")";return o&&(r+=" and next bandwidth > current bandwidth ("+e+" > "+i+")"),u(r),!0}return u("not "+l+" as no switching criteria met"),!1}({currentPlaylist:t,nextPlaylist:e,forwardBuffer:i.length?i.end(i.length-1)-this.tech_.currentTime():0,bufferLowWaterLine:this.bufferLowWaterLine(),bufferHighWaterLine:this.bufferHighWaterLine(),duration:this.duration(),experimentalBufferBasedABR:this.experimentalBufferBasedABR,log:this.logger_})},t.setupSegmentLoaderListeners_=function(){var t=this;this.experimentalBufferBasedABR||(this.mainSegmentLoader_.on("bandwidthupdate",function(){var e=t.selectPlaylist();t.shouldSwitchToMedia_(e)&&t.switchMedia_(e,"bandwidthupdate"),t.tech_.trigger("bandwidthupdate")}),this.mainSegmentLoader_.on("progress",function(){t.trigger("progress")})),this.mainSegmentLoader_.on("error",function(){t.blacklistCurrentPlaylist(t.mainSegmentLoader_.error())}),this.mainSegmentLoader_.on("appenderror",function(){t.error=t.mainSegmentLoader_.error_,t.trigger("error")}),this.mainSegmentLoader_.on("syncinfoupdate",function(){t.onSyncInfoUpdate_()}),this.mainSegmentLoader_.on("timestampoffset",function(){t.tech_.trigger({type:"usage",name:"vhs-timestamp-offset"}),t.tech_.trigger({type:"usage",name:"hls-timestamp-offset"})}),this.audioSegmentLoader_.on("syncinfoupdate",function(){t.onSyncInfoUpdate_()}),this.audioSegmentLoader_.on("appenderror",function(){t.error=t.audioSegmentLoader_.error_,t.trigger("error")}),this.mainSegmentLoader_.on("ended",function(){t.logger_("main segment loader ended"),t.onEndOfStream()}),this.mainSegmentLoader_.on("earlyabort",function(e){t.experimentalBufferBasedABR||(t.delegateLoaders_("all",["abort"]),t.blacklistCurrentPlaylist({message:"Aborted early because there isn't enough bandwidth to complete the request without rebuffering."},120))});function e(){if(!t.sourceUpdater_.hasCreatedSourceBuffers())return t.tryToCreateSourceBuffers_();var e=t.getCodecsOrExclude_();e&&t.sourceUpdater_.addOrChangeSourceBuffers(e)}this.mainSegmentLoader_.on("trackinfo",e),this.audioSegmentLoader_.on("trackinfo",e),this.mainSegmentLoader_.on("fmp4",function(){t.triggeredFmp4Usage||(t.tech_.trigger({type:"usage",name:"vhs-fmp4"}),t.tech_.trigger({type:"usage",name:"hls-fmp4"}),t.triggeredFmp4Usage=!0)}),this.audioSegmentLoader_.on("fmp4",function(){t.triggeredFmp4Usage||(t.tech_.trigger({type:"usage",name:"vhs-fmp4"}),t.tech_.trigger({type:"usage",name:"hls-fmp4"}),t.triggeredFmp4Usage=!0)}),this.audioSegmentLoader_.on("ended",function(){t.logger_("audioSegmentLoader ended"),t.onEndOfStream()})},t.mediaSecondsLoaded_=function(){return Math.max(this.audioSegmentLoader_.mediaSecondsLoaded+this.mainSegmentLoader_.mediaSecondsLoaded)},t.load=function(){this.mainSegmentLoader_.load(),this.mediaTypes_.AUDIO.activePlaylistLoader&&this.audioSegmentLoader_.load(),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&this.subtitleSegmentLoader_.load()},t.smoothQualityChange_=function(e){void 0===e&&(e=this.selectPlaylist()),this.fastQualityChange_(e)},t.fastQualityChange_=function(e){var t=this;(e=void 0===e?this.selectPlaylist():e)!==this.masterPlaylistLoader_.media()?(this.switchMedia_(e,"fast-quality"),this.mainSegmentLoader_.resetEverything(function(){ir.browser.IE_VERSION||ir.browser.IS_EDGE?t.tech_.setCurrentTime(t.tech_.currentTime()+.04):t.tech_.setCurrentTime(t.tech_.currentTime())})):this.logger_("skipping fastQualityChange because new media is same as old")},t.play=function(){if(!this.setupFirstPlay()){this.tech_.ended()&&this.tech_.setCurrentTime(0),this.hasPlayed_&&this.load();var e=this.tech_.seekable();return this.tech_.duration()===1/0&&this.tech_.currentTime()<e.start(0)?this.tech_.setCurrentTime(e.end(e.length-1)):void 0}},t.setupFirstPlay=function(){var e=this,t=this.masterPlaylistLoader_.media();if(!t||this.tech_.paused()||this.hasPlayed_)return!1;if(!t.endList){var i=this.seekable();if(!i.length)return!1;if(ir.browser.IE_VERSION&&0===this.tech_.readyState())return this.tech_.one("loadedmetadata",function(){e.trigger("firstplay"),e.tech_.setCurrentTime(i.end(0)),e.hasPlayed_=!0}),!1;this.trigger("firstplay"),this.tech_.setCurrentTime(i.end(0))}return this.hasPlayed_=!0,this.load(),!0},t.handleSourceOpen_=function(){var e;this.tryToCreateSourceBuffers_(),!this.tech_.autoplay()||"undefined"!=typeof(e=this.tech_.play())&&"function"==typeof e.then&&e.then(null,function(e){}),this.trigger("sourceopen")},t.handleSourceEnded_=function(){var e,t;!this.inbandTextTracks_.metadataTrack_||(e=this.inbandTextTracks_.metadataTrack_.cues)&&e.length&&(t=this.duration(),e[e.length-1].endTime=isNaN(t)||Math.abs(t)===1/0?Number.MAX_VALUE:t)},t.handleDurationChange_=function(){this.tech_.trigger("durationchange")},t.onEndOfStream=function(){var e,t=this.mainSegmentLoader_.ended_;(t=this.mediaTypes_.AUDIO.activePlaylistLoader?((e=this.mainSegmentLoader_.getCurrentMediaInfo_())&&!e.hasVideo||t)&&this.audioSegmentLoader_.ended_:t)&&(this.stopABRTimer_(),this.sourceUpdater_.endOfStream())},t.stuckAtPlaylistEnd_=function(e){if(!this.seekable().length)return!1;var t=this.syncController_.getExpiredTime(e,this.duration());if(null===t)return!1;var i=Pl.Playlist.playlistEnd(e,t),e=this.tech_.currentTime(),t=this.tech_.buffered();if(!t.length)return i-e<=.1;t=t.end(t.length-1);return t-e<=.1&&i-t<=.1},t.blacklistCurrentPlaylist=function(e,t){var i=(e=void 0===e?{}:e).playlist||this.masterPlaylistLoader_.media();if(t=t||e.blacklistDuration||this.blacklistDuration,!i)return this.error=e,void("open"!==this.mediaSource.readyState?this.trigger("error"):this.sourceUpdater_.endOfStream("network"));i.playlistErrors_++;var n,r=this.masterPlaylistLoader_.master.playlists,a=r.filter(Ro),s=1===a.length&&a[0]===i;if(1===r.length&&t!==1/0)return ir.log.warn("Problem encountered with playlist "+i.id+". Trying again since it is the only playlist."),this.tech_.trigger("retryplaylist"),this.masterPlaylistLoader_.load(s);s&&(n=!1,r.forEach(function(e){var t;e===i||"undefined"!=typeof(t=e.excludeUntil)&&t!==1/0&&(n=!0,delete e.excludeUntil)}),n&&(ir.log.warn("Removing other playlists from the exclusion list because the last rendition is about to be excluded."),this.tech_.trigger("retryplaylist"))),a=i.playlistErrors_>this.maxPlaylistRetries?1/0:Date.now()+1e3*t,i.excludeUntil=a,e.reason&&(i.lastExcludeReason_=e.reason),this.tech_.trigger("blacklistplaylist"),this.tech_.trigger({type:"usage",name:"vhs-rendition-blacklisted"}),this.tech_.trigger({type:"usage",name:"hls-rendition-blacklisted"});r=this.selectPlaylist();if(!r)return this.error="Playback cannot continue. No available working or supported playlists.",void this.trigger("error");t=e.internal?this.logger_:ir.log.warn,a=e.message?" "+e.message:"";t((e.internal?"Internal problem":"Problem")+" encountered with playlist "+i.id+"."+a+" Switching to playlist "+r.id+"."),r.attributes.AUDIO!==i.attributes.AUDIO&&this.delegateLoaders_("audio",["abort","pause"]),r.attributes.SUBTITLES!==i.attributes.SUBTITLES&&this.delegateLoaders_("subtitle",["abort","pause"]),this.delegateLoaders_("main",["abort","pause"]);a=r.targetDuration/2*1e3||5e3,a="number"==typeof r.lastRequest&&Date.now()-r.lastRequest<=a;return this.switchMedia_(r,"exclude",s||a)},t.pauseLoading=function(){this.delegateLoaders_("all",["abort","pause"]),this.stopABRTimer_()},t.delegateLoaders_=function(i,e){var n=this,r=[],t="all"===i;!t&&"main"!==i||r.push(this.masterPlaylistLoader_);var a=[];!t&&"audio"!==i||a.push("AUDIO"),!t&&"subtitle"!==i||(a.push("CLOSED-CAPTIONS"),a.push("SUBTITLES")),a.forEach(function(e){e=n.mediaTypes_[e]&&n.mediaTypes_[e].activePlaylistLoader;e&&r.push(e)}),["main","audio","subtitle"].forEach(function(e){var t=n[e+"SegmentLoader_"];!t||i!==e&&"all"!==i||r.push(t)}),r.forEach(function(t){return e.forEach(function(e){"function"==typeof t[e]&&t[e]()})})},t.setCurrentTime=function(e){var t=_o(this.tech_.buffered(),e);return this.masterPlaylistLoader_&&this.masterPlaylistLoader_.media()&&this.masterPlaylistLoader_.media().segments?t&&t.length?e:(this.mainSegmentLoader_.resetEverything(),this.mainSegmentLoader_.abort(),this.mediaTypes_.AUDIO.activePlaylistLoader&&(this.audioSegmentLoader_.resetEverything(),this.audioSegmentLoader_.abort()),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&(this.subtitleSegmentLoader_.resetEverything(),this.subtitleSegmentLoader_.abort()),void this.load()):0},t.duration=function(){if(!this.masterPlaylistLoader_)return 0;var e=this.masterPlaylistLoader_.media();return e?e.endList?this.mediaSource?this.mediaSource.duration:Pl.Playlist.duration(e):1/0:0},t.seekable=function(){return this.seekable_},t.onSyncInfoUpdate_=function(){var e;if(this.masterPlaylistLoader_){var t=this.masterPlaylistLoader_.media();if(t){var i=this.syncController_.getExpiredTime(t,this.duration());if(null!==i){var n,r,a=this.masterPlaylistLoader_.master,s=Pl.Playlist.seekable(t,i,Pl.Playlist.liveEdgeDelay(a,t));if(0!==s.length){if(this.mediaTypes_.AUDIO.activePlaylistLoader){if(t=this.mediaTypes_.AUDIO.activePlaylistLoader.media(),null===(i=this.syncController_.getExpiredTime(t,this.duration())))return;if(0===(e=Pl.Playlist.seekable(t,i,Pl.Playlist.liveEdgeDelay(a,t))).length)return}this.seekable_&&this.seekable_.length&&(n=this.seekable_.end(0),r=this.seekable_.start(0)),!e||e.start(0)>s.end(0)||s.start(0)>e.end(0)?this.seekable_=s:this.seekable_=ir.createTimeRanges([[(e.start(0)>s.start(0)?e:s).start(0),(e.end(0)<s.end(0)?e:s).end(0)]]),this.seekable_&&this.seekable_.length&&this.seekable_.end(0)===n&&this.seekable_.start(0)===r||(this.logger_("seekable updated ["+To(this.seekable_)+"]"),this.tech_.trigger("seekablechanged"))}}}}},t.updateDuration=function(e){if(this.updateDuration_&&(this.mediaSource.removeEventListener("sourceopen",this.updateDuration_),this.updateDuration_=null),"open"!==this.mediaSource.readyState)return this.updateDuration_=this.updateDuration.bind(this,e),void this.mediaSource.addEventListener("sourceopen",this.updateDuration_);if(e){var t=this.seekable();return t.length?void((isNaN(this.mediaSource.duration)||this.mediaSource.duration<t.end(t.length-1))&&this.sourceUpdater_.setDuration(t.end(t.length-1))):void 0}e=this.tech_.buffered(),t=Pl.Playlist.duration(this.masterPlaylistLoader_.media());0<e.length&&(t=Math.max(t,e.end(e.length-1))),this.mediaSource.duration!==t&&this.sourceUpdater_.setDuration(t)},t.dispose=function(){var n=this;this.trigger("dispose"),this.decrypter_.terminate(),this.masterPlaylistLoader_.dispose(),this.mainSegmentLoader_.dispose(),this.loadOnPlay_&&this.tech_.off("play",this.loadOnPlay_),["AUDIO","SUBTITLES"].forEach(function(e){var t,i=n.mediaTypes_[e].groups;for(t in i)i[t].forEach(function(e){e.playlistLoader&&e.playlistLoader.dispose()})}),this.audioSegmentLoader_.dispose(),this.subtitleSegmentLoader_.dispose(),this.sourceUpdater_.dispose(),this.timelineChangeController_.dispose(),this.stopABRTimer_(),this.updateDuration_&&this.mediaSource.removeEventListener("sourceopen",this.updateDuration_),this.mediaSource.removeEventListener("durationchange",this.handleDurationChange_),this.mediaSource.removeEventListener("sourceopen",this.handleSourceOpen_),this.mediaSource.removeEventListener("sourceended",this.handleSourceEnded_),this.off()},t.master=function(){return this.masterPlaylistLoader_.master},t.media=function(){return this.masterPlaylistLoader_.media()||this.initialMedia_},t.areMediaTypesKnown_=function(){var e=!!this.mediaTypes_.AUDIO.activePlaylistLoader,t=!!this.mainSegmentLoader_.getCurrentMediaInfo_(),e=!e||!!this.audioSegmentLoader_.getCurrentMediaInfo_();return t&&e},t.getCodecsOrExclude_=function(){var n=this,r={main:this.mainSegmentLoader_.getCurrentMediaInfo_()||{},audio:this.audioSegmentLoader_.getCurrentMediaInfo_()||{}};r.video=r.main;var e=Lu(this.master(),this.media()),a={},t=!!this.mediaTypes_.AUDIO.activePlaylistLoader;if(r.main.hasVideo&&(a.video=e.video||r.main.videoCodec||"avc1.4d400d"),r.main.isMuxed&&(a.video+=","+(e.audio||r.main.audioCodec||Ir)),(r.main.hasAudio&&!r.main.isMuxed||r.audio.hasAudio||t)&&(a.audio=e.audio||r.main.audioCodec||r.audio.audioCodec||Ir,r.audio.isFmp4=(r.main.hasAudio&&!r.main.isMuxed?r.main:r.audio).isFmp4),a.audio||a.video){var s,i,o={};if(["video","audio"].forEach(function(e){var t,i;a.hasOwnProperty(e)&&(t=r[e].isFmp4,i=a[e],!(t?yr:vr)(i))&&(i=r[e].isFmp4?"browser":"muxer",o[i]=o[i]||[],o[i].push(a[e]),"audio"===e&&(s=i))}),t&&s&&this.media().attributes.AUDIO&&(i=this.media().attributes.AUDIO,this.master().playlists.forEach(function(e){(e.attributes&&e.attributes.AUDIO)===i&&e!==n.media()&&(e.excludeUntil=1/0)}),this.logger_("excluding audio group "+i+" as "+s+' does not support codec(s): "'+a.audio+'"')),!Object.keys(o).length){if(this.sourceUpdater_.hasCreatedSourceBuffers()&&!this.sourceUpdater_.canChangeType()){var u=[];if(["video","audio"].forEach(function(e){var t=(fr(n.sourceUpdater_.codecs[e]||"")[0]||{}).type,i=(fr(a[e]||"")[0]||{}).type;t&&i&&t.toLowerCase()!==i.toLowerCase()&&u.push('"'+n.sourceUpdater_.codecs[e]+'" -> "'+a[e]+'"')}),u.length)return void this.blacklistCurrentPlaylist({playlist:this.media(),message:"Codec switching not supported: "+u.join(", ")+".",blacklistDuration:1/0,internal:!0})}return a}t=Object.keys(o).reduce(function(e,t){return e&&(e+=", "),e+=t+' does not support codec(s): "'+o[t].join(",")+'"'},"")+".";this.blacklistCurrentPlaylist({playlist:this.media(),internal:!0,message:t,blacklistDuration:1/0})}else this.blacklistCurrentPlaylist({playlist:this.media(),message:"Could not determine codecs for playlist.",blacklistDuration:1/0})},t.tryToCreateSourceBuffers_=function(){var e;"open"!==this.mediaSource.readyState||this.sourceUpdater_.hasCreatedSourceBuffers()||!this.areMediaTypesKnown_()||(e=this.getCodecsOrExclude_())&&(this.sourceUpdater_.createSourceBuffers(e),e=[e.video,e.audio].filter(Boolean).join(","),this.excludeIncompatibleVariants_(e))},t.excludeUnsupportedVariants_=function(){var n=this,r=this.master().playlists,a=[];Object.keys(r).forEach(function(e){var t,i=r[e];-1===a.indexOf(i.id)&&(a.push(i.id),t=[],!(e=Lu(n.master,i)).audio||vr(e.audio)||yr(e.audio)||t.push("audio codec "+e.audio),!e.video||vr(e.video)||yr(e.video)||t.push("video codec "+e.video),e.text&&"stpp.ttml.im1t"===e.text&&t.push("text codec "+e.text),t.length&&(i.excludeUntil=1/0,n.logger_("excluding "+i.id+" for unsupported: "+t.join(", "))))})},t.excludeIncompatibleVariants_=function(e){var r=this,a=[],s=this.master().playlists,e=Au(fr(e)),o=Pu(e),u=e.video&&fr(e.video)[0]||null,l=e.audio&&fr(e.audio)[0]||null;Object.keys(s).forEach(function(e){var t,i,n=s[e];-1===a.indexOf(n.id)&&n.excludeUntil!==1/0&&(a.push(n.id),t=[],i=Lu(r.masterPlaylistLoader_.master,n),e=Pu(i),(i.audio||i.video)&&(e!==o&&t.push('codec count "'+e+'" !== "'+o+'"'),r.sourceUpdater_.canChangeType()||(e=i.video&&fr(i.video)[0]||null,i=i.audio&&fr(i.audio)[0]||null,e&&u&&e.type.toLowerCase()!==u.type.toLowerCase()&&t.push('video codec "'+e.type+'" !== "'+u.type+'"'),i&&l&&i.type.toLowerCase()!==l.type.toLowerCase()&&t.push('audio codec "'+i.type+'" !== "'+l.type+'"')),t.length&&(n.excludeUntil=1/0,r.logger_("blacklisting "+n.id+": "+t.join(" && ")))))})},t.updateAdCues_=function(e){var t=0,i=this.seekable();i.length&&(t=i.start(0)),function(e,t,i){if(void 0===i&&(i=0),e.segments)for(var n=i,r=0;r<e.segments.length;r++){var a,s,o,u=e.segments[r];if(o=o||function(e,t){for(var i=e.cues,n=0;n<i.length;n++){var r=i[n];if(t>=r.adStartTime&&t<=r.adEndTime)return r}return null}(t,n+u.duration/2)){if("cueIn"in u){o.endTime=n,o.adEndTime=n,n+=u.duration,o=null;continue}if(n<o.endTime){n+=u.duration;continue}o.endTime+=u.duration}else"cueOut"in u&&((o=new _.VTTCue(n,n+u.duration,u.cueOut)).adStartTime=n,o.adEndTime=n+parseFloat(u.cueOut),t.addCue(o)),"cueOutCont"in u&&(a=(s=u.cueOutCont.split("/").map(parseFloat))[0],s=s[1],(o=new _.VTTCue(n,n+u.duration,"")).adStartTime=n-a,o.adEndTime=o.adStartTime+s,t.addCue(o));n+=u.duration}}(e,this.cueTagsTrack_,t)},t.goalBufferLength=function(){var e=this.tech_.currentTime(),t=rl.GOAL_BUFFER_LENGTH,i=rl.GOAL_BUFFER_LENGTH_RATE,n=Math.max(t,rl.MAX_GOAL_BUFFER_LENGTH);return Math.min(t+e*i,n)},t.bufferLowWaterLine=function(){var e=this.tech_.currentTime(),t=rl.BUFFER_LOW_WATER_LINE,i=rl.BUFFER_LOW_WATER_LINE_RATE,n=Math.max(t,rl.MAX_BUFFER_LOW_WATER_LINE),r=Math.max(t,rl.EXPERIMENTAL_MAX_BUFFER_LOW_WATER_LINE);return Math.min(t+e*i,this.experimentalBufferBasedABR?r:n)},t.bufferHighWaterLine=function(){return rl.BUFFER_HIGH_WATER_LINE},e}(ir.EventTarget),tc=["seeking","seeked","pause","playing","error"],ic=function(){function e(e){var t=this;this.masterPlaylistController_=e.masterPlaylistController,this.tech_=e.tech,this.seekable=e.seekable,this.allowSeeksWithinUnsafeLiveWindow=e.allowSeeksWithinUnsafeLiveWindow,this.liveRangeSafeTimeDelta=e.liveRangeSafeTimeDelta,this.media=e.media,this.consecutiveUpdates=0,this.lastRecordedTime=null,this.timer_=null,this.checkCurrentTimeTimeout_=null,this.logger_=yo("PlaybackWatcher"),this.logger_("initialize");function i(){return t.monitorCurrentTime_()}function n(){return t.monitorCurrentTime_()}function r(){return t.techWaiting_()}function a(){return t.cancelTimer_()}function s(){return t.fixesBadSeeks_()}var o=this.masterPlaylistController_,u=["main","subtitle","audio"],l={};u.forEach(function(e){l[e]={reset:function(){return t.resetSegmentDownloads_(e)},updateend:function(){return t.checkSegmentDownloads_(e)}},o[e+"SegmentLoader_"].on("appendsdone",l[e].updateend),o[e+"SegmentLoader_"].on("playlistupdate",l[e].reset),t.tech_.on(["seeked","seeking"],l[e].reset)}),this.tech_.on("seekablechanged",s),this.tech_.on("waiting",r),this.tech_.on(tc,a),this.tech_.on("canplay",n),this.tech_.one("play",i),this.dispose=function(){t.logger_("dispose"),t.tech_.off("seekablechanged",s),t.tech_.off("waiting",r),t.tech_.off(tc,a),t.tech_.off("canplay",n),t.tech_.off("play",i),u.forEach(function(e){o[e+"SegmentLoader_"].off("appendsdone",l[e].updateend),o[e+"SegmentLoader_"].off("playlistupdate",l[e].reset),t.tech_.off(["seeked","seeking"],l[e].reset)}),t.checkCurrentTimeTimeout_&&_.clearTimeout(t.checkCurrentTimeTimeout_),t.cancelTimer_()}}var t=e.prototype;return t.monitorCurrentTime_=function(){this.checkCurrentTime_(),this.checkCurrentTimeTimeout_&&_.clearTimeout(this.checkCurrentTimeTimeout_),this.checkCurrentTimeTimeout_=_.setTimeout(this.monitorCurrentTime_.bind(this),250)},t.resetSegmentDownloads_=function(e){var t=this.masterPlaylistController_[e+"SegmentLoader_"];0<this[e+"StalledDownloads_"]&&this.logger_("resetting possible stalled download count for "+e+" loader"),this[e+"StalledDownloads_"]=0,this[e+"Buffered_"]=t.buffered_()},t.checkSegmentDownloads_=function(e){var t=this.masterPlaylistController_,i=t[e+"SegmentLoader_"],n=i.buffered_(),r=function(e,t){if(e===t)return!1;if(!e&&t||!t&&e)return!0;if(e.length!==t.length)return!0;for(var i=0;i<e.length;i++)if(e.start(i)!==t.start(i)||e.end(i)!==t.end(i))return!0;return!1}(this[e+"Buffered_"],n);this[e+"Buffered_"]=n,r?this.resetSegmentDownloads_(e):(this[e+"StalledDownloads_"]++,this.logger_("found #"+this[e+"StalledDownloads_"]+" "+e+" appends that did not increase buffer (possible stalled download)",{playlistId:i.playlist_&&i.playlist_.id,buffered:So(n)}),this[e+"StalledDownloads_"]<10||(this.logger_(e+" loader stalled download exclusion"),this.resetSegmentDownloads_(e),this.tech_.trigger({type:"usage",name:"vhs-"+e+"-download-exclusion"}),"subtitle"!==e&&t.blacklistCurrentPlaylist({message:"Excessive "+e+" segment downloading detected."},1/0)))},t.checkCurrentTime_=function(){if(this.tech_.seeking()&&this.fixesBadSeeks_())return this.consecutiveUpdates=0,void(this.lastRecordedTime=this.tech_.currentTime());if(!this.tech_.paused()&&!this.tech_.seeking()){var e=this.tech_.currentTime(),t=this.tech_.buffered();if(this.lastRecordedTime===e&&(!t.length||e+.1>=t.end(t.length-1)))return this.techWaiting_();5<=this.consecutiveUpdates&&e===this.lastRecordedTime?(this.consecutiveUpdates++,this.waiting_()):e===this.lastRecordedTime?this.consecutiveUpdates++:(this.consecutiveUpdates=0,this.lastRecordedTime=e)}},t.cancelTimer_=function(){this.consecutiveUpdates=0,this.timer_&&(this.logger_("cancelTimer_"),clearTimeout(this.timer_)),this.timer_=null},t.fixesBadSeeks_=function(){if(!this.tech_.seeking())return!1;var e,t=this.seekable(),i=this.tech_.currentTime();if(this.afterSeekableWindow_(t,i,this.media(),this.allowSeeksWithinUnsafeLiveWindow)&&(e=t.end(t.length-1)),"undefined"!=typeof(e=this.beforeSeekableWindow_(t,i)?(r=t.start(0))+(r===t.end(0)?0:.1):e))return this.logger_("Trying to seek outside of seekable at time "+i+" with seekable range "+To(t)+". Seeking to "+e+"."),this.tech_.setCurrentTime(e),!0;var n,r,a=this.tech_.buffered();return n={buffered:a,targetDuration:this.media().targetDuration,currentTime:i},r=n.buffered,t=n.targetDuration,n=n.currentTime,!(!r.length||r.end(0)-r.start(0)<2*t||n>r.start(0))&&r.start(0)-n<t&&(e=a.start(0)+.1,this.logger_("Buffered region starts ("+a.start(0)+") just beyond seek point ("+i+"). Seeking to "+e+"."),this.tech_.setCurrentTime(e),!0)},t.waiting_=function(){var e,t;this.techWaiting_()||(e=this.tech_.currentTime(),t=this.tech_.buffered(),(t=_o(t,e)).length&&e+3<=t.end(0)&&(this.cancelTimer_(),this.tech_.setCurrentTime(e),this.logger_("Stopped at "+e+" while inside a buffered region ["+t.start(0)+" -> "+t.end(0)+"]. Attempting to resume playback by seeking to the current time."),this.tech_.trigger({type:"usage",name:"vhs-unknown-waiting"}),this.tech_.trigger({type:"usage",name:"hls-unknown-waiting"})))},t.techWaiting_=function(){var e=this.seekable(),t=this.tech_.currentTime();if(this.tech_.seeking()&&this.fixesBadSeeks_())return!0;if(this.tech_.seeking()||null!==this.timer_)return!0;if(this.beforeSeekableWindow_(e,t)){var i=e.end(e.length-1);return this.logger_("Fell out of live window at time "+t+". Seeking to live point (seekable end) "+i),this.cancelTimer_(),this.tech_.setCurrentTime(i),this.tech_.trigger({type:"usage",name:"vhs-live-resync"}),this.tech_.trigger({type:"usage",name:"hls-live-resync"}),!0}e=this.tech_.vhs.masterPlaylistController_.sourceUpdater_,i=this.tech_.buffered();if(this.videoUnderflow_({audioBuffered:e.audioBuffered(),videoBuffered:e.videoBuffered(),currentTime:t}))return this.cancelTimer_(),this.tech_.setCurrentTime(t),this.tech_.trigger({type:"usage",name:"vhs-video-underflow"}),this.tech_.trigger({type:"usage",name:"hls-video-underflow"}),!0;e=bo(i,t);if(0<e.length){i=e.start(0)-t;return this.logger_("Stopped at "+t+", setting timer for "+i+", seeking to "+e.start(0)),this.cancelTimer_(),this.timer_=setTimeout(this.skipTheGap_.bind(this),1e3*i,t),!0}return!1},t.afterSeekableWindow_=function(e,t,i,n){if(void 0===n&&(n=!1),!e.length)return!1;var r=e.end(e.length-1)+.1;return(r=!i.endList&&n?e.end(e.length-1)+3*i.targetDuration:r)<t},t.beforeSeekableWindow_=function(e,t){return!!(e.length&&0<e.start(0)&&t<e.start(0)-this.liveRangeSafeTimeDelta)},t.videoUnderflow_=function(e){var t,i,n=e.videoBuffered,r=e.audioBuffered,a=e.currentTime;if(n)return n.length&&r.length?(i=_o(n,a-3),e=_o(n,a),(r=_o(r,a)).length&&!e.length&&i.length&&(t={start:i.end(0),end:r.end(0)})):bo(n,a).length||(t=this.gapFromVideoUnderflow_(n,a)),!!t&&(this.logger_("Encountered a gap in video from "+t.start+" to "+t.end+". Seeking to current time "+a),!0)},t.skipTheGap_=function(e){var t=this.tech_.buffered(),i=this.tech_.currentTime(),t=bo(t,i);this.cancelTimer_(),0!==t.length&&i===e&&(this.logger_("skipTheGap_:","currentTime:",i,"scheduled currentTime:",e,"nextRange start:",t.start(0)),this.tech_.setCurrentTime(t.start(0)+Ku),this.tech_.trigger({type:"usage",name:"vhs-gap-skip"}),this.tech_.trigger({type:"usage",name:"hls-gap-skip"}))},t.gapFromVideoUnderflow_=function(e,t){for(var i=function(e){if(e.length<2)return ir.createTimeRanges();for(var t=[],i=1;i<e.length;i++){var n=e.end(i-1),r=e.start(i);t.push([n,r])}return ir.createTimeRanges(t)}(e),n=0;n<i.length;n++){var r=i.start(n),a=i.end(n);if(t-r<4&&2<t-r)return{start:r,end:a}}return null},e}(),nc={errorInterval:30,getSource:function(e){return e(this.tech({IWillNotUseThisInPlugins:!0}).currentSource_||this.currentSource())}},K=function(e){Al(this,e)},rc={PlaylistLoader:Zu,Playlist:Qu,utils:ai,STANDARD_PLAYLIST_SELECTOR:Kt,INITIAL_PLAYLIST_SELECTOR:function(){var t=this,e=this.playlists.master.playlists.filter(Qu.isEnabled);return Ru(e,Mu),e.filter(function(e){return!!Lu(t.playlists.master,e).video})[0]||null},lastBandwidthSelector:Kt,movingAverageBandwidthSelector:function(t){var i=-1,n=-1;if(t<0||1<t)throw new Error("Moving average bandwidth decay must be between 0 and 1.");return function(){var e=this.useDevicePixelRatio&&_.devicePixelRatio||1;return i<0&&(i=this.systemBandwidth,n=this.systemBandwidth),0<this.systemBandwidth&&this.systemBandwidth!==n&&(i=t*this.systemBandwidth+(1-t)*i,n=this.systemBandwidth),Nu(this.playlists.master,i,parseInt(Ou(this.tech_.el(),"width"),10)*e,parseInt(Ou(this.tech_.el(),"height"),10)*e,this.limitRenditionByPlayerDimensions,this.masterPlaylistController_)}},comparePlaylistBandwidth:Mu,comparePlaylistResolution:function(e,t){var i,n;return(i=(i=e.attributes.RESOLUTION&&e.attributes.RESOLUTION.width?e.attributes.RESOLUTION.width:i)||_.Number.MAX_VALUE)===(n=(n=t.attributes.RESOLUTION&&t.attributes.RESOLUTION.width?t.attributes.RESOLUTION.width:n)||_.Number.MAX_VALUE)&&e.attributes.BANDWIDTH&&t.attributes.BANDWIDTH?e.attributes.BANDWIDTH-t.attributes.BANDWIDTH:i-n},xhr:$o()};Object.keys(rl).forEach(function(t){Object.defineProperty(rc,t,{get:function(){return ir.log.warn("using Vhs."+t+" is UNSAFE be sure you know what you are doing"),rl[t]},set:function(e){ir.log.warn("using Vhs."+t+" is UNSAFE be sure you know what you are doing"),"number"!=typeof e||e<0?ir.log.warn("value of Vhs."+t+" must be greater than or equal to 0"):rl[t]=e}})});function ac(e,t){for(var i=t.media(),n=-1,r=0;r<e.length;r++)if(e[r].id===i.id){n=r;break}e.selectedIndex_=n,e.trigger({selectedIndex:n,type:"change"})}var sc="videojs-vhs";rc.canPlaySource=function(){return ir.log.warn("HLS is no longer a tech. Please remove it from your player's techOrder.")};function oc(e){var n=e.player,t=e.sourceKeySystems,i=e.audioMedia,e=e.mainPlaylists;if(!n.eme.initializeMediaKeys)return Promise.resolve();var r,e=(e=e=i?e.concat([i]):e,r=Object.keys(t),e.reduce(function(e,n){if(!n.contentProtection)return e;var t=r.reduce(function(e,t){var i=n.contentProtection[t];return i&&i.pssh&&(e[t]={pssh:i.pssh}),e},{});return Object.keys(t).length&&e.push(t),e},[])),a=[],s=[];return e.forEach(function(e){s.push(new Promise(function(e,t){n.tech_.one("keysessioncreated",e)})),a.push(new Promise(function(t,i){n.eme.initializeMediaKeys({keySystems:e},function(e){e?i(e):t()})}))}),Promise.race([Promise.all(a),Promise.race(s)])}function uc(e){var t=e.player;return!!(e=function(e,t,i){if(!e)return e;var n={};t&&t.attributes&&t.attributes.CODECS&&(n=Au(fr(t.attributes.CODECS))),i&&i.attributes&&i.attributes.CODECS&&(n.audio=i.attributes.CODECS);var r,a=gr(n.video),s=gr(n.audio),o={};for(r in e)o[r]={},s&&(o[r].audioContentType=s),a&&(o[r].videoContentType=a),t.contentProtection&&t.contentProtection[r]&&t.contentProtection[r].pssh&&(o[r].pssh=t.contentProtection[r].pssh),"string"==typeof e[r]&&(o[r].url=e[r]);return ir.mergeOptions(e,o)}(e.sourceKeySystems,e.media,e.audioMedia))&&(!((t.currentSource().keySystems=e)&&!t.eme)||(ir.log.warn("DRM encrypted source cannot be decrypted without a DRM plugin"),!1))}function lc(){if(!_.localStorage)return null;var e=_.localStorage.getItem(sc);if(!e)return null;try{return JSON.parse(e)}catch(e){return null}}rc.supportsNativeHls=function(){if(!d||!d.createElement)return!1;var t=d.createElement("video");if(!ir.getTech("Html5").isSupported())return!1;return["application/vnd.apple.mpegurl","audio/mpegurl","audio/x-mpegurl","application/x-mpegurl","video/x-mpegurl","video/mpegurl","application/mpegurl"].some(function(e){return/maybe|probably/i.test(t.canPlayType(e))})}(),rc.supportsNativeDash=!!(d&&d.createElement&&ir.getTech("Html5").isSupported())&&/maybe|probably/i.test(d.createElement("video").canPlayType("application/dash+xml")),rc.supportsTypeNatively=function(e){return"hls"===e?rc.supportsNativeHls:"dash"===e&&rc.supportsNativeDash},rc.isSupported=function(){return ir.log.warn("HLS is no longer a tech. Please remove it from your player's techOrder.")};var cc=function(r){function e(e,t,i){var n=r.call(this,t,ir.mergeOptions(i.hls,i.vhs))||this;if(i.hls&&Object.keys(i.hls).length&&ir.log.warn("Using hls options is deprecated. Use vhs instead."),"number"==typeof i.initialBandwidth&&(n.options_.bandwidth=i.initialBandwidth),n.logger_=yo("VhsHandler"),t.options_&&t.options_.playerId&&((i=ir(t.options_.playerId)).hasOwnProperty("hls")||Object.defineProperty(i,"hls",{get:function(){return ir.log.warn("player.hls is deprecated. Use player.tech().vhs instead."),t.trigger({type:"usage",name:"hls-player-access"}),yt(n)},configurable:!0}),i.hasOwnProperty("vhs")||Object.defineProperty(i,"vhs",{get:function(){return ir.log.warn("player.vhs is deprecated. Use player.tech().vhs instead."),t.trigger({type:"usage",name:"vhs-player-access"}),yt(n)},configurable:!0}),i.hasOwnProperty("dash")||Object.defineProperty(i,"dash",{get:function(){return ir.log.warn("player.dash is deprecated. Use player.tech().vhs instead."),yt(n)},configurable:!0}),n.player_=i),n.tech_=t,n.source_=e,n.stats={},n.ignoreNextSeekingEvent_=!1,n.setOptions_(),n.options_.overrideNative&&t.overrideNativeAudioTracks&&t.overrideNativeVideoTracks)t.overrideNativeAudioTracks(!0),t.overrideNativeVideoTracks(!0);else if(n.options_.overrideNative&&(t.featuresNativeVideoTracks||t.featuresNativeAudioTracks))throw new Error("Overriding native HLS requires emulated tracks. See https://git.io/vMpjB");return n.on(d,["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange"],function(e){var t=d.fullscreenElement||d.webkitFullscreenElement||d.mozFullScreenElement||d.msFullscreenElement;t&&t.contains(n.tech_.el())?n.masterPlaylistController_.fastQualityChange_():n.masterPlaylistController_.checkABR_()}),n.on(n.tech_,"seeking",function(){this.ignoreNextSeekingEvent_?this.ignoreNextSeekingEvent_=!1:this.setCurrentTime(this.tech_.currentTime())}),n.on(n.tech_,"error",function(){this.tech_.error()&&this.masterPlaylistController_&&this.masterPlaylistController_.pauseLoading()}),n.on(n.tech_,"play",n.play),n}vt(e,r);var t=e.prototype;return t.setOptions_=function(){var e,t=this;this.options_.withCredentials=this.options_.withCredentials||!1,this.options_.handleManifestRedirects=!1!==this.options_.handleManifestRedirects,this.options_.limitRenditionByPlayerDimensions=!1!==this.options_.limitRenditionByPlayerDimensions,this.options_.useDevicePixelRatio=this.options_.useDevicePixelRatio||!1,this.options_.smoothQualityChange=this.options_.smoothQualityChange||!1,this.options_.useBandwidthFromLocalStorage="undefined"!=typeof this.source_.useBandwidthFromLocalStorage?this.source_.useBandwidthFromLocalStorage:this.options_.useBandwidthFromLocalStorage||!1,this.options_.customTagParsers=this.options_.customTagParsers||[],this.options_.customTagMappers=this.options_.customTagMappers||[],this.options_.cacheEncryptionKeys=this.options_.cacheEncryptionKeys||!1,"number"!=typeof this.options_.blacklistDuration&&(this.options_.blacklistDuration=300),"number"!=typeof this.options_.bandwidth&&this.options_.useBandwidthFromLocalStorage&&((e=lc())&&e.bandwidth&&(this.options_.bandwidth=e.bandwidth,this.tech_.trigger({type:"usage",name:"vhs-bandwidth-from-local-storage"}),this.tech_.trigger({type:"usage",name:"hls-bandwidth-from-local-storage"})),e&&e.throughput&&(this.options_.throughput=e.throughput,this.tech_.trigger({type:"usage",name:"vhs-throughput-from-local-storage"}),this.tech_.trigger({type:"usage",name:"hls-throughput-from-local-storage"}))),"number"!=typeof this.options_.bandwidth&&(this.options_.bandwidth=rl.INITIAL_BANDWIDTH),this.options_.enableLowInitialPlaylist=this.options_.enableLowInitialPlaylist&&this.options_.bandwidth===rl.INITIAL_BANDWIDTH,["withCredentials","useDevicePixelRatio","limitRenditionByPlayerDimensions","bandwidth","smoothQualityChange","customTagParsers","customTagMappers","handleManifestRedirects","cacheEncryptionKeys","playlistSelector","initialPlaylistSelector","experimentalBufferBasedABR","liveRangeSafeTimeDelta","experimentalLLHLS","experimentalExactManifestTimings","experimentalLeastPixelDiffSelector"].forEach(function(e){"undefined"!=typeof t.source_[e]&&(t.options_[e]=t.source_[e])}),this.limitRenditionByPlayerDimensions=this.options_.limitRenditionByPlayerDimensions,this.useDevicePixelRatio=this.options_.useDevicePixelRatio},t.src=function(e,t){var n=this;e&&(this.setOptions_(),this.options_.src=0===(e=this.source_.src).toLowerCase().indexOf("data:application/vnd.videojs.vhs+json,")?JSON.parse(e.substring(e.indexOf(",")+1)):e,this.options_.tech=this.tech_,this.options_.externVhs=rc,this.options_.sourceType=_r(t),this.options_.seekTo=function(e){n.tech_.setCurrentTime(e)},this.options_.smoothQualityChange&&ir.log.warn("smoothQualityChange is deprecated and will be removed in the next major version"),this.masterPlaylistController_=new ec(this.options_),t=ir.mergeOptions({liveRangeSafeTimeDelta:.1},this.options_,{seekable:function(){return n.seekable()},media:function(){return n.masterPlaylistController_.media()},masterPlaylistController:this.masterPlaylistController_}),this.playbackWatcher_=new ic(t),this.masterPlaylistController_.on("error",function(){var e=ir.players[n.tech_.options_.playerId],t=n.masterPlaylistController_.error;"object"!=typeof t||t.code?"string"==typeof t&&(t={message:t,code:3}):t.code=3,e.error(t)}),t=this.options_.experimentalBufferBasedABR?rc.movingAverageBandwidthSelector(.55):rc.STANDARD_PLAYLIST_SELECTOR,this.masterPlaylistController_.selectPlaylist=(this.selectPlaylist||t).bind(this),this.masterPlaylistController_.selectInitialPlaylist=rc.INITIAL_PLAYLIST_SELECTOR.bind(this),this.playlists=this.masterPlaylistController_.masterPlaylistLoader_,this.mediaSource=this.masterPlaylistController_.mediaSource,Object.defineProperties(this,{selectPlaylist:{get:function(){return this.masterPlaylistController_.selectPlaylist},set:function(e){this.masterPlaylistController_.selectPlaylist=e.bind(this)}},throughput:{get:function(){return this.masterPlaylistController_.mainSegmentLoader_.throughput.rate},set:function(e){this.masterPlaylistController_.mainSegmentLoader_.throughput.rate=e,this.masterPlaylistController_.mainSegmentLoader_.throughput.count=1}},bandwidth:{get:function(){return this.masterPlaylistController_.mainSegmentLoader_.bandwidth},set:function(e){this.masterPlaylistController_.mainSegmentLoader_.bandwidth=e,this.masterPlaylistController_.mainSegmentLoader_.throughput={rate:0,count:0}}},systemBandwidth:{get:function(){var e=1/(this.bandwidth||1),t=0<this.throughput?1/this.throughput:0;return Math.floor(1/(e+t))},set:function(){ir.log.error('The "systemBandwidth" property is read-only')}}}),this.options_.bandwidth&&(this.bandwidth=this.options_.bandwidth),this.options_.throughput&&(this.throughput=this.options_.throughput),Object.defineProperties(this.stats,{bandwidth:{get:function(){return n.bandwidth||0},enumerable:!0},mediaRequests:{get:function(){return n.masterPlaylistController_.mediaRequests_()||0},enumerable:!0},mediaRequestsAborted:{get:function(){return n.masterPlaylistController_.mediaRequestsAborted_()||0},enumerable:!0},mediaRequestsTimedout:{get:function(){return n.masterPlaylistController_.mediaRequestsTimedout_()||0},enumerable:!0},mediaRequestsErrored:{get:function(){return n.masterPlaylistController_.mediaRequestsErrored_()||0},enumerable:!0},mediaTransferDuration:{get:function(){return n.masterPlaylistController_.mediaTransferDuration_()||0},enumerable:!0},mediaBytesTransferred:{get:function(){return n.masterPlaylistController_.mediaBytesTransferred_()||0},enumerable:!0},mediaSecondsLoaded:{get:function(){return n.masterPlaylistController_.mediaSecondsLoaded_()||0},enumerable:!0},mediaAppends:{get:function(){return n.masterPlaylistController_.mediaAppends_()||0},enumerable:!0},mainAppendsToLoadedData:{get:function(){return n.masterPlaylistController_.mainAppendsToLoadedData_()||0},enumerable:!0},audioAppendsToLoadedData:{get:function(){return n.masterPlaylistController_.audioAppendsToLoadedData_()||0},enumerable:!0},appendsToLoadedData:{get:function(){return n.masterPlaylistController_.appendsToLoadedData_()||0},enumerable:!0},timeToLoadedData:{get:function(){return n.masterPlaylistController_.timeToLoadedData_()||0},enumerable:!0},buffered:{get:function(){return So(n.tech_.buffered())},enumerable:!0},currentTime:{get:function(){return n.tech_.currentTime()},enumerable:!0},currentSource:{get:function(){return n.tech_.currentSource_},enumerable:!0},currentTech:{get:function(){return n.tech_.name_},enumerable:!0},duration:{get:function(){return n.tech_.duration()},enumerable:!0},master:{get:function(){return n.playlists.master},enumerable:!0},playerDimensions:{get:function(){return n.tech_.currentDimensions()},enumerable:!0},seekable:{get:function(){return So(n.tech_.seekable())},enumerable:!0},timestamp:{get:function(){return Date.now()},enumerable:!0},videoPlaybackQuality:{get:function(){return n.tech_.getVideoPlaybackQuality()},enumerable:!0}}),this.tech_.one("canplay",this.masterPlaylistController_.setupFirstPlay.bind(this.masterPlaylistController_)),this.tech_.on("bandwidthupdate",function(){n.options_.useBandwidthFromLocalStorage&&function(e){if(!_.localStorage)return;var t=(t=lc())?ir.mergeOptions(t,e):e;try{_.localStorage.setItem(sc,JSON.stringify(t))}catch(e){return}}({bandwidth:n.bandwidth,throughput:Math.round(n.throughput)})}),this.masterPlaylistController_.on("selectedinitialmedia",function(){var i;(i=n).representations=function(){var e=i.masterPlaylistController_.master(),e=Fo(e)?i.masterPlaylistController_.getAudioTrackPlaylists_():e.playlists;return e?e.filter(function(e){return!Oo(e)}).map(function(e,t){return new xl(i,e,e.id)}):[]}}),this.masterPlaylistController_.sourceUpdater_.on("createdsourcebuffers",function(){n.setupEme_()}),this.on(this.masterPlaylistController_,"progress",function(){this.tech_.trigger("progress")}),this.on(this.masterPlaylistController_,"firstplay",function(){this.ignoreNextSeekingEvent_=!0}),this.setupQualityLevels_(),this.tech_.el()&&(this.mediaSourceUrl_=_.URL.createObjectURL(this.masterPlaylistController_.mediaSource),this.tech_.src(this.mediaSourceUrl_)))},t.setupEme_=function(){var t=this,e=this.masterPlaylistController_.mediaTypes_.AUDIO.activePlaylistLoader,i=uc({player:this.player_,sourceKeySystems:this.source_.keySystems,media:this.playlists.media(),audioMedia:e&&e.media()});this.player_.tech_.on("keystatuschange",function(e){"output-restricted"===e.status&&t.masterPlaylistController_.blacklistCurrentPlaylist({playlist:t.masterPlaylistController_.media(),message:"DRM keystatus changed to "+e.status+". Playlist will fail to play. Check for HDCP content.",blacklistDuration:1/0})}),11!==ir.browser.IE_VERSION&&i?(this.logger_("waiting for EME key session creation"),oc({player:this.player_,sourceKeySystems:this.source_.keySystems,audioMedia:e&&e.media(),mainPlaylists:this.playlists.master.playlists}).then(function(){t.logger_("created EME key session"),t.masterPlaylistController_.sourceUpdater_.initializedEme()}).catch(function(e){t.logger_("error while creating EME key session",e),t.player_.error({message:"Failed to initialize media keys for EME",code:3})})):this.masterPlaylistController_.sourceUpdater_.initializedEme()},t.setupQualityLevels_=function(){var i=this,e=ir.players[this.tech_.options_.playerId];e&&e.qualityLevels&&!this.qualityLevels_&&(this.qualityLevels_=e.qualityLevels(),this.masterPlaylistController_.on("selectedinitialmedia",function(){var t,e;t=i.qualityLevels_,(e=i).representations().forEach(function(e){t.addQualityLevel(e)}),ac(t,e.playlists)}),this.playlists.on("mediachange",function(){ac(i.qualityLevels_,i.playlists)}))},e.version=function(){return{"@videojs/http-streaming":"2.10.2","mux.js":"5.13.0","mpd-parser":"0.19.0","m3u8-parser":"4.7.0","aes-decrypter":"3.1.2"}},t.version=function(){return this.constructor.version()},t.canChangeType=function(){return ql.canChangeType()},t.play=function(){this.masterPlaylistController_.play()},t.setCurrentTime=function(e){this.masterPlaylistController_.setCurrentTime(e)},t.duration=function(){return this.masterPlaylistController_.duration()},t.seekable=function(){return this.masterPlaylistController_.seekable()},t.dispose=function(){this.playbackWatcher_&&this.playbackWatcher_.dispose(),this.masterPlaylistController_&&this.masterPlaylistController_.dispose(),this.qualityLevels_&&this.qualityLevels_.dispose(),this.player_&&(delete this.player_.vhs,delete this.player_.dash,delete this.player_.hls),this.tech_&&this.tech_.vhs&&delete this.tech_.vhs,this.tech_&&delete this.tech_.hls,this.mediaSourceUrl_&&_.URL.revokeObjectURL&&(_.URL.revokeObjectURL(this.mediaSourceUrl_),this.mediaSourceUrl_=null),r.prototype.dispose.call(this)},t.convertToProgramTime=function(e,t){return au({playlist:this.masterPlaylistController_.media(),time:e,callback:t})},t.seekToProgramTime=function(e,t,i,n){return void 0===i&&(i=!0),void 0===n&&(n=2),su({programTime:e,playlist:this.masterPlaylistController_.media(),retryCount:n,pauseAfterSeek:i,seekTo:this.options_.seekTo,tech:this.options_.tech,callback:t})},e}(ir.getComponent("Component")),dc={name:"videojs-http-streaming",VERSION:"2.10.2",canHandleSource:function(e,t){t=ir.mergeOptions(ir.options,t=void 0===t?{}:t);return dc.canPlayType(e.type,t)},handleSource:function(e,t,i){i=ir.mergeOptions(ir.options,i=void 0===i?{}:i);return t.vhs=new cc(e,t,i),ir.hasOwnProperty("hls")||Object.defineProperty(t,"hls",{get:function(){return ir.log.warn("player.tech().hls is deprecated. Use player.tech().vhs instead."),t.vhs},configurable:!0}),t.vhs.xhr=$o(),t.vhs.src(e.src,e.type),t.vhs},canPlayType:function(e,t){t=ir.mergeOptions(ir.options,t=void 0===t?{}:t).vhs.overrideNative,t=void 0===t?!ir.browser.IS_ANY_SAFARI:t,e=_r(e);return e&&(!rc.supportsTypeNatively(e)||t)?"maybe":""}};return yr("avc1.4d400d,mp4a.40.2")&&ir.getTech("Html5").registerSourceHandler(dc,0),ir.VhsHandler=cc,Object.defineProperty(ir,"HlsHandler",{get:function(){return ir.log.warn("videojs.HlsHandler is deprecated. Use videojs.VhsHandler instead."),cc},configurable:!0}),ir.VhsSourceHandler=dc,Object.defineProperty(ir,"HlsSourceHandler",{get:function(){return ir.log.warn("videojs.HlsSourceHandler is deprecated. Use videojs.VhsSourceHandler instead."),dc},configurable:!0}),ir.Vhs=rc,Object.defineProperty(ir,"Hls",{get:function(){return ir.log.warn("videojs.Hls is deprecated. Use videojs.Vhs instead."),rc},configurable:!0}),ir.use||(ir.registerComponent("Hls",rc),ir.registerComponent("Vhs",rc)),ir.options.vhs=ir.options.vhs||{},ir.options.hls=ir.options.hls||{},ir.registerPlugin?ir.registerPlugin("reloadSourceOnError",K):ir.plugin("reloadSourceOnError",K),ir});
\ No newline at end of file
+++ /dev/null
-/**
- * Customized for fluidbook (search lines with scaleX or scaleY)
- */
-/**
- * @license
- * Video.js 6.4.0 <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 (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
- typeof define === 'function' && define.amd ? define(factory) :
- (global.videojs = factory());
-}(this, (function () {
-
- var version = "6.4.0";
-
- var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
-
-
- function createCommonjsModule(fn, module) {
- return module = {exports: {}}, fn(module, module.exports), module.exports;
- }
-
- var win;
-
- if (typeof window !== "undefined") {
- win = window;
- } else if (typeof commonjsGlobal !== "undefined") {
- win = commonjsGlobal;
- } else if (typeof self !== "undefined") {
- win = self;
- } else {
- win = {};
- }
-
- var window_1 = win;
-
- var empty = {};
-
-
- var empty$1 = (Object.freeze || Object)({
- 'default': empty
- });
-
- var minDoc = (empty$1 && empty) || empty$1;
-
- var topLevel = typeof commonjsGlobal !== 'undefined' ? commonjsGlobal :
- typeof window !== 'undefined' ? window : {};
-
-
- var doccy;
-
- if (typeof document !== 'undefined') {
- doccy = document;
- } else {
- doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];
-
- if (!doccy) {
- doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;
- }
- }
-
- var document_1 = doccy;
-
- /**
- * @file browser.js
- * @module browser
- */
- var USER_AGENT = window_1.navigator && window_1.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);
-
-// 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;
- var IS_IPOD = /iPod/i.test(USER_AGENT);
- var IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;
-
- var IOS_VERSION = function () {
- var match = USER_AGENT.match(/OS (\d+)_/i);
-
- if (match && match[1]) {
- return match[1];
- }
- return null;
- }();
-
- var IS_ANDROID = /Android/i.test(USER_AGENT);
- 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);
-
- if (!match) {
- return null;
- }
-
- var major = match[1] && parseFloat(match[1]);
- var minor = match[2] && parseFloat(match[2]);
-
- if (major && minor) {
- return parseFloat(match[1] + '.' + match[2]);
- } else if (major) {
- return major;
- }
- return null;
- }();
-
-// 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;
- var IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537;
-
- var IS_FIREFOX = /Firefox/i.test(USER_AGENT);
- var IS_EDGE = /Edge/i.test(USER_AGENT);
- var IS_CHROME = !IS_EDGE && /Chrome/i.test(USER_AGENT);
- var CHROME_VERSION = function () {
- var match = USER_AGENT.match(/Chrome\/(\d+)/);
-
- if (match && match[1]) {
- return parseFloat(match[1]);
- }
- return null;
- }();
- var IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT);
- var IE_VERSION = function () {
- var result = /MSIE\s(\d+)\.\d/.exec(USER_AGENT);
- var version = result && parseFloat(result[1]);
-
- if (!version && /Trident\/7.0/i.test(USER_AGENT) && /rv:11.0/.test(USER_AGENT)) {
- // IE 11 has a different user agent string than other IE versions
- version = 11.0;
- }
-
- return version;
- }();
-
- var IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE;
- var IS_ANY_SAFARI = IS_SAFARI || IS_IOS;
-
- var TOUCH_ENABLED = isReal() && ('ontouchstart' in window_1 || window_1.DocumentTouch && window_1.document instanceof window_1.DocumentTouch);
-
- var BACKGROUND_SIZE_SUPPORTED = isReal() && 'backgroundSize' in window_1.document.createElement('video').style;
-
- var browser = (Object.freeze || Object)({
- IS_IPAD: IS_IPAD,
- IS_IPHONE: IS_IPHONE,
- IS_IPOD: IS_IPOD,
- IS_IOS: IS_IOS,
- IOS_VERSION: IOS_VERSION,
- IS_ANDROID: IS_ANDROID,
- ANDROID_VERSION: ANDROID_VERSION,
- IS_OLD_ANDROID: IS_OLD_ANDROID,
- IS_NATIVE_ANDROID: IS_NATIVE_ANDROID,
- IS_FIREFOX: IS_FIREFOX,
- IS_EDGE: IS_EDGE,
- IS_CHROME: IS_CHROME,
- CHROME_VERSION: CHROME_VERSION,
- IS_IE8: IS_IE8,
- IE_VERSION: IE_VERSION,
- IS_SAFARI: IS_SAFARI,
- IS_ANY_SAFARI: IS_ANY_SAFARI,
- TOUCH_ENABLED: TOUCH_ENABLED,
- BACKGROUND_SIZE_SUPPORTED: BACKGROUND_SIZE_SUPPORTED
- });
-
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
- return typeof obj;
- } : function (obj) {
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- };
-
-
- var classCallCheck = function (instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- };
-
-
- var inherits = function (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 possibleConstructorReturn = function (self, call) {
- if (!self) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
-
- return call && (typeof call === "object" || typeof call === "function") ? call : self;
- };
-
-
- var taggedTemplateLiteralLoose = function (strings, raw) {
- strings.raw = raw;
- return strings;
- };
-
- /**
- * @file obj.js
- * @module obj
- */
-
- /**
- * @callback obj:EachCallback
- *
- * @param {Mixed} value
- * The current key for the object that is being iterated over.
- *
- * @param {string} key
- * The current key-value for object that is being iterated over
- */
-
- /**
- * @callback obj:ReduceCallback
- *
- * @param {Mixed} accum
- * The value that is accumulating over the reduce loop.
- *
- * @param {Mixed} value
- * The current key for the object that is being iterated over.
- *
- * @param {string} key
- * The current key-value for object that is being iterated over
- *
- * @return {Mixed}
- * The new accumulated value.
- */
- var toString = Object.prototype.toString;
-
- /**
- * Get the keys of an Object
- *
- * @param {Object}
- * The Object to get the keys from
- *
- * @return {string[]}
- * An array of the keys from the object. Returns an empty array if the
- * object passed in was invalid or had no keys.
- *
- * @private
- */
- var keys = function keys(object) {
- return isObject(object) ? Object.keys(object) : [];
- };
-
- /**
- * Array-like iteration for objects.
- *
- * @param {Object} object
- * The object to iterate over
- *
- * @param {obj:EachCallback} fn
- * The callback function which is called for each key in the object.
- */
- function each(object, fn) {
- keys(object).forEach(function (key) {
- return fn(object[key], key);
- });
- }
-
- /**
- * Array-like reduce for objects.
- *
- * @param {Object} object
- * The Object that you want to reduce.
- *
- * @param {Function} fn
- * A callback function which is called for each key in the object. It
- * receives the accumulated value and the per-iteration value and key
- * as arguments.
- *
- * @param {Mixed} [initial = 0]
- * Starting value
- *
- * @return {Mixed}
- * The final accumulated value.
- */
- function reduce(object, fn) {
- var initial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
-
- return keys(object).reduce(function (accum, key) {
- return fn(accum, object[key], key);
- }, initial);
- }
-
- /**
- * Object.assign-style object shallow merge/extend.
- *
- * @param {Object} target
- * @param {Object} ...sources
- * @return {Object}
- */
- function assign(target) {
- for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
- sources[_key - 1] = arguments[_key];
- }
-
- if (Object.assign) {
- return Object.assign.apply(Object, [target].concat(sources));
- }
-
- sources.forEach(function (source) {
- if (!source) {
- return;
- }
-
- each(source, function (value, key) {
- target[key] = value;
- });
- });
-
- return target;
- }
-
- /**
- * Returns whether a value is an object of any kind - including DOM nodes,
- * arrays, regular expressions, etc. Not functions, though.
- *
- * This avoids the gotcha where using `typeof` on a `null` value
- * results in `'object'`.
- *
- * @param {Object} value
- * @return {Boolean}
- */
- function isObject(value) {
- return !!value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object';
- }
-
- /**
- * Returns whether an object appears to be a "plain" object - that is, a
- * direct instance of `Object`.
- *
- * @param {Object} value
- * @return {Boolean}
- */
- function isPlain(value) {
- return isObject(value) && toString.call(value) === '[object Object]' && value.constructor === Object;
- }
-
- /**
- * @file log.js
- * @module log
- */
- var log = void 0;
-
-// This is the private tracking variable for logging level.
- var level = 'all';
-
-// This is the private tracking variable for the logging history.
- var history = [];
-
- /**
- * Log messages to the console and history based on the type of message
- *
- * @private
- * @param {string} type
- * The name of the console method to use.
- *
- * @param {Array} args
- * The arguments to be passed to the matching console method.
- *
- * @param {boolean} [stringify]
- * By default, only old IEs should get console argument stringification,
- * but this is exposed as a parameter to facilitate testing.
- */
- var logByType = function logByType(type, args) {
- var stringify = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : !!IE_VERSION && IE_VERSION < 11;
-
- var lvl = log.levels[level];
- var lvlRegExp = new RegExp('^(' + lvl + ')$');
-
- if (type !== 'log') {
-
- // Add the type to the front of the message when it's not "log".
- args.unshift(type.toUpperCase() + ':');
- }
-
- // Add a clone of the args at this point to history.
- if (history) {
- history.push([].concat(args));
- }
-
- // Add console prefix after adding to history.
- args.unshift('VIDEOJS:');
-
- // If there's no console then don't try to output messages, but they will
- // still be stored in 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
- // when the module is executed.
- var fn = window_1.console && window_1.console[type];
-
- // Bail out if there's no console or if this type is not allowed by the
- // current logging level.
- if (!fn || !lvl || !lvlRegExp.test(type)) {
- return;
- }
-
- // IEs previous to 11 log objects uselessly as "[object Object]"; so, JSONify
- // objects and arrays for those less-capable browsers.
- if (stringify) {
- args = args.map(function (a) {
- if (isObject(a) || Array.isArray(a)) {
- try {
- return JSON.stringify(a);
- } catch (x) {
- return String(a);
- }
- }
-
- // Cast to string before joining, so we get null and undefined explicitly
- // included in output (as we would in a modern console).
- return String(a);
- }).join(' ');
- }
-
- // Old IE versions do not allow .apply() for console methods (they are
- // reported as objects rather than functions).
- if (!fn.apply) {
- fn(args);
- } else {
- fn[Array.isArray(args) ? 'apply' : 'call'](window_1.console, args);
- }
- };
-
- /**
- * Logs plain debug messages. Similar to `console.log`.
- *
- * @class
- * @param {Mixed[]} args
- * One or more messages or objects that should be logged.
- */
- log = function log() {
- for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
- args[_key] = arguments[_key];
- }
-
- logByType('log', args);
- };
-
- /**
- * Enumeration of available logging levels, where the keys are the level names
- * and the values are `|`-separated strings containing logging methods allowed
- * in that logging level. These strings are used to create a regular expression
- * matching the function name being called.
- *
- * Levels provided by video.js are:
- *
- * - `off`: Matches no calls. Any value that can be cast to `false` will have
- * this effect. The most restrictive.
- * - `all` (default): Matches only Video.js-provided functions (`log`,
- * `log.warn`, and `log.error`).
- * - `warn`: Matches `log.warn` and `log.error` calls.
- * - `error`: Matches only `log.error` calls.
- *
- * @type {Object}
- */
- log.levels = {
- all: 'log|warn|error',
- error: 'error',
- off: '',
- warn: 'warn|error',
- DEFAULT: level
- };
-
- /**
- * Get or set the current logging level. If a string matching a key from
- * {@link log.levels} is provided, acts as a setter. Regardless of argument,
- * returns the current logging level.
- *
- * @param {string} [lvl]
- * Pass to set a new logging level.
- *
- * @return {string}
- * The current logging level.
- */
- log.level = function (lvl) {
- if (typeof lvl === 'string') {
- if (!log.levels.hasOwnProperty(lvl)) {
- throw new Error('"' + lvl + '" in not a valid log level');
- }
- level = lvl;
- }
- return level;
- };
-
- /**
- * Returns an array containing everything that has been logged to the history.
- *
- * This array is a shallow clone of the internal history record. However, its
- * contents are _not_ cloned; so, mutating objects inside this array will
- * mutate them in history.
- *
- * @return {Array}
- */
- log.history = function () {
- return history ? [].concat(history) : [];
- };
-
- /**
- * Clears the internal history tracking, but does not prevent further history
- * tracking.
- */
- log.history.clear = function () {
- if (history) {
- history.length = 0;
- }
- };
-
- /**
- * Disable history tracking if it is currently enabled.
- */
- log.history.disable = function () {
- if (history !== null) {
- history.length = 0;
- history = null;
- }
- };
-
- /**
- * Enable history tracking if it is currently disabled.
- */
- log.history.enable = function () {
- if (history === null) {
- history = [];
- }
- };
-
- /**
- * Logs error messages. Similar to `console.error`.
- *
- * @param {Mixed[]} args
- * One or more messages or objects that should be logged as an error
- */
- log.error = function () {
- for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
- args[_key2] = arguments[_key2];
- }
-
- return logByType('error', args);
- };
-
- /**
- * Logs warning messages. Similar to `console.warn`.
- *
- * @param {Mixed[]} args
- * One or more messages or objects that should be logged as a warning.
- */
- log.warn = function () {
- for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
- args[_key3] = arguments[_key3];
- }
-
- return logByType('warn', args);
- };
-
- var log$1 = log;
-
- function clean(s) {
- return s.replace(/\n\r?\s*/g, '')
- }
-
-
- var tsml = function tsml(sa) {
- var s = ''
- , i = 0;
-
- for (; i < arguments.length; i++)
- s += clean(sa[i]) + (arguments[i + 1] || '');
-
- return s
- };
-
- /**
- * @file computed-style.js
- * @module computed-style
- */
- /**
- * A safe getComputedStyle with an IE8 fallback.
- *
- * This is needed because in Firefox, if the player is loaded in an iframe with
- * `display:none`, then `getComputedStyle` returns `null`, so, we do a null-check to
- * make sure that the player doesn't break in these cases.
- *
- * @param {Element} el
- * The element you want the computed style of
- *
- * @param {string} prop
- * The property name you want
- *
- * @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397
- *
- * @static
- * @const
- */
- function computedStyle(el, prop) {
- if (!el || !prop) {
- return '';
- }
-
- if (typeof window_1.getComputedStyle === 'function') {
- var cs = window_1.getComputedStyle(el);
-
- return cs ? cs[prop] : '';
- }
-
- return el.currentStyle[prop] || '';
- }
-
- 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 ', '.']);
-
- /**
- * @file dom.js
- * @module dom
- */
- /**
- * Detect if a value is a string with any non-whitespace characters.
- *
- * @param {string} str
- * The string to check
- *
- * @return {boolean}
- * - True if the string is non-blank
- * - False otherwise
- *
- */
- 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
- * The string to check for whitespace.
- *
- * @throws {Error}
- * Throws an error if there is whitespace in the string.
- *
- */
- function throwIfWhitespace(str) {
- if (/\s/.test(str)) {
- throw new Error('class has illegal whitespace characters');
- }
- }
-
- /**
- * Produce a regular expression for matching a className within an elements className.
- *
- * @param {string} className
- * The className to generate the RegExp for.
- *
- * @return {RegExp}
- * The RegExp that will check for a specific `className` in an elements
- * className.
- */
- function classRegExp(className) {
- return new RegExp('(^|\\s)' + className + '($|\\s)');
- }
-
- /**
- * Whether the current DOM interface appears to be real.
- *
- * @return {Boolean}
- */
- function isReal() {
- return (
-
- // Both document and window will never be undefined thanks to `global`.
- document_1 === window_1.document &&
-
- // In IE < 9, DOM methods return "object" as their type, so all we can
- // confidently check is that it exists.
- typeof document_1.createElement !== 'undefined'
- );
- }
-
- /**
- * Determines, via duck typing, whether or not a value is a DOM element.
- *
- * @param {Mixed} value
- * The thing to check
- *
- * @return {boolean}
- * - True if it is a DOM element
- * - False otherwise
- */
- function isEl(value) {
- return isObject(value) && value.nodeType === 1;
- }
-
- /**
- * Determines if the current DOM is embedded in an iframe.
- *
- * @return {boolean}
- *
- */
- function isInFrame() {
-
- // We need a try/catch here because Safari will throw errors when attempting
- // to get either `parent` or `self`
- try {
- return window_1.parent !== window_1.self;
- } catch (x) {
- return true;
- }
- }
-
- /**
- * Creates functions to query the DOM using a given method.
- *
- * @param {string} method
- * The method to create the query with.
- *
- * @return {Function}
- * The query method
- */
- function createQuerier(method) {
- return function (selector, context) {
- if (!isNonBlankString(selector)) {
- return document_1[method](null);
- }
- if (isNonBlankString(context)) {
- context = document_1.querySelector(context);
- }
-
- var ctx = isEl(context) ? context : document_1;
-
- return ctx[method] && ctx[method](selector);
- };
- }
-
- /**
- * 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.
- *
- * @param {String|Element|TextNode|Array|Function} [content]
- * Contents for the element (see: {@link dom:normalizeContent})
- *
- * @return {Element}
- * The element that was created.
- */
- function createEl() {
- var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
- var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
- var content = arguments[3];
-
- var el = document_1.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') {
- log$1.warn(tsml(_templateObject, propName, val));
- el.setAttribute(propName, val);
-
- // Handle textContent since it's not supported everywhere and we have a
- // method for it.
- } else if (propName === 'textContent') {
- textContent(el, val);
- } else {
- el[propName] = val;
- }
- });
-
- Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
- el.setAttribute(attrName, attributes[attrName]);
- });
-
- if (content) {
- appendContent(el, content);
- }
-
- return el;
- }
-
- /**
- * Injects text into an element, replacing any existing contents entirely.
- *
- * @param {Element} el
- * The element to add text content into
- *
- * @param {string} text
- * The text content to add.
- *
- * @return {Element}
- * The element with added text content.
- */
- function textContent(el, text) {
- if (typeof el.textContent === 'undefined') {
- el.innerText = text;
- } else {
- el.textContent = text;
- }
- return el;
- }
-
- /**
- * Insert an element as the first child node of another
- *
- * @param {Element} child
- * Element to insert
- *
- * @param {Element} parent
- * Element to insert child into
- */
- function prependTo(child, parent) {
- if (parent.firstChild) {
- parent.insertBefore(child, parent.firstChild);
- } else {
- parent.appendChild(child);
- }
- }
-
- /**
- * Check if an element has a CSS class
- *
- * @param {Element} element
- * Element to check
- *
- * @param {string} classToCheck
- * Class name to check for
- *
- * @return {boolean}
- * - True if the element had the class
- * - False otherwise.
- *
- * @throws {Error}
- * Throws an error if `classToCheck` has white space.
- */
- function hasClass(element, classToCheck) {
- throwIfWhitespace(classToCheck);
- if (element.classList) {
- return element.classList.contains(classToCheck);
- }
- return classRegExp(classToCheck).test(element.className);
- }
-
- /**
- * Add a CSS class name to an element
- *
- * @param {Element} element
- * Element to add class name to.
- *
- * @param {string} classToAdd
- * Class name to add.
- *
- * @return {Element}
- * The dom element with the added class name.
- */
- function addClass(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 (!hasClass(element, classToAdd)) {
- element.className = (element.className + ' ' + classToAdd).trim();
- }
-
- return element;
- }
-
- /**
- * Remove a CSS class name from an element
- *
- * @param {Element} element
- * Element to remove a class name from.
- *
- * @param {string} classToRemove
- * Class name to remove
- *
- * @return {Element}
- * The dom element with class name removed.
- */
- function removeClass(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;
- }
-
- /**
- * The callback definition for toggleElClass.
- *
- * @callback Dom~PredicateCallback
- * @param {Element} element
- * The DOM element of the Component.
- *
- * @param {string} classToToggle
- * The `className` that wants to be toggled
- *
- * @return {boolean|undefined}
- * - If true the `classToToggle` will get added to `element`.
- * - If false the `classToToggle` will get removed from `element`.
- * - If undefined this callback will be ignored
- */
-
- /**
- * Adds or removes a CSS class name on an element depending on an optional
- * condition or the presence/absence of the class name.
- *
- * @param {Element} element
- * The element to toggle a class name on.
- *
- * @param {string} classToToggle
- * The class that should be toggled
- *
- * @param {boolean|PredicateCallback} [predicate]
- * See the return value for {@link Dom~PredicateCallback}
- *
- * @return {Element}
- * The element with a class that has been toggled.
- */
- function toggleClass(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 = hasClass(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) {
- addClass(element, classToToggle);
- } else {
- removeClass(element, classToToggle);
- }
-
- return element;
- }
-
- /**
- * Apply attributes to an HTML element.
- *
- * @param {Element} el
- * Element to add attributes to.
- *
- * @param {Object} [attributes]
- * Attributes to be applied.
- */
- function setAttributes(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}
- * All attributes of the element.
- */
- function getAttributes(tag) {
- var 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
- var knownBooleans = ',' + 'autoplay,controls,playsinline,loop,muted,default,defaultMuted' + ',';
-
- if (tag && tag.attributes && tag.attributes.length > 0) {
- var attrs = tag.attributes;
-
- for (var i = attrs.length - 1; i >= 0; i--) {
- var attrName = attrs[i].name;
- var 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;
- }
-
- /**
- * Get the value of an element's attribute
- *
- * @param {Element} el
- * A DOM element
- *
- * @param {string} attribute
- * Attribute to get the value of
- *
- * @return {string}
- * value of the attribute
- */
- function getAttribute(el, attribute) {
- return el.getAttribute(attribute);
- }
-
- /**
- * Set the value of an element's attribute
- *
- * @param {Element} el
- * A DOM element
- *
- * @param {string} attribute
- * Attribute to set
- *
- * @param {string} value
- * Value to set the attribute to
- */
- function setAttribute(el, attribute, value) {
- el.setAttribute(attribute, value);
- }
-
- /**
- * Remove an element's attribute
- *
- * @param {Element} el
- * A DOM element
- *
- * @param {string} attribute
- * Attribute to remove
- */
- function removeAttribute(el, attribute) {
- el.removeAttribute(attribute);
- }
-
- /**
- * Attempt to block the ability to select text while dragging controls
- */
- function blockTextSelection() {
- document_1.body.focus();
- document_1.onselectstart = function () {
- return false;
- };
- }
-
- /**
- * Turn off text selection blocking
- */
- function unblockTextSelection() {
- document_1.onselectstart = function () {
- return true;
- };
- }
-
- /**
- * Identical to the native `getBoundingClientRect` function, but ensures that
- * the method is supported at all (it is in all browsers we claim to support)
- * and that the element is in the DOM before continuing.
- *
- * This wrapper function also shims properties which are not provided by some
- * older browsers (namely, IE8).
- *
- * Additionally, some browsers do not support adding properties to a
- * `ClientRect`/`DOMRect` object; so, we shallow-copy it with the standard
- * properties (except `x` and `y` which are not widely supported). This helps
- * avoid implementations where keys are non-enumerable.
- *
- * @param {Element} el
- * Element whose `ClientRect` we want to calculate.
- *
- * @return {Object|undefined}
- * Always returns a plain
- */
- function getBoundingClientRect(el) {
- if (el && el.getBoundingClientRect && el.parentNode) {
- var rect = el.getBoundingClientRect();
- var result = {};
-
- ['bottom', 'height', 'left', 'right', 'top', 'width'].forEach(function (k) {
- if (rect[k] !== undefined) {
- result[k] = rect[k];
- }
- });
-
- if (!result.height) {
- result.height = parseFloat(computedStyle(el, 'height'));
- }
-
- if (!result.width) {
- result.width = parseFloat(computedStyle(el, 'width'));
- }
-
- return result;
- }
- }
-
- /**
- * The postion of a DOM element on the page.
- *
- * @typedef {Object} module:dom~Position
- *
- * @property {number} left
- * Pixels to the left
- *
- * @property {number} top
- * Pixels on top
- */
-
- /**
- * Offset Left.
- * getBoundingClientRect technique from
- * John Resig
- *
- * @see http://ejohn.org/blog/getboundingclientrect-is-awesome/
- *
- * @param {Element} el
- * Element from which to get offset
- *
- * @return {module:dom~Position}
- * The position of the element that was passed in.
- */
- function findPosition(el) {
- var box = void 0;
-
- if (el.getBoundingClientRect && el.parentNode) {
- box = el.getBoundingClientRect();
- }
-
- if (!box) {
- return {
- left: 0,
- top: 0
- };
- }
-
- var docEl = document_1.documentElement;
- var body = document_1.body;
-
- var clientLeft = docEl.clientLeft || body.clientLeft || 0;
- var scrollLeft = window_1.pageXOffset || body.scrollLeft;
- var left = box.left + scrollLeft - clientLeft;
-
- var clientTop = docEl.clientTop || body.clientTop || 0;
- var scrollTop = window_1.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)
- };
- }
-
- /**
- * x and y coordinates for a dom element or mouse pointer
- *
- * @typedef {Object} Dom~Coordinates
- *
- * @property {number} x
- * x coordinate in pixels
- *
- * @property {number} y
- * y coordinate in pixels
- */
-
- /**
- * 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.
- *
- * @param {Element} el
- * Element on which to get the pointer position on
- *
- * @param {EventTarget~Event} event
- * Event object
- *
- * @return {Dom~Coordinates}
- * A Coordinates object corresponding to the mouse position.
- *
- */
- function getPointerPosition(el, event) {
- var position = {};
- var box = videojs.dom.findPosition(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;
- }
-
- var scaleX = el.getBoundingClientRect().width / el.offsetWidth;
- var scaleY = el.getBoundingClientRect().height / el.offsetHeight;
-
- position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / (boxH * scaleY)));
- position.x = Math.max(0, Math.min(1, (pageX - boxX) / (boxW * scaleX)));
-
- return position;
- }
-
- /**
- * Determines, via duck typing, whether or not a value is a text node.
- *
- * @param {Mixed} value
- * Check if this value is a text node.
- *
- * @return {boolean}
- * - True if it is a text node
- * - False otherwise
- */
- function isTextNode(value) {
- return isObject(value) && value.nodeType === 3;
- }
-
- /**
- * Empties the contents of an element.
- *
- * @param {Element} el
- * The element to empty children from
- *
- * @return {Element}
- * The element with no children
- */
- 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:
- *
- * @param {String|Element|TextNode|Array|Function} content
- * - 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 as defined above.
- *
- * @return {Array}
- * All of the content that was passed in normalized.
- */
- 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 document_1.createTextNode(value);
- }
- }).filter(function (value) {
- return value;
- });
- }
-
- /**
- * Normalizes and appends content to an element.
- *
- * @param {Element} el
- * Element to append normalized content to.
- *
- *
- * @param {String|Element|TextNode|Array|Function} content
- * See the `content` argument of {@link dom:normalizeContent}
- *
- * @return {Element}
- * The element with appended normalized content.
- */
- 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.
- *
- * @param {Element} el
- * Element to insert normalized content into.
- *
- * @param {String|Element|TextNode|Array|Function} content
- * See the `content` argument of {@link dom:normalizeContent}
- *
- * @return {Element}
- * The element with inserted normalized content.
- *
- */
- 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`).
- *
- * @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}
- * The element that was found or null.
- */
- var $ = createQuerier('querySelector');
-
- /**
- * Finds a all DOM elements matching `selector` within the optional
- * `context` of another DOM element (defaulting to `document`).
- *
- * @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}
- * A element list of elements that were found. Will be empty if none were found.
- *
- */
- var $$ = createQuerier('querySelectorAll');
-
-
- var Dom = (Object.freeze || Object)({
- isReal: isReal,
- isEl: isEl,
- isInFrame: isInFrame,
- createEl: createEl,
- textContent: textContent,
- prependTo: prependTo,
- hasClass: hasClass,
- addClass: addClass,
- removeClass: removeClass,
- toggleClass: toggleClass,
- setAttributes: setAttributes,
- getAttributes: getAttributes,
- getAttribute: getAttribute,
- setAttribute: setAttribute,
- removeAttribute: removeAttribute,
- blockTextSelection: blockTextSelection,
- unblockTextSelection: unblockTextSelection,
- getBoundingClientRect: getBoundingClientRect,
- findPosition: findPosition,
- getPointerPosition: getPointerPosition,
- isTextNode: isTextNode,
- emptyEl: emptyEl,
- normalizeContent: normalizeContent,
- appendContent: appendContent,
- insertContent: insertContent,
- $: $,
- $$: $$
- });
-
- /**
- * @file guid.js
- * @module guid
- */
-
- /**
- * Unique ID for an element or function
- * @type {Number}
- */
- var _guid = 1;
-
- /**
- * Get a unique auto-incrementing ID by number that has not been returned before.
- *
- * @return {number}
- * A new unique ID.
- */
- function newGUID() {
- return _guid++;
- }
-
- /**
- * @file dom-data.js
- * @module dom-data
- */
- /**
- * 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}
- * The cache object for that el that was passed in.
- */
- function getData(el) {
- var id = el[elIdAttr];
-
- if (!id) {
- id = el[elIdAttr] = newGUID();
- }
-
- if (!elData[id]) {
- elData[id] = {};
- }
-
- return elData[id];
- }
-
- /**
- * Returns whether or not an element has cached data
- *
- * @param {Element} el
- * Check if this element has cached data.
- *
- * @return {boolean}
- * - True if the DOM element has cached data.
- * - False otherwise.
- */
- function hasData(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 cached data for this element.
- */
- function removeData(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;
- }
- }
- }
-
- /**
- * @file events.js. An 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.
- *
- * @module events
- */
-
- /**
- * Clean up the listener cache and dispatchers
- *
- * @param {Element|Object} elem
- * Element to clean up
- *
- * @param {string} type
- * Type of event to clean up
- */
- function _cleanUpEvents(elem, type) {
- var data = getData(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) {
- removeData(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 {EventTarget~EventListener} callback
- * Event listener.
- */
- function _handleMultipleEvents(fn, elem, types, callback) {
- types.forEach(function (type) {
- // Call the event method for each one of the types
- fn(elem, type, callback);
- });
- }
-
- /**
- * Fix a native event to have standard property values
- *
- * @param {Object} event
- * Event object to fix.
- *
- * @return {Object}
- * Fixed event object.
- */
- 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 || window_1.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 || document_1;
- }
-
- // 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 && event.clientX !== undefined) {
- var doc = document_1.documentElement;
- var body = document_1.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 !== undefined) {
-
- // The following is disabled because it does not pass videojs-standard
- // and... yikes.
- /* eslint-disable */
- event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0;
- /* eslint-enable */
- }
- }
-
- // Returns fixed-up instance
- return event;
- }
-
- /**
- * Whether passive event listeners are supported
- */
- var _supportsPassive = false;
-
- (function () {
- try {
- var opts = Object.defineProperty({}, 'passive', {
- get: function get() {
- _supportsPassive = true;
- }
- });
-
- window_1.addEventListener('test', null, opts);
- } catch (e) {
- // disregard
- }
- })();
-
- /**
- * Touch events Chrome expects to be passive
- */
- var passiveEvents = ['touchstart', 'touchmove'];
-
- /**
- * 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|string[]} type
- * Type of event to bind to.
- *
- * @param {EventTarget~EventListener} fn
- * Event listener.
- */
- function on(elem, type, fn) {
- if (Array.isArray(type)) {
- return _handleMultipleEvents(on, elem, type, fn);
- }
-
- var data = getData(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 = 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 {
- try {
- handlersCopy[m].call(elem, event, hash);
- } catch (e) {
- log$1.error(e);
- }
- }
- }
- }
- };
- }
-
- if (data.handlers[type].length === 1) {
- if (elem.addEventListener) {
- var options = false;
-
- if (_supportsPassive && passiveEvents.indexOf(type) > -1) {
- options = {passive: true};
- }
- elem.addEventListener(type, data.dispatcher, options);
- } 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|string[]} [type]
- * Type of listener to remove. Don't include to remove all events from element.
- *
- * @param {EventTarget~EventListener} [fn]
- * Specific listener to remove. Don't include to remove listeners for an event
- * type.
- */
- function off(elem, type, fn) {
- // Don't want to add a cache object through getElData if not needed
- if (!hasData(elem)) {
- return;
- }
-
- var data = getData(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 === undefined) {
- for (var t in data.handlers) {
- if (Object.prototype.hasOwnProperty.call(data.handlers || {}, t)) {
- 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 {EventTarget~Event|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|undefined}
- * - Returns the opposite of `defaultPrevented` if default was prevented
- * - Otherwise returns undefined
- */
- 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 = hasData(elem) ? getData(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 = getData(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 bind to.
- *
- * @param {string|string[]} type
- * Name/type of event
- *
- * @param {Event~EventListener} fn
- * Event Listener function
- */
- 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 || newGUID();
- on(elem, type, func);
- }
-
- var Events = (Object.freeze || Object)({
- fixEvent: fixEvent,
- on: on,
- off: off,
- trigger: trigger,
- one: one
- });
-
- /**
- * @file setup.js - Functions for setting up a player without
- * user interaction based on the data-setup `attribute` of the video tag.
- *
- * @module setup
- */
- var _windowLoaded = false;
- var videojs$2 = void 0;
-
- /**
- * Set up any tags that have a data-setup `attribute` when the player is started.
- */
- var autoSetup = function autoSetup() {
-
- // Protect against breakage in non-browser environments.
- if (!isReal()) {
- return;
- }
-
- // 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 = document_1.getElementsByTagName('video');
- var audios = document_1.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 _i2 = 0, _e2 = mediaEls.length; _i2 < _e2; _i2++) {
- var mediaEl = mediaEls[_i2];
-
- // 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.
- videojs$2(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);
- }
- };
-
- /**
- * Wait until the page is loaded before running autoSetup. This will be called in
- * autoSetup if `hasLoaded` returns false.
- *
- * @param {number} wait
- * How long to wait in ms
- *
- * @param {module:videojs} [vjs]
- * The videojs library function
- */
- function autoSetupTimeout(wait, vjs) {
- if (vjs) {
- videojs$2 = vjs;
- }
-
- window_1.setTimeout(autoSetup, wait);
- }
-
- if (isReal() && document_1.readyState === 'complete') {
- _windowLoaded = true;
- } else {
- /**
- * Listen for the load event on window, and set _windowLoaded to true.
- *
- * @listens load
- */
- one(window_1, 'load', function () {
- _windowLoaded = true;
- });
- }
-
- /**
- * @file stylesheet.js
- * @module stylesheet
- */
- /**
- * Create a DOM syle element given a className for it.
- *
- * @param {string} className
- * The className to add to the created style element.
- *
- * @return {Element}
- * The element that was created.
- */
- var createStyleElement = function createStyleElement(className) {
- var style = document_1.createElement('style');
-
- style.className = className;
-
- return style;
- };
-
- /**
- * Add text to a DOM element.
- *
- * @param {Element} el
- * The Element to add text content to.
- *
- * @param {string} content
- * The text to add to the element.
- */
- var setTextContent = function setTextContent(el, content) {
- if (el.styleSheet) {
- el.styleSheet.cssText = content;
- } else {
- el.textContent = content;
- }
- };
-
- /**
- * @file fn.js
- * @module fn
- */
- /**
- * 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 {Mixed} 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}
- * The new function that will be bound into the context given
- */
- var bind = function bind(context, fn, uid) {
- // Make sure the function has a unique ID
- if (!fn.guid) {
- fn.guid = newGUID();
- }
-
- // Create the new function that changes the context
- var bound = function bound() {
- 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
- bound.guid = uid ? uid + '_' + fn.guid : fn.guid;
-
- return bound;
- };
-
- /**
- * Wraps the given function, `fn`, with a new function that only invokes `fn`
- * at most once per every `wait` milliseconds.
- *
- * @param {Function} fn
- * The function to be throttled.
- *
- * @param {Number} wait
- * The number of milliseconds by which to throttle.
- *
- * @return {Function}
- */
- var throttle = function throttle(fn, wait) {
- var last = Date.now();
-
- var throttled = function throttled() {
- var now = Date.now();
-
- if (now - last >= wait) {
- fn.apply(undefined, arguments);
- last = now;
- }
- };
-
- return throttled;
- };
-
- /**
- * @file src/js/event-target.js
- */
- /**
- * `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It
- * adds shorthand functions that wrap around lengthy functions. For example:
- * the `on` function is a wrapper around `addEventListener`.
- *
- * @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget}
- * @class EventTarget
- */
- var EventTarget = function EventTarget() {
- };
-
- /**
- * A Custom DOM event.
- *
- * @typedef {Object} EventTarget~Event
- * @see [Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
- */
-
- /**
- * All event listeners should follow the following format.
- *
- * @callback EventTarget~EventListener
- * @this {EventTarget}
- *
- * @param {EventTarget~Event} event
- * the event that triggered this function
- *
- * @param {Object} [hash]
- * hash of data sent during the event
- */
-
- /**
- * An object containing event names as keys and booleans as values.
- *
- * > NOTE: If an event name is set to a true value here {@link EventTarget#trigger}
- * will have extra functionality. See that function for more information.
- *
- * @property EventTarget.prototype.allowedEvents_
- * @private
- */
- EventTarget.prototype.allowedEvents_ = {};
-
- /**
- * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a
- * function that will get called when an event with a certain name gets triggered.
- *
- * @param {string|string[]} type
- * An event name or an array of event names.
- *
- * @param {EventTarget~EventListener} fn
- * The function to call with `EventTarget`s
- */
- 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 () {
- };
- on(this, type, fn);
- this.addEventListener = ael;
- };
-
- /**
- * An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic
- * the standard DOM API.
- *
- * @function
- * @see {@link EventTarget#on}
- */
- EventTarget.prototype.addEventListener = EventTarget.prototype.on;
-
- /**
- * Removes an `event listener` for a specific event from an instance of `EventTarget`.
- * This makes it so that the `event listener` will no longer get called when the
- * named event happens.
- *
- * @param {string|string[]} type
- * An event name or an array of event names.
- *
- * @param {EventTarget~EventListener} fn
- * The function to remove.
- */
- EventTarget.prototype.off = function (type, fn) {
- off(this, type, fn);
- };
-
- /**
- * An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic
- * the standard DOM API.
- *
- * @function
- * @see {@link EventTarget#off}
- */
- EventTarget.prototype.removeEventListener = EventTarget.prototype.off;
-
- /**
- * This function will add an `event listener` that gets triggered only once. After the
- * first trigger it will get removed. This is like adding an `event listener`
- * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself.
- *
- * @param {string|string[]} type
- * An event name or an array of event names.
- *
- * @param {EventTarget~EventListener} fn
- * The function to be called once for each event name.
- */
- EventTarget.prototype.one = function (type, fn) {
- // Remove the addEventListener alialing Events.on
- // so we don't get into an infinite type loop
- var ael = this.addEventListener;
-
- this.addEventListener = function () {
- };
- one(this, type, fn);
- this.addEventListener = ael;
- };
-
- /**
- * This function causes an event to happen. This will then cause any `event listeners`
- * that are waiting for that event, to get called. If there are no `event listeners`
- * for an event then nothing will happen.
- *
- * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`.
- * Trigger will also call the `on` + `uppercaseEventName` function.
- *
- * Example:
- * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call
- * `onClick` if it exists.
- *
- * @param {string|EventTarget~Event|Object} event
- * The name of the event, an `Event`, or an object with a key of type set to
- * an event name.
- */
- EventTarget.prototype.trigger = function (event) {
- var type = event.type || event;
-
- if (typeof event === 'string') {
- event = {type: type};
- }
- event = fixEvent(event);
-
- if (this.allowedEvents_[type] && this['on' + type]) {
- this['on' + type](event);
- }
-
- trigger(this, event);
- };
-
- /**
- * An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic
- * the standard DOM API.
- *
- * @function
- * @see {@link EventTarget#trigger}
- */
- EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;
-
- /**
- * @file mixins/evented.js
- * @module evented
- */
- /**
- * Returns whether or not an object has had the evented mixin applied.
- *
- * @param {Object} object
- * An object to test.
- *
- * @return {boolean}
- * Whether or not the object appears to be evented.
- */
- var isEvented = function isEvented(object) {
- return object instanceof EventTarget || !!object.eventBusEl_ && ['on', 'one', 'off', 'trigger'].every(function (k) {
- return typeof object[k] === 'function';
- });
- };
-
- /**
- * Whether a value is a valid event type - non-empty string or array.
- *
- * @private
- * @param {string|Array} type
- * The type value to test.
- *
- * @return {boolean}
- * Whether or not the type is a valid event type.
- */
- var isValidEventType = function isValidEventType(type) {
- return (
- // The regex here verifies that the `type` contains at least one non-
- // whitespace character.
- typeof type === 'string' && /\S/.test(type) || Array.isArray(type) && !!type.length
- );
- };
-
- /**
- * Validates a value to determine if it is a valid event target. Throws if not.
- *
- * @private
- * @throws {Error}
- * If the target does not appear to be a valid event target.
- *
- * @param {Object} target
- * The object to test.
- */
- var validateTarget = function validateTarget(target) {
- if (!target.nodeName && !isEvented(target)) {
- throw new Error('Invalid target; must be a DOM node or evented object.');
- }
- };
-
- /**
- * Validates a value to determine if it is a valid event target. Throws if not.
- *
- * @private
- * @throws {Error}
- * If the type does not appear to be a valid event type.
- *
- * @param {string|Array} type
- * The type to test.
- */
- var validateEventType = function validateEventType(type) {
- if (!isValidEventType(type)) {
- throw new Error('Invalid event type; must be a non-empty string or array.');
- }
- };
-
- /**
- * Validates a value to determine if it is a valid listener. Throws if not.
- *
- * @private
- * @throws {Error}
- * If the listener is not a function.
- *
- * @param {Function} listener
- * The listener to test.
- */
- var validateListener = function validateListener(listener) {
- if (typeof listener !== 'function') {
- throw new Error('Invalid listener; must be a function.');
- }
- };
-
- /**
- * Takes an array of arguments given to `on()` or `one()`, validates them, and
- * normalizes them into an object.
- *
- * @private
- * @param {Object} self
- * The evented object on which `on()` or `one()` was called. This
- * object will be bound as the `this` value for the listener.
- *
- * @param {Array} args
- * An array of arguments passed to `on()` or `one()`.
- *
- * @return {Object}
- * An object containing useful values for `on()` or `one()` calls.
- */
- var normalizeListenArgs = function normalizeListenArgs(self, args) {
-
- // If the number of arguments is less than 3, the target is always the
- // evented object itself.
- var isTargetingSelf = args.length < 3 || args[0] === self || args[0] === self.eventBusEl_;
- var target = void 0;
- var type = void 0;
- var listener = void 0;
-
- if (isTargetingSelf) {
- target = self.eventBusEl_;
-
- // Deal with cases where we got 3 arguments, but we are still listening to
- // the evented object itself.
- if (args.length >= 3) {
- args.shift();
- }
-
- type = args[0];
- listener = args[1];
- } else {
- target = args[0];
- type = args[1];
- listener = args[2];
- }
-
- validateTarget(target);
- validateEventType(type);
- validateListener(listener);
-
- listener = bind(self, listener);
-
- return {isTargetingSelf: isTargetingSelf, target: target, type: type, listener: listener};
- };
-
- /**
- * Adds the listener to the event type(s) on the target, normalizing for
- * the type of target.
- *
- * @private
- * @param {Element|Object} target
- * A DOM node or evented object.
- *
- * @param {string} method
- * The event binding method to use ("on" or "one").
- *
- * @param {string|Array} type
- * One or more event type(s).
- *
- * @param {Function} listener
- * A listener function.
- */
- var listen = function listen(target, method, type, listener) {
- validateTarget(target);
-
- if (target.nodeName) {
- Events[method](target, type, listener);
- } else {
- target[method](type, listener);
- }
- };
-
- /**
- * Contains methods that provide event capabilites to an object which is passed
- * to {@link module:evented|evented}.
- *
- * @mixin EventedMixin
- */
- var EventedMixin = {
-
- /**
- * Add a listener to an event (or events) on this object or another evented
- * object.
- *
- * @param {string|Array|Element|Object} targetOrType
- * If this is a string or array, it represents the event type(s)
- * that will trigger the listener.
- *
- * Another evented object can be passed here instead, which will
- * cause the listener to listen for events on _that_ object.
- *
- * In either case, the listener's `this` value will be bound to
- * this object.
- *
- * @param {string|Array|Function} typeOrListener
- * If the first argument was a string or array, this should be the
- * listener function. Otherwise, this is a string or array of event
- * type(s).
- *
- * @param {Function} [listener]
- * If the first argument was another evented object, this will be
- * the listener function.
- */
- on: function on$$1() {
- var _this = this;
-
- for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
- args[_key] = arguments[_key];
- }
-
- var _normalizeListenArgs = normalizeListenArgs(this, args),
- isTargetingSelf = _normalizeListenArgs.isTargetingSelf,
- target = _normalizeListenArgs.target,
- type = _normalizeListenArgs.type,
- listener = _normalizeListenArgs.listener;
-
- listen(target, 'on', type, listener);
-
- // If this object is listening to another evented object.
- if (!isTargetingSelf) {
-
- // If this object is disposed, remove the listener.
- var removeListenerOnDispose = function removeListenerOnDispose() {
- return _this.off(target, type, listener);
- };
-
- // Use the same function ID as the listener so we can remove it later it
- // using the ID of the original listener.
- removeListenerOnDispose.guid = listener.guid;
-
- // Add a listener to the target's dispose event as well. This ensures
- // that if the target is disposed BEFORE this object, we remove the
- // removal listener that was just added. Otherwise, we create a memory leak.
- var removeRemoverOnTargetDispose = function removeRemoverOnTargetDispose() {
- return _this.off('dispose', removeListenerOnDispose);
- };
-
- // Use the same function ID as the listener so we can remove it later
- // it using the ID of the original listener.
- removeRemoverOnTargetDispose.guid = listener.guid;
-
- listen(this, 'on', 'dispose', removeListenerOnDispose);
- listen(target, 'on', 'dispose', removeRemoverOnTargetDispose);
- }
- },
-
-
- /**
- * Add a listener to an event (or events) on this object or another evented
- * object. The listener will only be called once and then removed.
- *
- * @param {string|Array|Element|Object} targetOrType
- * If this is a string or array, it represents the event type(s)
- * that will trigger the listener.
- *
- * Another evented object can be passed here instead, which will
- * cause the listener to listen for events on _that_ object.
- *
- * In either case, the listener's `this` value will be bound to
- * this object.
- *
- * @param {string|Array|Function} typeOrListener
- * If the first argument was a string or array, this should be the
- * listener function. Otherwise, this is a string or array of event
- * type(s).
- *
- * @param {Function} [listener]
- * If the first argument was another evented object, this will be
- * the listener function.
- */
- one: function one$$1() {
- var _this2 = this;
-
- for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
- args[_key2] = arguments[_key2];
- }
-
- var _normalizeListenArgs2 = normalizeListenArgs(this, args),
- isTargetingSelf = _normalizeListenArgs2.isTargetingSelf,
- target = _normalizeListenArgs2.target,
- type = _normalizeListenArgs2.type,
- listener = _normalizeListenArgs2.listener;
-
- // Targeting this evented object.
-
-
- if (isTargetingSelf) {
- listen(target, 'one', type, listener);
-
- // Targeting another evented object.
- } else {
- var wrapper = function wrapper() {
- for (var _len3 = arguments.length, largs = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
- largs[_key3] = arguments[_key3];
- }
-
- _this2.off(target, type, wrapper);
- listener.apply(null, largs);
- };
-
- // Use the same function ID as the listener so we can remove it later
- // it using the ID of the original listener.
- wrapper.guid = listener.guid;
- listen(target, 'one', type, wrapper);
- }
- },
-
-
- /**
- * Removes listener(s) from event(s) on an evented object.
- *
- * @param {string|Array|Element|Object} [targetOrType]
- * If this is a string or array, it represents the event type(s).
- *
- * Another evented object can be passed here instead, in which case
- * ALL 3 arguments are _required_.
- *
- * @param {string|Array|Function} [typeOrListener]
- * If the first argument was a string or array, this may be the
- * listener function. Otherwise, this is a string or array of event
- * type(s).
- *
- * @param {Function} [listener]
- * If the first argument was another evented object, this will be
- * the listener function; otherwise, _all_ listeners bound to the
- * event type(s) will be removed.
- */
- off: function off$$1(targetOrType, typeOrListener, listener) {
-
- // Targeting this evented object.
- if (!targetOrType || isValidEventType(targetOrType)) {
- off(this.eventBusEl_, targetOrType, typeOrListener);
-
- // Targeting another evented object.
- } else {
- var target = targetOrType;
- var type = typeOrListener;
-
- // Fail fast and in a meaningful way!
- validateTarget(target);
- validateEventType(type);
- validateListener(listener);
-
- // Ensure there's at least a guid, even if the function hasn't been used
- listener = bind(this, listener);
-
- // Remove the dispose listener on this evented object, which was given
- // the same guid as the event listener in on().
- this.off('dispose', listener);
-
- if (target.nodeName) {
- off(target, type, listener);
- off(target, 'dispose', listener);
- } else if (isEvented(target)) {
- target.off(type, listener);
- target.off('dispose', listener);
- }
- }
- },
-
-
- /**
- * Fire an event on this evented object, causing its listeners to be called.
- *
- * @param {string|Object} event
- * An event type or an object with a type property.
- *
- * @param {Object} [hash]
- * An additional object to pass along to listeners.
- *
- * @returns {boolean}
- * Whether or not the default behavior was prevented.
- */
- trigger: function trigger$$1(event, hash) {
- return trigger(this.eventBusEl_, event, hash);
- }
- };
-
- /**
- * Applies {@link module:evented~EventedMixin|EventedMixin} to a target object.
- *
- * @param {Object} target
- * The object to which to add event methods.
- *
- * @param {Object} [options={}]
- * Options for customizing the mixin behavior.
- *
- * @param {String} [options.eventBusKey]
- * By default, adds a `eventBusEl_` DOM element to the target object,
- * which is used as an event bus. If the target object already has a
- * DOM element that should be used, pass its key here.
- *
- * @return {Object}
- * The target object.
- */
- function evented(target) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- var eventBusKey = options.eventBusKey;
-
- // Set or create the eventBusEl_.
-
- if (eventBusKey) {
- if (!target[eventBusKey].nodeName) {
- throw new Error('The eventBusKey "' + eventBusKey + '" does not refer to an element.');
- }
- target.eventBusEl_ = target[eventBusKey];
- } else {
- target.eventBusEl_ = createEl('span', {className: 'vjs-event-bus'});
- }
-
- assign(target, EventedMixin);
-
- // When any evented object is disposed, it removes all its listeners.
- target.on('dispose', function () {
- return target.off();
- });
-
- return target;
- }
-
- /**
- * @file mixins/stateful.js
- * @module stateful
- */
- /**
- * Contains methods that provide statefulness to an object which is passed
- * to {@link module:stateful}.
- *
- * @mixin StatefulMixin
- */
- var StatefulMixin = {
-
- /**
- * A hash containing arbitrary keys and values representing the state of
- * the object.
- *
- * @type {Object}
- */
- state: {},
-
- /**
- * Set the state of an object by mutating its
- * {@link module:stateful~StatefulMixin.state|state} object in place.
- *
- * @fires module:stateful~StatefulMixin#statechanged
- * @param {Object|Function} stateUpdates
- * A new set of properties to shallow-merge into the plugin state.
- * Can be a plain object or a function returning a plain object.
- *
- * @returns {Object|undefined}
- * An object containing changes that occurred. If no changes
- * occurred, returns `undefined`.
- */
- setState: function setState(stateUpdates) {
- var _this = this;
-
- // Support providing the `stateUpdates` state as a function.
- if (typeof stateUpdates === 'function') {
- stateUpdates = stateUpdates();
- }
-
- var changes = void 0;
-
- each(stateUpdates, function (value, key) {
-
- // Record the change if the value is different from what's in the
- // current state.
- if (_this.state[key] !== value) {
- changes = changes || {};
- changes[key] = {
- from: _this.state[key],
- to: value
- };
- }
-
- _this.state[key] = value;
- });
-
- // Only trigger "statechange" if there were changes AND we have a trigger
- // function. This allows us to not require that the target object be an
- // evented object.
- if (changes && isEvented(this)) {
-
- /**
- * An event triggered on an object that is both
- * {@link module:stateful|stateful} and {@link module:evented|evented}
- * indicating that its state has changed.
- *
- * @event module:stateful~StatefulMixin#statechanged
- * @type {Object}
- * @property {Object} changes
- * A hash containing the properties that were changed and
- * the values they were changed `from` and `to`.
- */
- this.trigger({
- changes: changes,
- type: 'statechanged'
- });
- }
-
- return changes;
- }
- };
-
- /**
- * Applies {@link module:stateful~StatefulMixin|StatefulMixin} to a target
- * object.
- *
- * If the target object is {@link module:evented|evented} and has a
- * `handleStateChanged` method, that method will be automatically bound to the
- * `statechanged` event on itself.
- *
- * @param {Object} target
- * The object to be made stateful.
- *
- * @param {Object} [defaultState]
- * A default set of properties to populate the newly-stateful object's
- * `state` property.
- *
- * @returns {Object}
- * Returns the `target`.
- */
- function stateful(target, defaultState) {
- assign(target, StatefulMixin);
-
- // This happens after the mixing-in because we need to replace the `state`
- // added in that step.
- target.state = assign({}, target.state, defaultState);
-
- // Auto-bind the `handleStateChanged` method of the target object if it exists.
- if (typeof target.handleStateChanged === 'function' && isEvented(target)) {
- target.on('statechanged', target.handleStateChanged);
- }
-
- return target;
- }
-
- /**
- * @file to-title-case.js
- * @module to-title-case
- */
-
- /**
- * Uppercase the first letter of a string.
- *
- * @param {string} string
- * String to be uppercased
- *
- * @return {string}
- * The string with an uppercased first letter
- */
- function toTitleCase(string) {
- if (typeof string !== 'string') {
- return string;
- }
-
- return string.charAt(0).toUpperCase() + string.slice(1);
- }
-
- /**
- * Compares the TitleCase versions of the two strings for equality.
- *
- * @param {string} str1
- * The first string to compare
- *
- * @param {string} str2
- * The second string to compare
- *
- * @return {boolean}
- * Whether the TitleCase versions of the strings are equal
- */
- function titleCaseEquals(str1, str2) {
- return toTitleCase(str1) === toTitleCase(str2);
- }
-
- /**
- * @file merge-options.js
- * @module merge-options
- */
- /**
- * Deep-merge one or more options objects, recursively merging **only** plain
- * object properties.
- *
- * @param {Object[]} sources
- * One or more objects to merge into a new object.
- *
- * @returns {Object}
- * A new object that is the merged result of all sources.
- */
- function mergeOptions() {
- var result = {};
-
- for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {
- sources[_key] = arguments[_key];
- }
-
- sources.forEach(function (source) {
- if (!source) {
- return;
- }
-
- each(source, function (value, key) {
- if (!isPlain(value)) {
- result[key] = value;
- return;
- }
-
- if (!isPlain(result[key])) {
- result[key] = {};
- }
-
- result[key] = mergeOptions(result[key], value);
- });
- });
-
- return result;
- }
-
- /**
- * Player Component - Base class for all UI objects
- *
- * @file component.js
- */
- /**
- * Base class for all UI Components.
- * Components are UI objects which represent both a javascript object and an element
- * in the DOM. They can be children of other components, and can have
- * children themselves.
- *
- * Components can also use methods from {@link EventTarget}
- */
-
- var Component = function () {
-
- /**
- * A callback that is called when a component is ready. Does not have any
- * paramters and any callback value will be ignored.
- *
- * @callback Component~ReadyCallback
- * @this Component
- */
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- *
- * @param {Object[]} [options.children]
- * An array of children objects to intialize this component with. Children objects have
- * a name property that will be used if more than one component of the same type needs to be
- * added.
- *
- * @param {Component~ReadyCallback} [ready]
- * Function that gets called when the `Component` is ready.
- */
- 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_ = mergeOptions({}, this.options_);
-
- // Updated options with supplied options
- options = this.options_ = mergeOptions(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_' + 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();
- }
-
- // Make this an evented object and use `el_`, if available, as its event bus
- evented(this, {eventBusKey: this.el_ ? 'el_' : null});
- stateful(this, this.constructor.defaultState);
-
- 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.
- *
- * @fires Component#dispose
- */
-
-
- Component.prototype.dispose = function dispose() {
-
- /**
- * Triggered when a `Component` is disposed.
- *
- * @event Component#dispose
- * @type {EventTarget~Event}
- *
- * @property {boolean} [bubbles=false]
- * set to false so that the close event does not
- * bubble up
- */
- 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;
-
- if (this.el_) {
- // Remove element from DOM
- if (this.el_.parentNode) {
- this.el_.parentNode.removeChild(this.el_);
- }
-
- removeData(this.el_);
- this.el_ = null;
- }
- };
-
- /**
- * Return the {@link Player} that the `Component` has attached to.
- *
- * @return {Player}
- * The player that this `Component` has attached to.
- */
-
-
- Component.prototype.player = function player() {
- return this.player_;
- };
-
- /**
- * Deep merge of options objects with new options.
- * > Note: When both `obj` and `options` contain properties whose values are objects.
- * The two properties get merged using {@link module:mergeOptions}
- *
- * @param {Object} obj
- * The object that contains new options.
- *
- * @return {Object}
- * A new object of `this.options_` and `obj` merged together.
- *
- * @deprecated since version 5
- */
-
-
- Component.prototype.options = function options(obj) {
- log$1.warn('this.options() has been deprecated and will be moved to the constructor in 6.0');
-
- if (!obj) {
- return this.options_;
- }
-
- this.options_ = mergeOptions(this.options_, obj);
- return this.options_;
- };
-
- /**
- * Get the `Component`s DOM element
- *
- * @return {Element}
- * The DOM element for this `Component`.
- */
-
-
- Component.prototype.el = function el() {
- return this.el_;
- };
-
- /**
- * Create the `Component`s DOM element.
- *
- * @param {string} [tagName]
- * Element's DOM 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}
- * The element that gets created.
- */
-
-
- Component.prototype.createEl = function createEl$$1(tagName, properties, attributes) {
- return createEl(tagName, properties, attributes);
- };
-
- /**
- * Localize a string given the string in english.
- *
- * If tokens are provided, it'll try and run a simple token replacement on the provided string.
- * The tokens it loooks for look like `{1}` with the index being 1-indexed into the tokens array.
- *
- * If a `defaultValue` is provided, it'll use that over `string`,
- * if a value isn't found in provided language files.
- * This is useful if you want to have a descriptive key for token replacement
- * but have a succinct localized string and not require `en.json` to be included.
- *
- * Currently, it is used for the progress bar timing.
- * ```js
- * {
- * "progress bar timing: currentTime={1} duration={2}": "{1} of {2}"
- * }
- * ```
- * It is then used like so:
- * ```js
- * this.localize('progress bar timing: currentTime={1} duration{2}',
- * [this.player_.currentTime(), this.player_.duration()],
- * '{1} of {2}');
- * ```
- *
- * Which outputs something like: `01:23 of 24:56`.
- *
- *
- * @param {string} string
- * The string to localize and the key to lookup in the language files.
- * @param {string[]} [tokens]
- * If the current item has token replacements, provide the tokens here.
- * @param {string} [defaultValue]
- * Defaults to `string`. Can be a default value to use for token replacement
- * if the lookup key is needed to be separate.
- *
- * @return {string}
- * The localized string or if no localization exists the english string.
- */
-
-
- Component.prototype.localize = function localize(string, tokens) {
- var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : string;
-
- var code = this.player_.language && this.player_.language();
- var languages = this.player_.languages && this.player_.languages();
- var language = languages && languages[code];
- var primaryCode = code && code.split('-')[0];
- var primaryLang = languages && languages[primaryCode];
-
- var localizedString = defaultValue;
-
- if (language && language[string]) {
- localizedString = language[string];
- } else if (primaryLang && primaryLang[string]) {
- localizedString = primaryLang[string];
- }
-
- if (tokens) {
- localizedString = localizedString.replace(/\{(\d+)\}/g, function (match, index) {
- var value = tokens[index - 1];
- var ret = value;
-
- if (typeof value === 'undefined') {
- ret = match;
- }
-
- return ret;
- });
- }
-
- return localizedString;
- };
-
- /**
- * Return the `Component`s DOM element. This is where children get inserted.
- * This will usually be the the same as the element returned in {@link Component#el}.
- *
- * @return {Element}
- * The content element for this `Component`.
- */
-
-
- Component.prototype.contentEl = function contentEl() {
- return this.contentEl_ || this.el_;
- };
-
- /**
- * Get this `Component`s ID
- *
- * @return {string}
- * The id of this `Component`
- */
-
-
- Component.prototype.id = function id() {
- return this.id_;
- };
-
- /**
- * Get the `Component`s name. The name gets used to reference the `Component`
- * and is set during registration.
- *
- * @return {string}
- * The name of this `Component`.
- */
-
-
- Component.prototype.name = function name() {
- return this.name_;
- };
-
- /**
- * Get an array of all child components
- *
- * @return {Array}
- * The children
- */
-
-
- Component.prototype.children = function children() {
- return this.children_;
- };
-
- /**
- * Returns the child `Component` with the given `id`.
- *
- * @param {string} id
- * The id of the child `Component` to get.
- *
- * @return {Component|undefined}
- * The child `Component` with the given `id` or undefined.
- */
-
-
- Component.prototype.getChildById = function getChildById(id) {
- return this.childIndex_[id];
- };
-
- /**
- * Returns the child `Component` with the given `name`.
- *
- * @param {string} name
- * The name of the child `Component` to get.
- *
- * @return {Component|undefined}
- * The child `Component` with the given `name` or undefined.
- */
-
-
- Component.prototype.getChild = function getChild(name) {
- if (!name) {
- return;
- }
-
- name = toTitleCase(name);
-
- return this.childNameIndex_[name];
- };
-
- /**
- * Add a child `Component` inside the current `Component`.
- *
- *
- * @param {string|Component} child
- * The name or instance of a child to add.
- *
- * @param {Object} [options={}]
- * The key/value store of options that will get passed to children of
- * the child.
- *
- * @param {number} [index=this.children_.length]
- * The index to attempt to add a child into.
- *
- * @return {Component}
- * The `Component` that gets added as a child. When using a string the
- * `Component` will get created by this process.
- */
-
-
- Component.prototype.addChild = function addChild(child) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.children_.length;
-
- var component = void 0;
- var componentName = void 0;
-
- // If child is a string, create component with options
- if (typeof child === 'string') {
- componentName = toTitleCase(child);
-
- var componentClassName = options.componentClass || 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 && toTitleCase(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. Also removes
- * the child `Component`s element from this `Component`s element.
- *
- * @param {Component} component
- * The child `Component` to remove.
- */
-
-
- 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 `Component`s based upon options.
- */
-
-
- Component.prototype.initChildren = function initChildren() {
- var _this = this;
-
- var children = this.options_.children;
-
- if (children) {
- // `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 = void 0;
- 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;
- }
- return child === wchild.name;
- });
- })).map(function (child) {
- var name = void 0;
- var opts = void 0;
-
- 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 || toTitleCase(child.name));
-
- return c && !Tech.isTech(c);
- }).forEach(handleAdd);
- }
- };
-
- /**
- * Builds the default DOM class name. Should be overriden by sub-components.
- *
- * @return {string}
- * The DOM class name for this object.
- *
- * @abstract
- */
-
-
- Component.prototype.buildCSSClass = function buildCSSClass() {
- // Child classes can include a function that does:
- // return 'CLASS NAME' + this._super();
- return '';
- };
-
- /**
- * 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.
- *
- * @return {Component}
- * Returns itself; method can be chained.
- */
-
-
- Component.prototype.ready = function ready(fn) {
- var sync = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
-
- if (!fn) {
- return;
- }
-
- if (!this.isReady_) {
- this.readyQueue_ = this.readyQueue_ || [];
- this.readyQueue_.push(fn);
- return;
- }
-
- if (sync) {
- fn.call(this);
- } else {
- // Call the function asynchronously by default for consistency
- this.setTimeout(fn, 1);
- }
- };
-
- /**
- * Trigger all the ready listeners for this `Component`.
- *
- * @fires Component#ready
- */
-
-
- 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
- /**
- * Triggered when a `Component` is ready.
- *
- * @event Component#ready
- * @type {EventTarget~Event}
- */
- this.trigger('ready');
- }, 1);
- };
-
- /**
- * Find a single DOM element matching a `selector`. This can be within the `Component`s
- * `contentEl()` or another custom context.
- *
- * @param {string} selector
- * A valid CSS selector, which will be passed to `querySelector`.
- *
- * @param {Element|string} [context=this.contentEl()]
- * A DOM element within which to query. Can also be a selector string in
- * which case the first matching element will get used as context. If
- * missing `this.contentEl()` gets used. If `this.contentEl()` returns
- * nothing it falls back to `document`.
- *
- * @return {Element|null}
- * the dom element that was found, or null
- *
- * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
- */
-
-
- Component.prototype.$ = function $$$1(selector, context) {
- return $(selector, context || this.contentEl());
- };
-
- /**
- * Finds all DOM element matching a `selector`. This can be within the `Component`s
- * `contentEl()` or another custom context.
- *
- * @param {string} selector
- * A valid CSS selector, which will be passed to `querySelectorAll`.
- *
- * @param {Element|string} [context=this.contentEl()]
- * A DOM element within which to query. Can also be a selector string in
- * which case the first matching element will get used as context. If
- * missing `this.contentEl()` gets used. If `this.contentEl()` returns
- * nothing it falls back to `document`.
- *
- * @return {NodeList}
- * a list of dom elements that were found
- *
- * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
- */
-
-
- Component.prototype.$$ = function $$$$1(selector, context) {
- return $$(selector, context || this.contentEl());
- };
-
- /**
- * Check if a component's element has a CSS class name.
- *
- * @param {string} classToCheck
- * CSS class name to check.
- *
- * @return {boolean}
- * - True if the `Component` has the class.
- * - False if the `Component` does not have the class`
- */
-
-
- Component.prototype.hasClass = function hasClass$$1(classToCheck) {
- return hasClass(this.el_, classToCheck);
- };
-
- /**
- * Add a CSS class name to the `Component`s element.
- *
- * @param {string} classToAdd
- * CSS class name to add
- */
-
-
- Component.prototype.addClass = function addClass$$1(classToAdd) {
- addClass(this.el_, classToAdd);
- };
-
- /**
- * Remove a CSS class name from the `Component`s element.
- *
- * @param {string} classToRemove
- * CSS class name to remove
- */
-
-
- Component.prototype.removeClass = function removeClass$$1(classToRemove) {
- removeClass(this.el_, classToRemove);
- };
-
- /**
- * Add or remove a CSS class name from the component's element.
- * - `classToToggle` gets added when {@link Component#hasClass} would return false.
- * - `classToToggle` gets removed when {@link Component#hasClass} would return true.
- *
- * @param {string} classToToggle
- * The class to add or remove based on (@link Component#hasClass}
- *
- * @param {boolean|Dom~predicate} [predicate]
- * An {@link Dom~predicate} function or a boolean
- */
-
-
- Component.prototype.toggleClass = function toggleClass$$1(classToToggle, predicate) {
- toggleClass(this.el_, classToToggle, predicate);
- };
-
- /**
- * Show the `Component`s element if it is hidden by removing the
- * 'vjs-hidden' class name from it.
- */
-
-
- Component.prototype.show = function show() {
- this.removeClass('vjs-hidden');
- };
-
- /**
- * Hide the `Component`s element if it is currently showing by adding the
- * 'vjs-hidden` class name to it.
- */
-
-
- Component.prototype.hide = function hide() {
- this.addClass('vjs-hidden');
- };
-
- /**
- * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing'
- * class name to it. Used during fadeIn/fadeOut.
- *
- * @private
- */
-
-
- Component.prototype.lockShowing = function lockShowing() {
- this.addClass('vjs-lock-showing');
- };
-
- /**
- * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing'
- * class name from it. Used during fadeIn/fadeOut.
- *
- * @private
- */
-
-
- Component.prototype.unlockShowing = function unlockShowing() {
- this.removeClass('vjs-lock-showing');
- };
-
- /**
- * Get the value of an attribute on the `Component`s element.
- *
- * @param {string} attribute
- * Name of the attribute to get the value from.
- *
- * @return {string|null}
- * - The value of the attribute that was asked for.
- * - Can be an empty string on some browsers if the attribute does not exist
- * or has no value
- * - Most browsers will return null if the attibute does not exist or has
- * no value.
- *
- * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute}
- */
-
-
- Component.prototype.getAttribute = function getAttribute$$1(attribute) {
- return getAttribute(this.el_, attribute);
- };
-
- /**
- * Set the value of an attribute on the `Component`'s element
- *
- * @param {string} attribute
- * Name of the attribute to set.
- *
- * @param {string} value
- * Value to set the attribute to.
- *
- * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute}
- */
-
-
- Component.prototype.setAttribute = function setAttribute$$1(attribute, value) {
- setAttribute(this.el_, attribute, value);
- };
-
- /**
- * Remove an attribute from the `Component`s element.
- *
- * @param {string} attribute
- * Name of the attribute to remove.
- *
- * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute}
- */
-
-
- Component.prototype.removeAttribute = function removeAttribute$$1(attribute) {
- removeAttribute(this.el_, attribute);
- };
-
- /**
- * Get or set the width of the component based upon the CSS styles.
- * See {@link Component#dimension} for more detailed information.
- *
- * @param {number|string} [num]
- * The width that you want to set postfixed with '%', 'px' or nothing.
- *
- * @param {boolean} [skipListeners]
- * Skip the componentresize event trigger
- *
- * @return {number|string}
- * The width when getting, zero if there is no width. Can be a string
- * postpixed with '%' or 'px'.
- */
-
-
- Component.prototype.width = function width(num, skipListeners) {
- return this.dimension('width', num, skipListeners);
- };
-
- /**
- * Get or set the height of the component based upon the CSS styles.
- * See {@link Component#dimension} for more detailed information.
- *
- * @param {number|string} [num]
- * The height that you want to set postfixed with '%', 'px' or nothing.
- *
- * @param {boolean} [skipListeners]
- * Skip the componentresize event trigger
- *
- * @return {number|string}
- * The width when getting, zero if there is no width. Can be a string
- * postpixed with '%' or 'px'.
- */
-
-
- Component.prototype.height = function height(num, skipListeners) {
- return this.dimension('height', num, skipListeners);
- };
-
- /**
- * Set both the width and height of the `Component` element at the same time.
- *
- * @param {number|string} width
- * Width to set the `Component`s element to.
- *
- * @param {number|string} height
- * Height to set the `Component`s element to.
- */
-
-
- Component.prototype.dimensions = function dimensions(width, height) {
- // Skip componentresize listeners on width for optimization
- this.width(width, true);
- this.height(height);
- };
-
- /**
- * Get or set width or height of the `Component` element. This is the shared code
- * for the {@link Component#width} and {@link Component#height}.
- *
- * Things to know:
- * - If the width or height in an number this will return the number postfixed with 'px'.
- * - If the width/height is a percent this will return the percent postfixed with '%'
- * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function
- * defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`.
- * See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/}
- * for more information
- * - If you want the computed style of the component, use {@link Component#currentWidth}
- * and {@link {Component#currentHeight}
- *
- * @fires Component#componentresize
- *
- * @param {string} widthOrHeight
- 8 'width' or 'height'
- *
- * @param {number|string} [num]
- 8 New dimension
- *
- * @param {boolean} [skipListeners]
- * Skip componentresize event trigger
- *
- * @return {number}
- * The dimension when getting or 0 if unset
- */
-
-
- 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) {
- /**
- * Triggered when a component is resized.
- *
- * @event Component#componentresize
- * @type {EventTarget~Event}
- */
- this.trigger('componentresize');
- }
-
- return;
- }
-
- // 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' + toTitleCase(widthOrHeight)], 10);
- };
-
- /**
- * Get the width or the height of the `Component` elements computed style. Uses
- * `window.getComputedStyle`.
- *
- * @param {string} widthOrHeight
- * A string containing 'width' or 'height'. Whichever one you want to get.
- *
- * @return {number}
- * The dimension that gets asked for or 0 if nothing was set
- * for that dimension.
- */
-
-
- Component.prototype.currentDimension = function currentDimension(widthOrHeight) {
- var computedWidthOrHeight = 0;
-
- if (widthOrHeight !== 'width' && widthOrHeight !== 'height') {
- throw new Error('currentDimension only accepts width or height value');
- }
-
- if (typeof window_1.getComputedStyle === 'function') {
- var computedStyle = window_1.getComputedStyle(this.el_);
-
- computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight];
- }
-
- // remove 'px' from variable and parse as integer
- computedWidthOrHeight = parseFloat(computedWidthOrHeight);
-
- // if the computed value is still 0, it's possible that the browser is lying
- // and we want to check the offset values.
- // This code also runs on IE8 and wherever getComputedStyle doesn't exist.
- if (computedWidthOrHeight === 0) {
- var rule = 'offset' + toTitleCase(widthOrHeight);
-
- computedWidthOrHeight = this.el_[rule];
- }
-
- return computedWidthOrHeight;
- };
-
- /**
- * An object that contains width and height values of the `Component`s
- * computed style. Uses `window.getComputedStyle`.
- *
- * @typedef {Object} Component~DimensionObject
- *
- * @property {number} width
- * The width of the `Component`s computed style.
- *
- * @property {number} height
- * The height of the `Component`s computed style.
- */
-
- /**
- * Get an object that contains width and height values of the `Component`s
- * computed style.
- *
- * @return {Component~DimensionObject}
- * The dimensions of the components element
- */
-
-
- Component.prototype.currentDimensions = function currentDimensions() {
- return {
- width: this.currentDimension('width'),
- height: this.currentDimension('height')
- };
- };
-
- /**
- * Get the width of the `Component`s computed style. Uses `window.getComputedStyle`.
- *
- * @return {number} width
- * The width of the `Component`s computed style.
- */
-
-
- Component.prototype.currentWidth = function currentWidth() {
- return this.currentDimension('width');
- };
-
- /**
- * Get the height of the `Component`s computed style. Uses `window.getComputedStyle`.
- *
- * @return {number} height
- * The height of the `Component`s computed style.
- */
-
-
- Component.prototype.currentHeight = function currentHeight() {
- return this.currentDimension('height');
- };
-
- /**
- * Set the focus to this component
- */
-
-
- Component.prototype.focus = function focus() {
- this.el_.focus();
- };
-
- /**
- * Remove the focus from this component
- */
-
-
- Component.prototype.blur = function blur() {
- this.el_.blur();
- };
-
- /**
- * Emit a 'tap' events when touch event support gets detected. This gets used to
- * support toggling the controls through a tap on the video. They get enabled
- * because every sub-component would have extra overhead otherwise.
- *
- * @private
- * @fires Component#tap
- * @listens Component#touchstart
- * @listens Component#touchmove
- * @listens Component#touchleave
- * @listens Component#touchcancel
- * @listens Component#touchend
- */
-
-
- 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 = void 0;
-
- this.on('touchstart', function (event) {
- // If more than one finger, don't consider treating this as a click
- if (event.touches.length === 1) {
- // Copy pageX/pageY from the object
- firstTouch = {
- pageX: event.touches[0].pageX,
- pageY: event.touches[0].pageY
- };
- // 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();
- /**
- * Triggered when a `Component` is tapped.
- *
- * @event Component#tap
- * @type {EventTarget~Event}
- */
- 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)
- }
- }
- });
- };
-
- /**
- * This function reports user activity whenever touch events happen. This can get
- * turned off by any sub-components that wants touch events to act another way.
- *
- * Report user touch activity when touch events occur. User activity gets used to
- * determine when controls should show/hide. It is 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 as `touchstart` and `touchend` toggle player
- * controls. So touch events can't help us at the player level either.
- *
- * User activity gets 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.
- * Furthermore a `touchmove` event and anything other than a tap, should not turn
- * controls back on.
- *
- * @listens Component#touchstart
- * @listens Component#touchmove
- * @listens Component#touchend
- * @listens Component#touchcancel
- */
-
-
- 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 = bind(this.player(), this.player().reportUserActivity);
-
- var touchHolding = void 0;
-
- 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);
- };
-
- /**
- * A callback that has no parameters and is bound into `Component`s context.
- *
- * @callback Component~GenericCallback
- * @this Component
- */
-
- /**
- * Creates a function that runs after an `x` millisecond timeout. This function is a
- * wrapper around `window.setTimeout`. There are a few reasons to use this one
- * instead though:
- * 1. It gets cleared via {@link Component#clearTimeout} when
- * {@link Component#dispose} gets called.
- * 2. The function callback will gets turned into a {@link Component~GenericCallback}
- *
- * > Note: You can use `window.clearTimeout` on the id returned by this function. This
- * will cause its dispose listener not to get cleaned up! Please use
- * {@link Component#clearTimeout} or {@link Component#dispose}.
- *
- * @param {Component~GenericCallback} fn
- * The function that will be run after `timeout`.
- *
- * @param {number} timeout
- * Timeout in milliseconds to delay before executing the specified function.
- *
- * @return {number}
- * Returns a timeout ID that gets used to identify the timeout. It can also
- * get used in {@link Component#clearTimeout} to clear the timeout that
- * was set.
- *
- * @listens Component#dispose
- * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout}
- */
-
-
- Component.prototype.setTimeout = function setTimeout(fn, timeout) {
- var _this2 = this;
-
- fn = bind(this, fn);
-
- var timeoutId = window_1.setTimeout(fn, timeout);
- var disposeFn = function disposeFn() {
- return _this2.clearTimeout(timeoutId);
- };
-
- disposeFn.guid = 'vjs-timeout-' + timeoutId;
-
- this.on('dispose', disposeFn);
-
- return timeoutId;
- };
-
- /**
- * Clears a timeout that gets created via `window.setTimeout` or
- * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout}
- * use this function instead of `window.clearTimout`. If you don't your dispose
- * listener will not get cleaned up until {@link Component#dispose}!
- *
- * @param {number} timeoutId
- * The id of the timeout to clear. The return value of
- * {@link Component#setTimeout} or `window.setTimeout`.
- *
- * @return {number}
- * Returns the timeout id that was cleared.
- *
- * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout}
- */
-
-
- Component.prototype.clearTimeout = function clearTimeout(timeoutId) {
- window_1.clearTimeout(timeoutId);
-
- var disposeFn = function disposeFn() {
- };
-
- disposeFn.guid = 'vjs-timeout-' + timeoutId;
-
- this.off('dispose', disposeFn);
-
- return timeoutId;
- };
-
- /**
- * Creates a function that gets run every `x` milliseconds. This function is a wrapper
- * around `window.setInterval`. There are a few reasons to use this one instead though.
- * 1. It gets cleared via {@link Component#clearInterval} when
- * {@link Component#dispose} gets called.
- * 2. The function callback will be a {@link Component~GenericCallback}
- *
- * @param {Component~GenericCallback} fn
- * The function to run every `x` seconds.
- *
- * @param {number} interval
- * Execute the specified function every `x` milliseconds.
- *
- * @return {number}
- * Returns an id that can be used to identify the interval. It can also be be used in
- * {@link Component#clearInterval} to clear the interval.
- *
- * @listens Component#dispose
- * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval}
- */
-
-
- Component.prototype.setInterval = function setInterval(fn, interval) {
- var _this3 = this;
-
- fn = bind(this, fn);
-
- var intervalId = window_1.setInterval(fn, interval);
-
- var disposeFn = function disposeFn() {
- return _this3.clearInterval(intervalId);
- };
-
- disposeFn.guid = 'vjs-interval-' + intervalId;
-
- this.on('dispose', disposeFn);
-
- return intervalId;
- };
-
- /**
- * Clears an interval that gets created via `window.setInterval` or
- * {@link Component#setInterval}. If you set an inteval via {@link Component#setInterval}
- * use this function instead of `window.clearInterval`. If you don't your dispose
- * listener will not get cleaned up until {@link Component#dispose}!
- *
- * @param {number} intervalId
- * The id of the interval to clear. The return value of
- * {@link Component#setInterval} or `window.setInterval`.
- *
- * @return {number}
- * Returns the interval id that was cleared.
- *
- * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval}
- */
-
-
- Component.prototype.clearInterval = function clearInterval(intervalId) {
- window_1.clearInterval(intervalId);
-
- var disposeFn = function disposeFn() {
- };
-
- disposeFn.guid = 'vjs-interval-' + intervalId;
-
- this.off('dispose', disposeFn);
-
- return intervalId;
- };
-
- /**
- * Queues up a callback to be passed to requestAnimationFrame (rAF), but
- * with a few extra bonuses:
- *
- * - Supports browsers that do not support rAF by falling back to
- * {@link Component#setTimeout}.
- *
- * - The callback is turned into a {@link Component~GenericCallback} (i.e.
- * bound to the component).
- *
- * - Automatic cancellation of the rAF callback is handled if the component
- * is disposed before it is called.
- *
- * @param {Component~GenericCallback} fn
- * A function that will be bound to this component and executed just
- * before the browser's next repaint.
- *
- * @return {number}
- * Returns an rAF ID that gets used to identify the timeout. It can
- * also be used in {@link Component#cancelAnimationFrame} to cancel
- * the animation frame callback.
- *
- * @listens Component#dispose
- * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame}
- */
-
-
- Component.prototype.requestAnimationFrame = function requestAnimationFrame(fn) {
- var _this4 = this;
-
- if (this.supportsRaf_) {
- fn = bind(this, fn);
-
- var id = window_1.requestAnimationFrame(fn);
- var disposeFn = function disposeFn() {
- return _this4.cancelAnimationFrame(id);
- };
-
- disposeFn.guid = 'vjs-raf-' + id;
- this.on('dispose', disposeFn);
-
- return id;
- }
-
- // Fall back to using a timer.
- return this.setTimeout(fn, 1000 / 60);
- };
-
- /**
- * Cancels a queued callback passed to {@link Component#requestAnimationFrame}
- * (rAF).
- *
- * If you queue an rAF callback via {@link Component#requestAnimationFrame},
- * use this function instead of `window.cancelAnimationFrame`. If you don't,
- * your dispose listener will not get cleaned up until {@link Component#dispose}!
- *
- * @param {number} id
- * The rAF ID to clear. The return value of {@link Component#requestAnimationFrame}.
- *
- * @return {number}
- * Returns the rAF ID that was cleared.
- *
- * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/window/cancelAnimationFrame}
- */
-
-
- Component.prototype.cancelAnimationFrame = function cancelAnimationFrame(id) {
- if (this.supportsRaf_) {
- window_1.cancelAnimationFrame(id);
-
- var disposeFn = function disposeFn() {
- };
-
- disposeFn.guid = 'vjs-raf-' + id;
-
- this.off('dispose', disposeFn);
-
- return id;
- }
-
- // Fall back to using a timer.
- return this.clearTimeout(id);
- };
-
- /**
- * Register a `Component` with `videojs` given the name and the component.
- *
- * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s
- * should be registered using {@link Tech.registerTech} or
- * {@link videojs:videojs.registerTech}.
- *
- * > NOTE: This function can also be seen on videojs as
- * {@link videojs:videojs.registerComponent}.
- *
- * @param {string} name
- * The name of the `Component` to register.
- *
- * @param {Component} ComponentToRegister
- * The `Component` class to register.
- *
- * @return {Component}
- * The `Component` that was registered.
- */
-
-
- Component.registerComponent = function registerComponent(name, ComponentToRegister) {
- if (typeof name !== 'string' || !name) {
- throw new Error('Illegal component name, "' + name + '"; must be a non-empty string.');
- }
-
- var Tech = Component.getComponent('Tech');
-
- // We need to make sure this check is only done if Tech has been registered.
- var isTech = Tech && Tech.isTech(ComponentToRegister);
- var isComp = Component === ComponentToRegister || Component.prototype.isPrototypeOf(ComponentToRegister.prototype);
-
- if (isTech || !isComp) {
- var reason = void 0;
-
- if (isTech) {
- reason = 'techs must be registered using Tech.registerTech()';
- } else {
- reason = 'must be a Component subclass';
- }
-
- throw new Error('Illegal component, "' + name + '"; ' + reason + '.');
- }
-
- name = toTitleCase(name);
-
- if (!Component.components_) {
- Component.components_ = {};
- }
-
- var Player = Component.getComponent('Player');
-
- if (name === 'Player' && Player && Player.players) {
- var players = Player.players;
- var playerNames = Object.keys(players);
-
- // If we have players that were disposed, then their name will still be
- // in Players.players. So, we must loop through and verify that the value
- // for each item is not null. This allows registration of the Player component
- // after all players have been disposed or before any were created.
- if (players && playerNames.length > 0 && playerNames.map(function (pname) {
- return players[pname];
- }).every(Boolean)) {
- throw new Error('Can not register Player component after player has been created.');
- }
- }
-
- Component.components_[name] = ComponentToRegister;
-
- return ComponentToRegister;
- };
-
- /**
- * Get a `Component` based on the name it was registered with.
- *
- * @param {string} name
- * The Name of the component to get.
- *
- * @return {Component}
- * The `Component` that got registered under the given name.
- *
- * @deprecated In `videojs` 6 this will not return `Component`s that were not
- * registered using {@link Component.registerComponent}. Currently we
- * check the global `videojs` object for a `Component` name and
- * return that if it exists.
- */
-
-
- Component.getComponent = function getComponent(name) {
- if (!name) {
- return;
- }
-
- name = toTitleCase(name);
-
- if (Component.components_ && Component.components_[name]) {
- return Component.components_[name];
- }
- };
-
- return Component;
- }();
-
- /**
- * Whether or not this component supports `requestAnimationFrame`.
- *
- * This is exposed primarily for testing purposes.
- *
- * @private
- * @type {Boolean}
- */
-
-
- Component.prototype.supportsRaf_ = typeof window_1.requestAnimationFrame === 'function' && typeof window_1.cancelAnimationFrame === 'function';
-
- Component.registerComponent('Component', Component);
-
- /**
- * @file time-ranges.js
- * @module time-ranges
- */
-
- /**
- * Returns the time for the specified index at the start or end
- * of a TimeRange object.
- *
- * @function time-ranges:indexFunction
- *
- * @param {number} [index=0]
- * The range number to return the time for.
- *
- * @return {number}
- * The time that offset at the specified index.
- *
- * @depricated index must be set to a value, in the future this will throw an error.
- */
-
- /**
- * An object that contains ranges of time for various reasons.
- *
- * @typedef {Object} TimeRange
- *
- * @property {number} length
- * The number of time ranges represented by this Object
- *
- * @property {time-ranges:indexFunction} start
- * Returns the time offset at which a specified time range begins.
- *
- * @property {time-ranges:indexFunction} end
- * Returns the time offset at which a specified time range begins.
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges
- */
-
- /**
- * Check if any of the time ranges are over the maximum index.
- *
- * @param {string} fnName
- * The function name to use for logging
- *
- * @param {number} index
- * The index to check
- *
- * @param {number} maxIndex
- * The maximum possible index
- *
- * @throws {Error} if the timeRanges provided are over the maxIndex
- */
- function rangeCheck(fnName, index, maxIndex) {
- if (typeof index !== 'number' || index < 0 || index > maxIndex) {
- throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is non-numeric or out of bounds (0-' + maxIndex + ').');
- }
- }
-
- /**
- * Check if any of the time ranges are over the maximum index.
- *
- * @param {string} fnName
- * The function name to use for logging
- *
- * @param {string} valueIndex
- * The proprety that should be used to get the time. should be 'start' or 'end'
- *
- * @param {Array} ranges
- * An array of time ranges
- *
- * @param {Array} [rangeIndex=0]
- * The index to start the search at
- *
- * @return {number}
- * The time that offset at the specified index.
- *
- *
- * @depricated rangeIndex must be set to a value, in the future this will throw an error.
- * @throws {Error} if rangeIndex is more than the length of ranges
- */
- function getRange(fnName, valueIndex, ranges, rangeIndex) {
- rangeCheck(fnName, rangeIndex, ranges.length - 1);
- return ranges[rangeIndex][valueIndex];
- }
-
- /**
- * Create a time range object givent ranges of time.
- *
- * @param {Array} [ranges]
- * An array of time ranges.
- */
- 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)
- };
- }
-
- /**
- * Should create a fake `TimeRange` object which mimics an HTML5 time range instance.
- *
- * @param {number|Array} start
- * The start of a single range or an array of ranges
- *
- * @param {number} end
- * The end of a single range.
- *
- * @private
- */
- function createTimeRanges(start, end) {
- if (Array.isArray(start)) {
- return createTimeRangesObj(start);
- } else if (start === undefined || end === undefined) {
- return createTimeRangesObj();
- }
- return createTimeRangesObj([[start, end]]);
- }
-
- /**
- * @file buffer.js
- * @module buffer
- */
- /**
- * Compute the percentage of the media that has been buffered.
- *
- * @param {TimeRange} buffered
- * The current `TimeRange` object representing buffered time ranges
- *
- * @param {number} duration
- * Total duration of the media
- *
- * @return {number}
- * Percent buffered of the total duration in decimal form.
- */
- function bufferedPercent(buffered, duration) {
- var bufferedDuration = 0;
- var start = void 0;
- var end = void 0;
-
- if (!duration) {
- return 0;
- }
-
- if (!buffered || !buffered.length) {
- buffered = createTimeRanges(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;
- }
-
- /**
- * @file fullscreen-api.js
- * @module fullscreen-api
- * @private
- */
- /**
- * Store the browser-specific methods for the fullscreen API.
- *
- * @type {Object}
- * @see [Specification]{@link https://fullscreen.spec.whatwg.org}
- * @see [Map Approach From Screenfull.js]{@link https://github.com/sindresorhus/screenfull.js}
- */
- var FullscreenApi = {};
-
-// browser API methods
- var apiMap = [['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 = void 0;
-
-// determine the supported set of functions
- for (var i = 0; i < apiMap.length; i++) {
- // check for exitFullscreen function
- if (apiMap[i][1] in document_1) {
- 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];
- }
- }
-
- /**
- * @file media-error.js
- */
- /**
- * A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class.
- *
- * @param {number|string|Object|MediaError} value
- * This can be of multiple types:
- * - number: should be a standard error code
- * - string: an error message (the code will be 0)
- * - Object: arbitrary properties
- * - `MediaError` (native): used to populate a video.js `MediaError` object
- * - `MediaError` (video.js): will return itself if it's already a
- * video.js `MediaError` object.
- *
- * @see [MediaError Spec]{@link https://dev.w3.org/html5/spec-author-view/video.html#mediaerror}
- * @see [Encrypted MediaError Spec]{@link https://www.w3.org/TR/2013/WD-encrypted-media-20130510/#error-codes}
- *
- * @class MediaError
- */
- function MediaError(value) {
-
- // Allow redundant calls to this constructor to avoid having `instanceof`
- // checks peppered around the code.
- if (value instanceof MediaError) {
- return value;
- }
-
- if (typeof value === 'number') {
- this.code = value;
- } else if (typeof value === 'string') {
- // default code is zero, so this is a custom error
- this.message = value;
- } else if (isObject(value)) {
-
- // We assign the `code` property manually because native `MediaError` objects
- // do not expose it as an own/enumerable property of the object.
- if (typeof value.code === 'number') {
- this.code = value.code;
- }
-
- assign(this, value);
- }
-
- 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 that to show 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 a plugin might provide a specific HTTP status code and an
- * error message for that code. Then when the plugin gets that error this class will
- * know how to display an error message for it. This allows a custom message to show
- * up on the `Player` error overlay.
- *
- * @type {Array}
- */
- MediaError.prototype.status = null;
-
- /**
- * Errors indexed by the W3C standard. The order **CANNOT CHANGE**! See the
- * specification listed under {@link MediaError} for more information.
- *
- * @enum {array}
- * @readonly
- * @property {string} 0 - MEDIA_ERR_CUSTOM
- * @property {string} 1 - MEDIA_ERR_CUSTOM
- * @property {string} 2 - MEDIA_ERR_ABORTED
- * @property {string} 3 - MEDIA_ERR_NETWORK
- * @property {string} 4 - MEDIA_ERR_SRC_NOT_SUPPORTED
- * @property {string} 5 - MEDIA_ERR_ENCRYPTED
- */
- MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED'];
-
- /**
- * The default `MediaError` messages based on the {@link MediaError.errorTypes}.
- *
- * @type {Array}
- * @constant
- */
- 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;
- }
-
- var tuple = SafeParseTuple;
-
- function SafeParseTuple(obj, reviver) {
- var json;
- var error = null;
-
- try {
- json = JSON.parse(obj, reviver);
- } catch (err) {
- error = err;
- }
-
- return [error, json]
- }
-
- /**
- * @file text-track-list-converter.js Utilities for capturing text track state and
- * re-creating tracks based on a capture.
- *
- * @module text-track-list-converter
- */
-
- /**
- * Examine a single {@link TextTrack} and return a JSON-compatible javascript object that
- * represents the {@link TextTrack}'s state.
- *
- * @param {TextTrack} track
- * The text track to query.
- *
- * @return {Object}
- * A serializable javascript representation of the TextTrack.
- * @private
- */
- 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 {@link Tech} and return a JSON-compatible javascript array that represents the
- * state of all {@link TextTrack}s currently configured. The return array is compatible with
- * {@link text-track-list-converter:jsonToTextTracks}.
- *
- * @param {Tech} tech
- * The tech object to query
- *
- * @return {Array}
- * A serializable javascript representation of the {@link Tech}s
- * {@link TextTrackList}.
- */
- 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_));
- };
-
- /**
- * Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript
- * object {@link TextTrack} representations.
- *
- * @param {Array} json
- * An array of `TextTrack` representation objects, like those that would be
- * produced by `textTracksToJson`.
- *
- * @param {Tech} tech
- * The `Tech` to create the `TextTrack`s on.
- */
- 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();
- };
-
- var textTrackConverter = {textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_};
-
- /**
- * @file modal-dialog.js
- */
- 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
- */
-
- var ModalDialog = function (_Component) {
- inherits(ModalDialog, _Component);
-
- /**
- * Create an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player 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);
-
- var _this = possibleConstructorReturn(this, _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_ = createEl('div', {
- className: MODAL_CLASS_NAME + '-content'
- }, {
- role: 'document'
- });
-
- _this.descEl_ = createEl('p', {
- className: MODAL_CLASS_NAME + '-description vjs-control-text',
- id: _this.el().getAttribute('aria-describedby')
- });
-
- textContent(_this.descEl_, _this.description());
- _this.el_.appendChild(_this.descEl_);
- _this.el_.appendChild(_this.contentEl_);
- return _this;
- }
-
- /**
- * Create the `ModalDialog`'s DOM element
- *
- * @return {Element}
- * The DOM element that gets created.
- */
-
-
- ModalDialog.prototype.createEl = function createEl$$1() {
- 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'
- });
- };
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- ModalDialog.prototype.buildCSSClass = function buildCSSClass() {
- return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this);
- };
-
- /**
- * Handles `keydown` events on the document, looking for ESC, which closes
- * the modal.
- *
- * @param {EventTarget~Event} e
- * The keypress that triggered this event.
- *
- * @listens keydown
- */
-
-
- 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}
- * the localized or raw label of this modal.
- */
-
-
- ModalDialog.prototype.label = function label() {
- return this.localize(this.options_.label || 'Modal Window');
- };
-
- /**
- * Returns the description string for this modal. Primarily used for
- * accessibility.
- *
- * @return {string}
- * The localized or raw description of this modal.
- */
-
-
- 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.
- *
- * @fires ModalDialog#beforemodalopen
- * @fires ModalDialog#modalopen
- */
-
-
- ModalDialog.prototype.open = function open() {
- if (!this.opened_) {
- var player = this.player();
-
- /**
- * Fired just before a `ModalDialog` is opened.
- *
- * @event ModalDialog#beforemodalopen
- * @type {EventTarget~Event}
- */
- 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.options_.pauseOnOpen && this.wasPlaying_) {
- player.pause();
- }
-
- if (this.closeable()) {
- this.on(this.el_.ownerDocument, 'keydown', bind(this, this.handleKeyPress));
- }
-
- // Hide controls and note if they were enabled.
- this.hadControls_ = player.controls();
- player.controls(false);
-
- this.show();
- this.conditionalFocus_();
- this.el().setAttribute('aria-hidden', 'false');
-
- /**
- * Fired just after a `ModalDialog` is opened.
- *
- * @event ModalDialog#modalopen
- * @type {EventTarget~Event}
- */
- this.trigger('modalopen');
- this.hasBeenOpened_ = true;
- }
- };
-
- /**
- * If the `ModalDialog` is currently open or closed.
- *
- * @param {boolean} [value]
- * If given, it will open (`true`) or close (`false`) the modal.
- *
- * @return {boolean}
- * the current open state of the modaldialog
- */
-
-
- ModalDialog.prototype.opened = function opened(value) {
- if (typeof value === 'boolean') {
- this[value ? 'open' : 'close']();
- }
- return this.opened_;
- };
-
- /**
- * Closes the modal, does nothing if the `ModalDialog` is
- * not open.
- *
- * @fires ModalDialog#beforemodalclose
- * @fires ModalDialog#modalclose
- */
-
-
- ModalDialog.prototype.close = function close() {
- if (!this.opened_) {
- return;
- }
- var player = this.player();
-
- /**
- * Fired just before a `ModalDialog` is closed.
- *
- * @event ModalDialog#beforemodalclose
- * @type {EventTarget~Event}
- */
- this.trigger('beforemodalclose');
- this.opened_ = false;
-
- if (this.wasPlaying_ && this.options_.pauseOnOpen) {
- player.play();
- }
-
- if (this.closeable()) {
- this.off(this.el_.ownerDocument, 'keydown', bind(this, this.handleKeyPress));
- }
-
- if (this.hadControls_) {
- player.controls(true);
- }
-
- this.hide();
- this.el().setAttribute('aria-hidden', 'true');
-
- /**
- * Fired just after a `ModalDialog` is closed.
- *
- * @event ModalDialog#modalclose
- * @type {EventTarget~Event}
- */
- this.trigger('modalclose');
- this.conditionalBlur_();
-
- if (this.options_.temporary) {
- this.dispose();
- }
- };
-
- /**
- * Check to see if the `ModalDialog` is closeable via the UI.
- *
- * @param {boolean} [value]
- * If given as a boolean, it will set the `closeable` option.
- *
- * @return {boolean}
- * Returns the final value of the closable option.
- */
-
-
- 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', {controlText: 'Close Modal Dialog'});
- 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.
- */
-
-
- ModalDialog.prototype.fill = function fill() {
- this.fillWith(this.content());
- };
-
- /**
- * Fill the modal's content element with arbitrary content.
- * The content element will be emptied before this change takes place.
- *
- * @fires ModalDialog#beforemodalfill
- * @fires ModalDialog#modalfill
- *
- * @param {Mixed} [content]
- * The same rules apply to this as apply to the `content` option.
- */
-
-
- ModalDialog.prototype.fillWith = function fillWith(content) {
- var contentEl = this.contentEl();
- var parentEl = contentEl.parentNode;
- var nextSiblingEl = contentEl.nextSibling;
-
- /**
- * Fired just before a `ModalDialog` is filled with content.
- *
- * @event ModalDialog#beforemodalfill
- * @type {EventTarget~Event}
- */
- 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();
- insertContent(contentEl, content);
- /**
- * Fired just after a `ModalDialog` is filled with content.
- *
- * @event ModalDialog#modalfill
- * @type {EventTarget~Event}
- */
- this.trigger('modalfill');
-
- // Re-inject the re-filled content element.
- if (nextSiblingEl) {
- parentEl.insertBefore(contentEl, nextSiblingEl);
- } else {
- parentEl.appendChild(contentEl);
- }
-
- // make sure that the close button is last in the dialog DOM
- var closeButton = this.getChild('closeButton');
-
- if (closeButton) {
- parentEl.appendChild(closeButton.el_);
- }
- };
-
- /**
- * Empties the content element. This happens anytime the modal is filled.
- *
- * @fires ModalDialog#beforemodalempty
- * @fires ModalDialog#modalempty
- */
-
-
- ModalDialog.prototype.empty = function empty() {
- /**
- * Fired just before a `ModalDialog` is emptied.
- *
- * @event ModalDialog#beforemodalempty
- * @type {EventTarget~Event}
- */
- this.trigger('beforemodalempty');
- emptyEl(this.contentEl());
-
- /**
- * Fired just after a `ModalDialog` is emptied.
- *
- * @event ModalDialog#modalempty
- * @type {EventTarget~Event}
- */
- this.trigger('modalempty');
- };
-
- /**
- * 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.
- *
- * @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}
- * The current content of the modal dialog
- */
-
-
- ModalDialog.prototype.content = function content(value) {
- if (typeof value !== 'undefined') {
- this.content_ = value;
- }
- return this.content_;
- };
-
- /**
- * conditionally focus the modal dialog if focus was previously on the player.
- *
- * @private
- */
-
-
- ModalDialog.prototype.conditionalFocus_ = function conditionalFocus_() {
- var activeEl = document_1.activeElement;
- var playerEl = this.player_.el_;
-
- this.previouslyActiveEl_ = null;
-
- if (playerEl.contains(activeEl) || playerEl === activeEl) {
- this.previouslyActiveEl_ = activeEl;
-
- this.focus();
-
- this.on(document_1, 'keydown', this.handleKeyDown);
- }
- };
-
- /**
- * conditionally blur the element and refocus the last focused element
- *
- * @private
- */
-
-
- ModalDialog.prototype.conditionalBlur_ = function conditionalBlur_() {
- if (this.previouslyActiveEl_) {
- this.previouslyActiveEl_.focus();
- this.previouslyActiveEl_ = null;
- }
-
- this.off(document_1, 'keydown', this.handleKeyDown);
- };
-
- /**
- * Keydown handler. Attached when modal is focused.
- *
- * @listens keydown
- */
-
-
- ModalDialog.prototype.handleKeyDown = function handleKeyDown(event) {
- // exit early if it isn't a tab key
- if (event.which !== 9) {
- return;
- }
-
- var focusableEls = this.focusableEls_();
- var activeEl = this.el_.querySelector(':focus');
- var focusIndex = void 0;
-
- for (var i = 0; i < focusableEls.length; i++) {
- if (activeEl === focusableEls[i]) {
- focusIndex = i;
- break;
- }
- }
-
- if (document_1.activeElement === this.el_) {
- focusIndex = 0;
- }
-
- if (event.shiftKey && focusIndex === 0) {
- focusableEls[focusableEls.length - 1].focus();
- event.preventDefault();
- } else if (!event.shiftKey && focusIndex === focusableEls.length - 1) {
- focusableEls[0].focus();
- event.preventDefault();
- }
- };
-
- /**
- * get all focusable elements
- *
- * @private
- */
-
-
- ModalDialog.prototype.focusableEls_ = function focusableEls_() {
- var allChildren = this.el_.querySelectorAll('*');
-
- return Array.prototype.filter.call(allChildren, function (child) {
- return (child instanceof window_1.HTMLAnchorElement || child instanceof window_1.HTMLAreaElement) && child.hasAttribute('href') || (child instanceof window_1.HTMLInputElement || child instanceof window_1.HTMLSelectElement || child instanceof window_1.HTMLTextAreaElement || child instanceof window_1.HTMLButtonElement) && !child.hasAttribute('disabled') || child instanceof window_1.HTMLIFrameElement || child instanceof window_1.HTMLObjectElement || child instanceof window_1.HTMLEmbedElement || child.hasAttribute('tabindex') && child.getAttribute('tabindex') !== -1 || child.hasAttribute('contenteditable');
- });
- };
-
- return ModalDialog;
- }(Component);
-
- /**
- * Default options for `ModalDialog` default options.
- *
- * @type {Object}
- * @private
- */
-
-
- ModalDialog.prototype.options_ = {
- pauseOnOpen: true,
- temporary: true
- };
-
- Component.registerComponent('ModalDialog', ModalDialog);
-
- /**
- * @file track-list.js
- */
- /**
- * Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and
- * {@link VideoTrackList}
- *
- * @extends EventTarget
- */
-
- var TrackList = function (_EventTarget) {
- inherits(TrackList, _EventTarget);
-
- /**
- * Create an instance of this class
- *
- * @param {Track[]} tracks
- * A list of tracks to initialize the list with.
- *
- * @param {Object} [list]
- * The child object with inheritance done manually for ie8.
- *
- * @abstract
- */
- function TrackList() {
- var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
-
- var _ret;
-
- var list = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
- classCallCheck(this, TrackList);
-
- var _this = possibleConstructorReturn(this, _EventTarget.call(this));
-
- if (!list) {
- list = _this; // eslint-disable-line
- if (IS_IE8) {
- list = document_1.createElement('custom');
- for (var prop in TrackList.prototype) {
- if (prop !== 'constructor') {
- list[prop] = TrackList.prototype[prop];
- }
- }
- }
- }
-
- list.tracks_ = [];
-
- /**
- * @memberof TrackList
- * @member {number} length
- * The current number of `Track`s in the this Trackist.
- * @instance
- */
- Object.defineProperty(list, 'length', {
- get: function get$$1() {
- return this.tracks_.length;
- }
- });
-
- for (var i = 0; i < tracks.length; i++) {
- list.addTrack(tracks[i]);
- }
-
- // must return the object, as for ie8 it will not be this
- // but a reference to a document object
- return _ret = list, possibleConstructorReturn(_this, _ret);
- }
-
- /**
- * Add a {@link Track} to the `TrackList`
- *
- * @param {Track} track
- * The audio, video, or text track to add to the list.
- *
- * @fires TrackList#addtrack
- */
-
-
- TrackList.prototype.addTrack = function addTrack(track) {
- var index = this.tracks_.length;
-
- if (!('' + index in this)) {
- Object.defineProperty(this, index, {
- get: function get$$1() {
- return this.tracks_[index];
- }
- });
- }
-
- // Do not add duplicate tracks
- if (this.tracks_.indexOf(track) === -1) {
- this.tracks_.push(track);
- /**
- * Triggered when a track is added to a track list.
- *
- * @event TrackList#addtrack
- * @type {EventTarget~Event}
- * @property {Track} track
- * A reference to track that was added.
- */
- this.trigger({
- track: track,
- type: 'addtrack'
- });
- }
- };
-
- /**
- * Remove a {@link Track} from the `TrackList`
- *
- * @param {Track} rtrack
- * The audio, video, or text track to remove from the list.
- *
- * @fires TrackList#removetrack
- */
-
-
- TrackList.prototype.removeTrack = function removeTrack(rtrack) {
- var track = void 0;
-
- 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;
- }
-
- /**
- * Triggered when a track is removed from track list.
- *
- * @event TrackList#removetrack
- * @type {EventTarget~Event}
- * @property {Track} track
- * A reference to track that was removed.
- */
- this.trigger({
- track: track,
- type: 'removetrack'
- });
- };
-
- /**
- * Get a Track from the TrackList by a tracks id
- *
- * @param {String} id - the id of the track to get
- * @method getTrackById
- * @return {Track}
- * @private
- */
-
-
- TrackList.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 TrackList;
- }(EventTarget);
-
- /**
- * Triggered when a different track is selected/enabled.
- *
- * @event TrackList#change
- * @type {EventTarget~Event}
- */
-
- /**
- * Events that can be called with on + eventName. See {@link EventHandler}.
- *
- * @property {Object} TrackList#allowedEvents_
- * @private
- */
-
-
- TrackList.prototype.allowedEvents_ = {
- change: 'change',
- addtrack: 'addtrack',
- removetrack: 'removetrack'
- };
-
-// emulate attribute EventHandler support to allow for feature detection
- for (var event in TrackList.prototype.allowedEvents_) {
- TrackList.prototype['on' + event] = null;
- }
-
- /**
- * @file audio-track-list.js
- */
- /**
- * Anywhere we call this function we diverge from the spec
- * as we only support one enabled audiotrack at a time
- *
- * @param {AudioTrackList} list
- * list to work on
- *
- * @param {AudioTrack} track
- * The track to skip
- *
- * @private
- */
- var disableOthers = function disableOthers(list, track) {
- for (var i = 0; i < list.length; i++) {
- if (!Object.keys(list[i]).length || track.id === list[i].id) {
- continue;
- }
- // another audio track is enabled, disable it
- list[i].enabled = false;
- }
- };
-
- /**
- * The current list of {@link AudioTrack} for a media file.
- *
- * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist}
- * @extends TrackList
- */
-
- var AudioTrackList = function (_TrackList) {
- inherits(AudioTrackList, _TrackList);
-
- /**
- * Create an instance of this class.
- *
- * @param {AudioTrack[]} [tracks=[]]
- * A list of `AudioTrack` to instantiate the list with.
- */
- function AudioTrackList() {
- var _this, _ret;
-
- var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
- classCallCheck(this, AudioTrackList);
-
- var list = void 0;
-
- // make sure only 1 track is enabled
- // sorted from last index to first index
- for (var i = tracks.length - 1; i >= 0; i--) {
- if (tracks[i].enabled) {
- disableOthers(tracks, tracks[i]);
- break;
- }
- }
-
- // IE8 forces us to implement inheritance ourselves
- // as it does not support Object.defineProperty properly
- if (IS_IE8) {
- list = document_1.createElement('custom');
- for (var prop in TrackList.prototype) {
- if (prop !== 'constructor') {
- list[prop] = TrackList.prototype[prop];
- }
- }
- for (var _prop in AudioTrackList.prototype) {
- if (_prop !== 'constructor') {
- list[_prop] = AudioTrackList.prototype[_prop];
- }
- }
- }
-
- list = (_this = possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
- list.changing_ = false;
-
- return _ret = list, possibleConstructorReturn(_this, _ret);
- }
-
- /**
- * Add an {@link AudioTrack} to the `AudioTrackList`.
- *
- * @param {AudioTrack} track
- * The AudioTrack to add to the list
- *
- * @fires TrackList#addtrack
- */
-
-
- AudioTrackList.prototype.addTrack = function addTrack(track) {
- var _this2 = this;
-
- if (track.enabled) {
- disableOthers(this, track);
- }
-
- _TrackList.prototype.addTrack.call(this, track);
- // native tracks don't have this
- if (!track.addEventListener) {
- return;
- }
-
- /**
- * @listens AudioTrack#enabledchange
- * @fires TrackList#change
- */
- track.addEventListener('enabledchange', function () {
- // when we are disabling other tracks (since we don't support
- // more than one track at a time) we will set changing_
- // to true so that we don't trigger additional change events
- if (_this2.changing_) {
- return;
- }
- _this2.changing_ = true;
- disableOthers(_this2, track);
- _this2.changing_ = false;
- _this2.trigger('change');
- });
- };
-
- return AudioTrackList;
- }(TrackList);
-
- /**
- * @file video-track-list.js
- */
- /**
- * Un-select all other {@link VideoTrack}s that are selected.
- *
- * @param {VideoTrackList} list
- * list to work on
- *
- * @param {VideoTrack} track
- * The track to skip
- *
- * @private
- */
- var disableOthers$1 = function disableOthers(list, track) {
- for (var i = 0; i < list.length; i++) {
- if (!Object.keys(list[i]).length || track.id === list[i].id) {
- continue;
- }
- // another video track is enabled, disable it
- list[i].selected = false;
- }
- };
-
- /**
- * The current list of {@link VideoTrack} for a video.
- *
- * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist}
- * @extends TrackList
- */
-
- var VideoTrackList = function (_TrackList) {
- inherits(VideoTrackList, _TrackList);
-
- /**
- * Create an instance of this class.
- *
- * @param {VideoTrack[]} [tracks=[]]
- * A list of `VideoTrack` to instantiate the list with.
- */
- function VideoTrackList() {
- var _this, _ret;
-
- var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
- classCallCheck(this, VideoTrackList);
-
- var list = void 0;
-
- // make sure only 1 track is enabled
- // sorted from last index to first index
- for (var i = tracks.length - 1; i >= 0; i--) {
- if (tracks[i].selected) {
- disableOthers$1(tracks, tracks[i]);
- break;
- }
- }
-
- // IE8 forces us to implement inheritance ourselves
- // as it does not support Object.defineProperty properly
- if (IS_IE8) {
- list = document_1.createElement('custom');
- for (var prop in TrackList.prototype) {
- if (prop !== 'constructor') {
- list[prop] = TrackList.prototype[prop];
- }
- }
- for (var _prop in VideoTrackList.prototype) {
- if (_prop !== 'constructor') {
- list[_prop] = VideoTrackList.prototype[_prop];
- }
- }
- }
-
- list = (_this = possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
- list.changing_ = false;
-
- /**
- * @member {number} VideoTrackList#selectedIndex
- * The current index of the selected {@link VideoTrack`}.
- */
- Object.defineProperty(list, 'selectedIndex', {
- get: function get$$1() {
- for (var _i = 0; _i < this.length; _i++) {
- if (this[_i].selected) {
- return _i;
- }
- }
- return -1;
- },
- set: function set$$1() {
- }
- });
-
- return _ret = list, possibleConstructorReturn(_this, _ret);
- }
-
- /**
- * Add a {@link VideoTrack} to the `VideoTrackList`.
- *
- * @param {VideoTrack} track
- * The VideoTrack to add to the list
- *
- * @fires TrackList#addtrack
- */
-
-
- VideoTrackList.prototype.addTrack = function addTrack(track) {
- var _this2 = this;
-
- if (track.selected) {
- disableOthers$1(this, track);
- }
-
- _TrackList.prototype.addTrack.call(this, track);
- // native tracks don't have this
- if (!track.addEventListener) {
- return;
- }
-
- /**
- * @listens VideoTrack#selectedchange
- * @fires TrackList#change
- */
- track.addEventListener('selectedchange', function () {
- if (_this2.changing_) {
- return;
- }
- _this2.changing_ = true;
- disableOthers$1(_this2, track);
- _this2.changing_ = false;
- _this2.trigger('change');
- });
- };
-
- return VideoTrackList;
- }(TrackList);
-
- /**
- * @file text-track-list.js
- */
- /**
- * The current list of {@link TextTrack} for a media file.
- *
- * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist}
- * @extends TrackList
- */
-
- var TextTrackList = function (_TrackList) {
- inherits(TextTrackList, _TrackList);
-
- /**
- * Create an instance of this class.
- *
- * @param {TextTrack[]} [tracks=[]]
- * A list of `TextTrack` to instantiate the list with.
- */
- function TextTrackList() {
- var _this, _ret;
-
- var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
- classCallCheck(this, TextTrackList);
-
- var list = void 0;
-
- // IE8 forces us to implement inheritance ourselves
- // as it does not support Object.defineProperty properly
- if (IS_IE8) {
- list = document_1.createElement('custom');
- for (var prop in TrackList.prototype) {
- if (prop !== 'constructor') {
- list[prop] = TrackList.prototype[prop];
- }
- }
- for (var _prop in TextTrackList.prototype) {
- if (_prop !== 'constructor') {
- list[_prop] = TextTrackList.prototype[_prop];
- }
- }
- }
-
- list = (_this = possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
- return _ret = list, possibleConstructorReturn(_this, _ret);
- }
-
- /**
- * Add a {@link TextTrack} to the `TextTrackList`
- *
- * @param {TextTrack} track
- * The text track to add to the list.
- *
- * @fires TrackList#addtrack
- */
-
-
- TextTrackList.prototype.addTrack = function addTrack(track) {
- _TrackList.prototype.addTrack.call(this, track);
-
- /**
- * @listens TextTrack#modechange
- * @fires TrackList#change
- */
- track.addEventListener('modechange', bind(this, function () {
- this.trigger('change');
- }));
-
- var nonLanguageTextTrackKind = ['metadata', 'chapters'];
-
- if (nonLanguageTextTrackKind.indexOf(track.kind) === -1) {
- track.addEventListener('modechange', bind(this, function () {
- this.trigger('selectedlanguagechange');
- }));
- }
- };
-
- return TextTrackList;
- }(TrackList);
-
- /**
- * @file html-track-element-list.js
- */
-
- /**
- * The current list of {@link HtmlTrackElement}s.
- */
-
- var HtmlTrackElementList = function () {
-
- /**
- * Create an instance of this class.
- *
- * @param {HtmlTrackElement[]} [tracks=[]]
- * A list of `HtmlTrackElement` to instantiate the list with.
- */
- function HtmlTrackElementList() {
- var trackElements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
- classCallCheck(this, HtmlTrackElementList);
-
- var list = this; // eslint-disable-line
-
- if (IS_IE8) {
- list = document_1.createElement('custom');
-
- for (var prop in HtmlTrackElementList.prototype) {
- if (prop !== 'constructor') {
- list[prop] = HtmlTrackElementList.prototype[prop];
- }
- }
- }
-
- list.trackElements_ = [];
-
- /**
- * @memberof HtmlTrackElementList
- * @member {number} length
- * The current number of `Track`s in the this Trackist.
- * @instance
- */
- Object.defineProperty(list, 'length', {
- get: function get$$1() {
- return this.trackElements_.length;
- }
- });
-
- for (var i = 0, length = trackElements.length; i < length; i++) {
- list.addTrackElement_(trackElements[i]);
- }
-
- if (IS_IE8) {
- return list;
- }
- }
-
- /**
- * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList`
- *
- * @param {HtmlTrackElement} trackElement
- * The track element to add to the list.
- *
- * @private
- */
-
-
- HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) {
- var index = this.trackElements_.length;
-
- if (!('' + index in this)) {
- Object.defineProperty(this, index, {
- get: function get$$1() {
- return this.trackElements_[index];
- }
- });
- }
-
- // Do not add duplicate elements
- if (this.trackElements_.indexOf(trackElement) === -1) {
- this.trackElements_.push(trackElement);
- }
- };
-
- /**
- * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an
- * {@link TextTrack}.
- *
- * @param {TextTrack} track
- * The track associated with a track element.
- *
- * @return {HtmlTrackElement|undefined}
- * The track element that was found or undefined.
- *
- * @private
- */
-
-
- HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) {
- var trackElement_ = void 0;
-
- for (var i = 0, length = this.trackElements_.length; i < length; i++) {
- if (track === this.trackElements_[i].track) {
- trackElement_ = this.trackElements_[i];
-
- break;
- }
- }
-
- return trackElement_;
- };
-
- /**
- * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList`
- *
- * @param {HtmlTrackElement} trackElement
- * The track element to remove from the list.
- *
- * @private
- */
-
-
- HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) {
- for (var i = 0, length = this.trackElements_.length; i < length; i++) {
- if (trackElement === this.trackElements_[i]) {
- this.trackElements_.splice(i, 1);
-
- break;
- }
- }
- };
-
- return HtmlTrackElementList;
- }();
-
- /**
- * @file text-track-cue-list.js
- */
- /**
- * @typedef {Object} TextTrackCueList~TextTrackCue
- *
- * @property {string} id
- * The unique id for this text track cue
- *
- * @property {number} startTime
- * The start time for this text track cue
- *
- * @property {number} endTime
- * The end time for this text track cue
- *
- * @property {boolean} pauseOnExit
- * Pause when the end time is reached if true.
- *
- * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcue}
- */
-
- /**
- * A List of TextTrackCues.
- *
- * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist}
- */
-
- var TextTrackCueList = function () {
-
- /**
- * Create an instance of this class..
- *
- * @param {Array} cues
- * A list of cues to be initialized with
- */
- function TextTrackCueList(cues) {
- classCallCheck(this, TextTrackCueList);
-
- var list = this; // eslint-disable-line
-
- if (IS_IE8) {
- list = document_1.createElement('custom');
-
- for (var prop in TextTrackCueList.prototype) {
- if (prop !== 'constructor') {
- list[prop] = TextTrackCueList.prototype[prop];
- }
- }
- }
-
- TextTrackCueList.prototype.setCues_.call(list, cues);
-
- /**
- * @memberof TextTrackCueList
- * @member {number} length
- * The current number of `TextTrackCue`s in the TextTrackCueList.
- * @instance
- */
- Object.defineProperty(list, 'length', {
- get: function get$$1() {
- return this.length_;
- }
- });
-
- if (IS_IE8) {
- return list;
- }
- }
-
- /**
- * A setter for cues in this list. Creates getters
- * an an index for the cues.
- *
- * @param {Array} cues
- * An array of cues to set
- *
- * @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$$1() {
- return this.cues_[index];
- }
- });
- }
- };
-
- if (oldLength < l) {
- i = oldLength;
-
- for (; i < l; i++) {
- defineProp.call(this, i);
- }
- }
- };
-
- /**
- * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id.
- *
- * @param {string} id
- * The id of the cue that should be searched for.
- *
- * @return {TextTrackCueList~TextTrackCue|null}
- * A single cue or null if none was found.
- */
-
-
- 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;
- }();
-
- /**
- * @file track-kinds.js
- */
-
- /**
- * All possible `VideoTrackKind`s
- *
- * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind
- * @typedef VideoTrack~Kind
- * @enum
- */
- var VideoTrackKind = {
- alternative: 'alternative',
- captions: 'captions',
- main: 'main',
- sign: 'sign',
- subtitles: 'subtitles',
- commentary: 'commentary'
- };
-
- /**
- * All possible `AudioTrackKind`s
- *
- * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind
- * @typedef AudioTrack~Kind
- * @enum
- */
- var AudioTrackKind = {
- 'alternative': 'alternative',
- 'descriptions': 'descriptions',
- 'main': 'main',
- 'main-desc': 'main-desc',
- 'translation': 'translation',
- 'commentary': 'commentary'
- };
-
- /**
- * All possible `TextTrackKind`s
- *
- * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-texttrack-kind
- * @typedef TextTrack~Kind
- * @enum
- */
- var TextTrackKind = {
- subtitles: 'subtitles',
- captions: 'captions',
- descriptions: 'descriptions',
- chapters: 'chapters',
- metadata: 'metadata'
- };
-
- /**
- * All possible `TextTrackMode`s
- *
- * @see https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode
- * @typedef TextTrack~Mode
- * @enum
- */
- var TextTrackMode = {
- disabled: 'disabled',
- hidden: 'hidden',
- showing: 'showing'
- };
-
- /**
- * @file track.js
- */
- /**
- * A Track class that contains all of the common functionality for {@link AudioTrack},
- * {@link VideoTrack}, and {@link TextTrack}.
- *
- * > Note: This class should not be used directly
- *
- * @see {@link https://html.spec.whatwg.org/multipage/embedded-content.html}
- * @extends EventTarget
- * @abstract
- */
-
- var Track = function (_EventTarget) {
- inherits(Track, _EventTarget);
-
- /**
- * Create an instance of this class.
- *
- * @param {Object} [options={}]
- * Object of option names and values
- *
- * @param {string} [options.kind='']
- * A valid kind for the track type you are creating.
- *
- * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
- * A unique id for this AudioTrack.
- *
- * @param {string} [options.label='']
- * The menu label for this track.
- *
- * @param {string} [options.language='']
- * A valid two character language code.
- *
- * @abstract
- */
- function Track() {
- var _ret;
-
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- classCallCheck(this, Track);
-
- var _this = possibleConstructorReturn(this, _EventTarget.call(this));
-
- var track = _this; // eslint-disable-line
-
- if (IS_IE8) {
- track = document_1.createElement('custom');
- for (var prop in Track.prototype) {
- if (prop !== 'constructor') {
- track[prop] = Track.prototype[prop];
- }
- }
- }
-
- var trackProps = {
- id: options.id || 'vjs_track_' + newGUID(),
- kind: options.kind || '',
- label: options.label || '',
- language: options.language || ''
- };
-
- /**
- * @memberof Track
- * @member {string} id
- * The id of this track. Cannot be changed after creation.
- * @instance
- *
- * @readonly
- */
-
- /**
- * @memberof Track
- * @member {string} kind
- * The kind of track that this is. Cannot be changed after creation.
- * @instance
- *
- * @readonly
- */
-
- /**
- * @memberof Track
- * @member {string} label
- * The label of this track. Cannot be changed after creation.
- * @instance
- *
- * @readonly
- */
-
- /**
- * @memberof Track
- * @member {string} language
- * The two letter language code for this track. Cannot be changed after
- * creation.
- * @instance
- *
- * @readonly
- */
-
- var _loop = function _loop(key) {
- Object.defineProperty(track, key, {
- get: function get$$1() {
- return trackProps[key];
- },
- set: function set$$1() {
- }
- });
- };
-
- for (var key in trackProps) {
- _loop(key);
- }
-
- return _ret = track, possibleConstructorReturn(_this, _ret);
- }
-
- return Track;
- }(EventTarget);
-
- /**
- * @file url.js
- * @module url
- */
- /**
- * @typedef {Object} url:URLObject
- *
- * @property {string} protocol
- * The protocol of the url that was parsed.
- *
- * @property {string} hostname
- * The hostname of the url that was parsed.
- *
- * @property {string} port
- * The port of the url that was parsed.
- *
- * @property {string} pathname
- * The pathname of the url that was parsed.
- *
- * @property {string} search
- * The search query of the url that was parsed.
- *
- * @property {string} hash
- * The hash of the url that was parsed.
- *
- * @property {string} host
- * The host of the url that was parsed.
- */
-
- /**
- * Resolve and parse the elements of a URL.
- *
- * @param {String} url
- * The url to parse
- *
- * @return {url:URLObject}
- * An object of url details
- */
- 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 = document_1.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 = void 0;
-
- if (addToBody) {
- div = document_1.createElement('div');
- div.innerHTML = '<a href="' + url + '"></a>';
- a = div.firstChild;
- // prevent the div from affecting layout
- div.setAttribute('style', 'display:none; position:absolute;');
- document_1.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 (!details.protocol) {
- details.protocol = window_1.location.protocol;
- }
-
- if (addToBody) {
- document_1.body.removeChild(div);
- }
-
- return details;
- };
-
- /**
- * Get absolute version of relative URL. Used to tell flash correct URL.
- *
- *
- * @param {string} url
- * URL to make absolute
- *
- * @return {string}
- * Absolute URL
- *
- * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
- */
- 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 = document_1.createElement('div');
-
- div.innerHTML = '<a href="' + url + '">x</a>';
- url = div.firstChild.href;
- }
-
- return url;
- };
-
- /**
- * Returns the extension of the passed file name. It will return an empty string
- * if passed 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.
- */
- 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 '';
- };
-
- /**
- * 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.
- */
- var isCrossOrigin = function isCrossOrigin(url) {
- var winLoc = window_1.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;
- };
-
- var Url = (Object.freeze || Object)({
- parseUrl: parseUrl,
- getAbsoluteURL: getAbsoluteURL,
- getFileExtension: getFileExtension,
- isCrossOrigin: isCrossOrigin
- });
-
- var index$1 = isFunction;
-
- var toString$1 = Object.prototype.toString;
-
- function isFunction(fn) {
- var string = toString$1.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))
- }
-
- var index$3 = createCommonjsModule(function (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*$/, '');
- };
- });
-
- var index$5 = forEach;
-
- var toString$2 = Object.prototype.toString;
- var hasOwnProperty = Object.prototype.hasOwnProperty;
-
- function forEach(list, iterator, context) {
- if (!index$1(iterator)) {
- throw new TypeError('iterator must be a function')
- }
-
- if (arguments.length < 3) {
- context = this;
- }
-
- if (toString$2.call(list) === '[object Array]')
- forEachArray$1(list, iterator, context);
- else if (typeof list === 'string')
- forEachString(list, iterator, context);
- else
- forEachObject(list, iterator, context);
- }
-
- function forEachArray$1(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);
- }
- }
- }
-
- var isArray = function (arg) {
- return Object.prototype.toString.call(arg) === '[object Array]';
- };
-
- var parseHeaders = function (headers) {
- if (!headers)
- return {}
-
- var result = {};
-
- index$5(
- index$3(headers).split('\n')
- , function (row) {
- var index = row.indexOf(':')
- , key = index$3(row.slice(0, index)).toLowerCase()
- , value = index$3(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
- };
-
- var immutable = extend;
-
- var hasOwnProperty$1 = 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$1.call(source, key)) {
- target[key] = source[key];
- }
- }
- }
-
- return target
- }
-
- var index = createXHR;
- createXHR.XMLHttpRequest = window_1.XMLHttpRequest || noop;
- createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window_1.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 (index$1(options)) {
- callback = options;
- if (typeof uri === "string") {
- params = {uri: uri};
- }
- } else {
- params = immutable(options, {uri: uri});
- }
-
- params.callback = callback;
- return params
- }
-
- function createXHR(uri, options, callback) {
- options = initParams(uri, options, callback);
- return _createXHR(options)
- }
-
- function _createXHR(options) {
- if (typeof options.callback === "undefined") {
- throw new Error("callback argument missing")
- }
-
- var called = false;
- var callback = function cbOnce(err, response, body) {
- if (!called) {
- called = true;
- options.callback(err, response, body);
- }
- };
-
- function readystatechange() {
- if (xhr.readyState === 4) {
- setTimeout(loadFunc, 0);
- }
- }
-
- 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 {
- body = xhr.responseText || getXml(xhr);
- }
-
- if (isJson) {
- try {
- body = JSON.parse(body);
- } catch (e) {
- }
- }
-
- return body
- }
-
- function errorFunc(evt) {
- clearTimeout(timeoutTimer);
- if (!(evt instanceof Error)) {
- evt = new Error("" + (evt || "Unknown XMLHttpRequest Error"));
- }
- evt.statusCode = 0;
- return 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");
- }
- return 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;
- var headers = xhr.headers = options.headers || {};
- var sync = !!options.sync;
- var isJson = false;
- var timeoutTimer;
- var failureResponse = {
- body: undefined,
- headers: {},
- statusCode: 0,
- method: method,
- url: uri,
- rawRequest: xhr
- };
-
- if ("json" in options && options.json !== false) {
- 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 === true ? body : 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.onabort = function () {
- aborted = true;
- };
- 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 () {
- if (aborted) return
- 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);
- }
-
- // Microsoft Edge browser sends "undefined" when send is called with undefined value.
- // XMLHttpRequest spec says to pass null as body to indicate no body
- // See https://github.com/naugtur/xhr/issues/100.
- xhr.send(body || null);
-
- return xhr
-
-
- }
-
- function getXml(xhr) {
- if (xhr.responseType === "document") {
- return xhr.responseXML
- }
- var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror";
- if (xhr.responseType === "" && !firefoxBugTakenEffect) {
- return xhr.responseXML
- }
-
- return null
- }
-
- function noop() {
- }
-
- /**
- * @file text-track.js
- */
- /**
- * Takes a webvtt file contents and parses it into cues
- *
- * @param {string} srcContent
- * webVTT file contents
- *
- * @param {TextTrack} track
- * TextTrack to add cues to. Cues come from the srcContent.
- *
- * @private
- */
- var parseCues = function parseCues(srcContent, track) {
- var parser = new window_1.WebVTT.Parser(window_1, window_1.vttjs, window_1.WebVTT.StringDecoder());
- var errors = [];
-
- parser.oncue = function (cue) {
- track.addCue(cue);
- };
-
- parser.onparsingerror = function (error) {
- errors.push(error);
- };
-
- parser.onflush = function () {
- track.trigger({
- type: 'loadeddata',
- target: track
- });
- };
-
- parser.parse(srcContent);
- if (errors.length > 0) {
- if (window_1.console && window_1.console.groupCollapsed) {
- window_1.console.groupCollapsed('Text Track parsing errors for ' + track.src);
- }
- errors.forEach(function (error) {
- return log$1.error(error);
- });
- if (window_1.console && window_1.console.groupEnd) {
- window_1.console.groupEnd();
- }
- }
-
- parser.flush();
- };
-
- /**
- * Load a `TextTrack` from a specifed url.
- *
- * @param {string} src
- * Url to load track from.
- *
- * @param {TextTrack} track
- * Track to add cues to. Comes from the content at the end of `url`.
- *
- * @private
- */
- var loadTrack = function loadTrack(src, track) {
- var opts = {
- uri: src
- };
- var crossOrigin = isCrossOrigin(src);
-
- if (crossOrigin) {
- opts.cors = crossOrigin;
- }
-
- index(opts, bind(this, function (err, response, responseBody) {
- if (err) {
- return log$1.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 window_1.WebVTT !== 'function') {
- if (track.tech_) {
- var loadHandler = function loadHandler() {
- return parseCues(responseBody, track);
- };
-
- track.tech_.on('vttjsloaded', loadHandler);
- track.tech_.on('vttjserror', function () {
- log$1.error('vttjs failed to load, stopping trying to process ' + track.src);
- track.tech_.off('vttjsloaded', loadHandler);
- });
- }
- } else {
- parseCues(responseBody, track);
- }
- }));
- };
-
- /**
- * A representation of a single `TextTrack`.
- *
- * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack}
- * @extends Track
- */
-
- var TextTrack = function (_Track) {
- inherits(TextTrack, _Track);
-
- /**
- * Create an instance of this class.
- *
- * @param {Object} options={}
- * Object of option names and values
- *
- * @param {Tech} options.tech
- * A reference to the tech that owns this TextTrack.
- *
- * @param {TextTrack~Kind} [options.kind='subtitles']
- * A valid text track kind.
- *
- * @param {TextTrack~Mode} [options.mode='disabled']
- * A valid text track mode.
- *
- * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
- * A unique id for this TextTrack.
- *
- * @param {string} [options.label='']
- * The menu label for this track.
- *
- * @param {string} [options.language='']
- * A valid two character language code.
- *
- * @param {string} [options.srclang='']
- * A valid two character language code. An alternative, but deprioritized
- * vesion of `options.language`
- *
- * @param {string} [options.src]
- * A url to TextTrack cues.
- *
- * @param {boolean} [options.default]
- * If this track should default to on or off.
- */
- function TextTrack() {
- var _this, _ret;
-
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- classCallCheck(this, TextTrack);
-
- if (!options.tech) {
- throw new Error('A tech was not provided.');
- }
-
- var settings = mergeOptions(options, {
- kind: TextTrackKind[options.kind] || 'subtitles',
- language: options.language || options.srclang || ''
- });
- var mode = TextTrackMode[settings.mode] || 'disabled';
- var default_ = settings['default'];
-
- if (settings.kind === 'metadata' || settings.kind === 'chapters') {
- mode = 'hidden';
- }
- // on IE8 this will be a document element
- // for every other browser this will be a normal object
- var tt = (_this = possibleConstructorReturn(this, _Track.call(this, settings)), _this);
-
- tt.tech_ = settings.tech;
-
- if (IS_IE8) {
- for (var prop in TextTrack.prototype) {
- if (prop !== 'constructor') {
- tt[prop] = TextTrack.prototype[prop];
- }
- }
- }
-
- tt.cues_ = [];
- tt.activeCues_ = [];
-
- var cues = new TextTrackCueList(tt.cues_);
- var activeCues = new TextTrackCueList(tt.activeCues_);
- var changed = false;
- var timeupdateHandler = bind(tt, function () {
-
- // Accessing this.activeCues for the side-effects of updating itself
- // due to it's nature as a getter function. Do not remove or cues will
- // stop updating!
- /* eslint-disable no-unused-expressions */
- this.activeCues;
- /* eslint-enable no-unused-expressions */
- if (changed) {
- this.trigger('cuechange');
- changed = false;
- }
- });
-
- if (mode !== 'disabled') {
- tt.tech_.ready(function () {
- tt.tech_.on('timeupdate', timeupdateHandler);
- }, true);
- }
-
- /**
- * @memberof TextTrack
- * @member {boolean} default
- * If this track was set to be on or off by default. Cannot be changed after
- * creation.
- * @instance
- *
- * @readonly
- */
- Object.defineProperty(tt, 'default', {
- get: function get$$1() {
- return default_;
- },
- set: function set$$1() {
- }
- });
-
- /**
- * @memberof TextTrack
- * @member {string} mode
- * Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will
- * not be set if setting to an invalid mode.
- * @instance
- *
- * @fires TextTrack#modechange
- */
- Object.defineProperty(tt, 'mode', {
- get: function get$$1() {
- return mode;
- },
- set: function set$$1(newMode) {
- var _this2 = this;
-
- if (!TextTrackMode[newMode]) {
- return;
- }
- mode = newMode;
- if (mode === 'showing') {
-
- this.tech_.ready(function () {
- _this2.tech_.on('timeupdate', timeupdateHandler);
- }, true);
- }
- /**
- * An event that fires when mode changes on this track. This allows
- * the TextTrackList that holds this track to act accordingly.
- *
- * > Note: This is not part of the spec!
- *
- * @event TextTrack#modechange
- * @type {EventTarget~Event}
- */
- this.trigger('modechange');
- }
- });
-
- /**
- * @memberof TextTrack
- * @member {TextTrackCueList} cues
- * The text track cue list for this TextTrack.
- * @instance
- */
- Object.defineProperty(tt, 'cues', {
- get: function get$$1() {
- if (!this.loaded_) {
- return null;
- }
-
- return cues;
- },
- set: function set$$1() {
- }
- });
-
- /**
- * @memberof TextTrack
- * @member {TextTrackCueList} activeCues
- * The list text track cues that are currently active for this TextTrack.
- * @instance
- */
- Object.defineProperty(tt, 'activeCues', {
- get: function get$$1() {
- 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$$1() {
- }
- });
-
- if (settings.src) {
- tt.src = settings.src;
- loadTrack(settings.src, tt);
- } else {
- tt.loaded_ = true;
- }
-
- return _ret = tt, possibleConstructorReturn(_this, _ret);
- }
-
- /**
- * Add a cue to the internal list of cues.
- *
- * @param {TextTrack~Cue} cue
- * The cue to add to our internal list
- */
-
-
- TextTrack.prototype.addCue = function addCue(originalCue) {
- var cue = originalCue;
-
- if (window_1.vttjs && !(originalCue instanceof window_1.vttjs.VTTCue)) {
- cue = new window_1.vttjs.VTTCue(originalCue.startTime, originalCue.endTime, originalCue.text);
-
- for (var prop in originalCue) {
- if (!(prop in cue)) {
- cue[prop] = originalCue[prop];
- }
- }
-
- // make sure that `id` is copied over
- cue.id = originalCue.id;
- cue.originalCue_ = originalCue;
- }
-
- var tracks = this.tech_.textTracks();
-
- 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_);
- };
-
- /**
- * Remove a cue from our internal list
- *
- * @param {TextTrack~Cue} removeCue
- * The cue to remove from our internal list
- */
-
-
- TextTrack.prototype.removeCue = function removeCue(_removeCue) {
- var i = this.cues_.length;
-
- while (i--) {
- var cue = this.cues_[i];
-
- if (cue === _removeCue || cue.originalCue_ && cue.originalCue_ === _removeCue) {
- this.cues_.splice(i, 1);
- this.cues.setCues_(this.cues_);
- break;
- }
- }
- };
-
- return TextTrack;
- }(Track);
-
- /**
- * cuechange - One or more cues in the track have become active or stopped being active.
- */
-
-
- TextTrack.prototype.allowedEvents_ = {
- cuechange: 'cuechange'
- };
-
- /**
- * A representation of a single `AudioTrack`. If it is part of an {@link AudioTrackList}
- * only one `AudioTrack` in the list will be enabled at a time.
- *
- * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack}
- * @extends Track
- */
-
- var AudioTrack = function (_Track) {
- inherits(AudioTrack, _Track);
-
- /**
- * Create an instance of this class.
- *
- * @param {Object} [options={}]
- * Object of option names and values
- *
- * @param {AudioTrack~Kind} [options.kind='']
- * A valid audio track kind
- *
- * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
- * A unique id for this AudioTrack.
- *
- * @param {string} [options.label='']
- * The menu label for this track.
- *
- * @param {string} [options.language='']
- * A valid two character language code.
- *
- * @param {boolean} [options.enabled]
- * If this track is the one that is currently playing. If this track is part of
- * an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled.
- */
- function AudioTrack() {
- var _this, _ret;
-
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- classCallCheck(this, AudioTrack);
-
- var settings = mergeOptions(options, {
- kind: AudioTrackKind[options.kind] || ''
- });
- // on IE8 this will be a document element
- // for every other browser this will be a normal object
- var track = (_this = possibleConstructorReturn(this, _Track.call(this, settings)), _this);
- var enabled = false;
-
- if (IS_IE8) {
- for (var prop in AudioTrack.prototype) {
- if (prop !== 'constructor') {
- track[prop] = AudioTrack.prototype[prop];
- }
- }
- }
- /**
- * @memberof AudioTrack
- * @member {boolean} enabled
- * If this `AudioTrack` is enabled or not. When setting this will
- * fire {@link AudioTrack#enabledchange} if the state of enabled is changed.
- * @instance
- *
- * @fires VideoTrack#selectedchange
- */
- Object.defineProperty(track, 'enabled', {
- get: function get$$1() {
- return enabled;
- },
- set: function set$$1(newEnabled) {
- // an invalid or unchanged value
- if (typeof newEnabled !== 'boolean' || newEnabled === enabled) {
- return;
- }
- enabled = newEnabled;
-
- /**
- * An event that fires when enabled changes on this track. This allows
- * the AudioTrackList that holds this track to act accordingly.
- *
- * > Note: This is not part of the spec! Native tracks will do
- * this internally without an event.
- *
- * @event AudioTrack#enabledchange
- * @type {EventTarget~Event}
- */
- this.trigger('enabledchange');
- }
- });
-
- // if the user sets this track to selected then
- // set selected to that true value otherwise
- // we keep it false
- if (settings.enabled) {
- track.enabled = settings.enabled;
- }
- track.loaded_ = true;
-
- return _ret = track, possibleConstructorReturn(_this, _ret);
- }
-
- return AudioTrack;
- }(Track);
-
- /**
- * A representation of a single `VideoTrack`.
- *
- * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack}
- * @extends Track
- */
-
- var VideoTrack = function (_Track) {
- inherits(VideoTrack, _Track);
-
- /**
- * Create an instance of this class.
- *
- * @param {Object} [options={}]
- * Object of option names and values
- *
- * @param {string} [options.kind='']
- * A valid {@link VideoTrack~Kind}
- *
- * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
- * A unique id for this AudioTrack.
- *
- * @param {string} [options.label='']
- * The menu label for this track.
- *
- * @param {string} [options.language='']
- * A valid two character language code.
- *
- * @param {boolean} [options.selected]
- * If this track is the one that is currently playing.
- */
- function VideoTrack() {
- var _this, _ret;
-
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- classCallCheck(this, VideoTrack);
-
- var settings = mergeOptions(options, {
- kind: VideoTrackKind[options.kind] || ''
- });
-
- // on IE8 this will be a document element
- // for every other browser this will be a normal object
- var track = (_this = possibleConstructorReturn(this, _Track.call(this, settings)), _this);
- var selected = false;
-
- if (IS_IE8) {
- for (var prop in VideoTrack.prototype) {
- if (prop !== 'constructor') {
- track[prop] = VideoTrack.prototype[prop];
- }
- }
- }
-
- /**
- * @memberof VideoTrack
- * @member {boolean} selected
- * If this `VideoTrack` is selected or not. When setting this will
- * fire {@link VideoTrack#selectedchange} if the state of selected changed.
- * @instance
- *
- * @fires VideoTrack#selectedchange
- */
- Object.defineProperty(track, 'selected', {
- get: function get$$1() {
- return selected;
- },
- set: function set$$1(newSelected) {
- // an invalid or unchanged value
- if (typeof newSelected !== 'boolean' || newSelected === selected) {
- return;
- }
- selected = newSelected;
-
- /**
- * An event that fires when selected changes on this track. This allows
- * the VideoTrackList that holds this track to act accordingly.
- *
- * > Note: This is not part of the spec! Native tracks will do
- * this internally without an event.
- *
- * @event VideoTrack#selectedchange
- * @type {EventTarget~Event}
- */
- this.trigger('selectedchange');
- }
- });
-
- // if the user sets this track to selected then
- // set selected to that true value otherwise
- // we keep it false
- if (settings.selected) {
- track.selected = settings.selected;
- }
-
- return _ret = track, possibleConstructorReturn(_this, _ret);
- }
-
- return VideoTrack;
- }(Track);
-
- /**
- * @file html-track-element.js
- */
-
- /**
- * @memberof HTMLTrackElement
- * @typedef {HTMLTrackElement~ReadyState}
- * @enum {number}
- */
- var NONE = 0;
- var LOADING = 1;
- var LOADED = 2;
- var ERROR = 3;
-
- /**
- * A single track represented in the DOM.
- *
- * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement}
- * @extends EventTarget
- */
-
- var HTMLTrackElement = function (_EventTarget) {
- inherits(HTMLTrackElement, _EventTarget);
-
- /**
- * Create an instance of this class.
- *
- * @param {Object} options={}
- * Object of option names and values
- *
- * @param {Tech} options.tech
- * A reference to the tech that owns this HTMLTrackElement.
- *
- * @param {TextTrack~Kind} [options.kind='subtitles']
- * A valid text track kind.
- *
- * @param {TextTrack~Mode} [options.mode='disabled']
- * A valid text track mode.
- *
- * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
- * A unique id for this TextTrack.
- *
- * @param {string} [options.label='']
- * The menu label for this track.
- *
- * @param {string} [options.language='']
- * A valid two character language code.
- *
- * @param {string} [options.srclang='']
- * A valid two character language code. An alternative, but deprioritized
- * vesion of `options.language`
- *
- * @param {string} [options.src]
- * A url to TextTrack cues.
- *
- * @param {boolean} [options.default]
- * If this track should default to on or off.
- */
- function HTMLTrackElement() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- classCallCheck(this, HTMLTrackElement);
-
- var _this = possibleConstructorReturn(this, _EventTarget.call(this));
-
- var readyState = void 0;
- var trackElement = _this; // eslint-disable-line
-
- if (IS_IE8) {
- trackElement = document_1.createElement('custom');
-
- for (var prop in HTMLTrackElement.prototype) {
- if (prop !== 'constructor') {
- trackElement[prop] = HTMLTrackElement.prototype[prop];
- }
- }
- }
-
- var track = new TextTrack(options);
-
- trackElement.kind = track.kind;
- trackElement.src = track.src;
- trackElement.srclang = track.language;
- trackElement.label = track.label;
- trackElement['default'] = track['default'];
-
- /**
- * @memberof HTMLTrackElement
- * @member {HTMLTrackElement~ReadyState} readyState
- * The current ready state of the track element.
- * @instance
- */
- Object.defineProperty(trackElement, 'readyState', {
- get: function get$$1() {
- return readyState;
- }
- });
-
- /**
- * @memberof HTMLTrackElement
- * @member {TextTrack} track
- * The underlying TextTrack object.
- * @instance
- *
- */
- Object.defineProperty(trackElement, 'track', {
- get: function get$$1() {
- return track;
- }
- });
-
- readyState = NONE;
-
- /**
- * @listens TextTrack#loadeddata
- * @fires HTMLTrackElement#load
- */
- track.addEventListener('loadeddata', function () {
- readyState = LOADED;
-
- trackElement.trigger({
- type: 'load',
- target: trackElement
- });
- });
-
- if (IS_IE8) {
- var _ret;
-
- return _ret = trackElement, possibleConstructorReturn(_this, _ret);
- }
- return _this;
- }
-
- return HTMLTrackElement;
- }(EventTarget);
-
- HTMLTrackElement.prototype.allowedEvents_ = {
- load: 'load'
- };
-
- HTMLTrackElement.NONE = NONE;
- HTMLTrackElement.LOADING = LOADING;
- HTMLTrackElement.LOADED = LOADED;
- HTMLTrackElement.ERROR = ERROR;
-
- /*
- * This file contains all track properties that are used in
- * player.js, tech.js, html5.js and possibly other techs in the future.
- */
-
- var NORMAL = {
- audio: {
- ListClass: AudioTrackList,
- TrackClass: AudioTrack,
- capitalName: 'Audio'
- },
- video: {
- ListClass: VideoTrackList,
- TrackClass: VideoTrack,
- capitalName: 'Video'
- },
- text: {
- ListClass: TextTrackList,
- TrackClass: TextTrack,
- capitalName: 'Text'
- }
- };
-
- Object.keys(NORMAL).forEach(function (type) {
- NORMAL[type].getterName = type + 'Tracks';
- NORMAL[type].privateName = type + 'Tracks_';
- });
-
- var REMOTE = {
- remoteText: {
- ListClass: TextTrackList,
- TrackClass: TextTrack,
- capitalName: 'RemoteText',
- getterName: 'remoteTextTracks',
- privateName: 'remoteTextTracks_'
- },
- remoteTextEl: {
- ListClass: HtmlTrackElementList,
- TrackClass: HTMLTrackElement,
- capitalName: 'RemoteTextTrackEls',
- getterName: 'remoteTextTrackEls',
- privateName: 'remoteTextTrackEls_'
- }
- };
-
- var ALL = mergeOptions(NORMAL, REMOTE);
-
- REMOTE.names = Object.keys(REMOTE);
- NORMAL.names = Object.keys(NORMAL);
- ALL.names = [].concat(REMOTE.names).concat(NORMAL.names);
-
- /**
- * 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: */
- 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 = {
- "&": "&",
- "<": "<",
- ">": ">",
- "‎": "\u200e",
- "‏": "\u200f",
- " ": "\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 strongRTLRanges = [[0x5be, 0x5be], [0x5c0, 0x5c0], [0x5c3, 0x5c3], [0x5c6, 0x5c6],
- [0x5d0, 0x5ea], [0x5f0, 0x5f4], [0x608, 0x608], [0x60b, 0x60b], [0x60d, 0x60d],
- [0x61b, 0x61b], [0x61e, 0x64a], [0x66d, 0x66f], [0x671, 0x6d5], [0x6e5, 0x6e6],
- [0x6ee, 0x6ef], [0x6fa, 0x70d], [0x70f, 0x710], [0x712, 0x72f], [0x74d, 0x7a5],
- [0x7b1, 0x7b1], [0x7c0, 0x7ea], [0x7f4, 0x7f5], [0x7fa, 0x7fa], [0x800, 0x815],
- [0x81a, 0x81a], [0x824, 0x824], [0x828, 0x828], [0x830, 0x83e], [0x840, 0x858],
- [0x85e, 0x85e], [0x8a0, 0x8a0], [0x8a2, 0x8ac], [0x200f, 0x200f],
- [0xfb1d, 0xfb1d], [0xfb1f, 0xfb28], [0xfb2a, 0xfb36], [0xfb38, 0xfb3c],
- [0xfb3e, 0xfb3e], [0xfb40, 0xfb41], [0xfb43, 0xfb44], [0xfb46, 0xfbc1],
- [0xfbd3, 0xfd3d], [0xfd50, 0xfd8f], [0xfd92, 0xfdc7], [0xfdf0, 0xfdfc],
- [0xfe70, 0xfe74], [0xfe76, 0xfefc], [0x10800, 0x10805], [0x10808, 0x10808],
- [0x1080a, 0x10835], [0x10837, 0x10838], [0x1083c, 0x1083c], [0x1083f, 0x10855],
- [0x10857, 0x1085f], [0x10900, 0x1091b], [0x10920, 0x10939], [0x1093f, 0x1093f],
- [0x10980, 0x109b7], [0x109be, 0x109bf], [0x10a00, 0x10a00], [0x10a10, 0x10a13],
- [0x10a15, 0x10a17], [0x10a19, 0x10a33], [0x10a40, 0x10a47], [0x10a50, 0x10a58],
- [0x10a60, 0x10a7f], [0x10b00, 0x10b35], [0x10b40, 0x10b55], [0x10b58, 0x10b72],
- [0x10b78, 0x10b7f], [0x10c00, 0x10c48], [0x1ee00, 0x1ee03], [0x1ee05, 0x1ee1f],
- [0x1ee21, 0x1ee22], [0x1ee24, 0x1ee24], [0x1ee27, 0x1ee27], [0x1ee29, 0x1ee32],
- [0x1ee34, 0x1ee37], [0x1ee39, 0x1ee39], [0x1ee3b, 0x1ee3b], [0x1ee42, 0x1ee42],
- [0x1ee47, 0x1ee47], [0x1ee49, 0x1ee49], [0x1ee4b, 0x1ee4b], [0x1ee4d, 0x1ee4f],
- [0x1ee51, 0x1ee52], [0x1ee54, 0x1ee54], [0x1ee57, 0x1ee57], [0x1ee59, 0x1ee59],
- [0x1ee5b, 0x1ee5b], [0x1ee5d, 0x1ee5d], [0x1ee5f, 0x1ee5f], [0x1ee61, 0x1ee62],
- [0x1ee64, 0x1ee64], [0x1ee67, 0x1ee6a], [0x1ee6c, 0x1ee72], [0x1ee74, 0x1ee77],
- [0x1ee79, 0x1ee7c], [0x1ee7e, 0x1ee7e], [0x1ee80, 0x1ee89], [0x1ee8b, 0x1ee9b],
- [0x1eea1, 0x1eea3], [0x1eea5, 0x1eea9], [0x1eeab, 0x1eebb], [0x10fffd, 0x10fffd]];
-
- function isStrongRTLChar(charCode) {
- for (var i = 0; i < strongRTLRanges.length; i++) {
- var currentRange = strongRTLRanges[i];
- if (charCode >= currentRange[0] && charCode <= currentRange[1]) {
- return true;
- }
- }
-
- return false;
- }
-
- 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);
- if (isStrongRTLChar(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$1() {
- // Nothing
- }
-
-// Helper to allow strings to be decoded instead of the default binary utf8 data.
- WebVTT$1.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$1.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$1.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$1.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$1.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
- });
- }
- }
-
- // draft-pantos-http-live-streaming-20
- // https://tools.ietf.org/html/draft-pantos-http-live-streaming-20#section-3.5
- // 3.5 WebVTT
- function parseTimestampMap(input) {
- var settings = new Settings();
-
- parseOptions(input, function (k, v) {
- switch (k) {
- case "MPEGT":
- settings.integer(k + 'S', v);
- break;
- case "LOCA":
- settings.set(k + 'L', parseTimeStamp(v));
- break;
- }
- }, /[^\d]:/, /,/);
-
- self.ontimestampmap && self.ontimestampmap({
- "MPEGTS": settings.get("MPEGTS"),
- "LOCAL": settings.get("LOCAL")
- });
- }
-
- // 3.2 WebVTT metadata header syntax
- function parseHeader(input) {
- if (input.match(/X-TIMESTAMP-MAP/)) {
- // This line contains HLS X-TIMESTAMP-MAP metadata
- parseOptions(input, function (k, v) {
- switch (k) {
- case "X-TIMESTAMP-MAP":
- parseTimestampMap(v);
- break;
- }
- }, /=/);
- } else {
- 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;
- }
- };
-
- var vtt$1 = WebVTT$1;
-
- /**
- * 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.
- */
-
- 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$1(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$1({}, baseObj, {
- get: function () {
- return _id;
- },
- set: function (value) {
- _id = "" + value;
- }
- }));
-
- Object.defineProperty(cue,
- "pauseOnExit", extend$1({}, baseObj, {
- get: function () {
- return _pauseOnExit;
- },
- set: function (value) {
- _pauseOnExit = !!value;
- }
- }));
-
- Object.defineProperty(cue,
- "startTime", extend$1({}, 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$1({}, 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$1({}, baseObj, {
- get: function () {
- return _text;
- },
- set: function (value) {
- _text = "" + value;
- this.hasBeenReset = true;
- }
- }));
-
- Object.defineProperty(cue,
- "region", extend$1({}, baseObj, {
- get: function () {
- return _region;
- },
- set: function (value) {
- _region = value;
- this.hasBeenReset = true;
- }
- }));
-
- Object.defineProperty(cue,
- "vertical", extend$1({}, 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$1({}, baseObj, {
- get: function () {
- return _snapToLines;
- },
- set: function (value) {
- _snapToLines = !!value;
- this.hasBeenReset = true;
- }
- }));
-
- Object.defineProperty(cue,
- "line", extend$1({}, 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$1({}, 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$1({}, 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$1({}, 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$1({}, 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$1({}, 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);
- };
-
- var vttcue = VTTCue;
-
- /**
- * 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.
- */
-
- 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;
- }
- }
- });
- }
-
- var vttregion = VTTRegion;
-
- var browserIndex = createCommonjsModule(function (module) {
- /**
- * 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.
- */
-
-// Default exports for Node. Export the extended versions of VTTCue and
-// VTTRegion in Node since we likely want the capability to convert back and
-// forth between JSON. If we don't then it's not that big of a deal since we're
-// off browser.
-
-
- var vttjs = module.exports = {
- WebVTT: vtt$1,
- VTTCue: vttcue,
- VTTRegion: vttregion
- };
-
- window_1.vttjs = vttjs;
- window_1.WebVTT = vttjs.WebVTT;
-
- var cueShim = vttjs.VTTCue;
- var regionShim = vttjs.VTTRegion;
- var nativeVTTCue = window_1.VTTCue;
- var nativeVTTRegion = window_1.VTTRegion;
-
- vttjs.shim = function () {
- window_1.VTTCue = cueShim;
- window_1.VTTRegion = regionShim;
- };
-
- vttjs.restore = function () {
- window_1.VTTCue = nativeVTTCue;
- window_1.VTTRegion = nativeVTTRegion;
- };
-
- if (!window_1.VTTCue) {
- vttjs.shim();
- }
- });
-
- /**
- * @file tech.js
- */
-
- /**
- * An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string
- * that just contains the src url alone.
- * * `var SourceObject = {src: 'http://ex.com/video.mp4', type: 'video/mp4'};`
- * `var SourceString = 'http://example.com/some-video.mp4';`
- *
- * @typedef {Object|string} Tech~SourceObject
- *
- * @property {string} src
- * The url to the source
- *
- * @property {string} type
- * The mime type of the source
- */
-
- /**
- * A function used by {@link Tech} to create a new {@link TextTrack}.
- *
- * @private
- *
- * @param {Tech} self
- * An instance of the Tech class.
- *
- * @param {string} kind
- * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
- *
- * @param {string} [label]
- * Label to identify the text track
- *
- * @param {string} [language]
- * Two letter language abbreviation
- *
- * @param {Object} [options={}]
- * An object with additional text track options
- *
- * @return {TextTrack}
- * The text track that was created.
- */
- 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 ALL.text.TrackClass(options);
-
- tracks.addTrack(track);
-
- return track;
- }
-
- /**
- * This is the base class for media playback technology controllers, such as
- * {@link Flash} and {@link HTML5}
- *
- * @extends Component
- */
-
- var Tech = function (_Component) {
- inherits(Tech, _Component);
-
- /**
- * Create an instance of this Tech.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- *
- * @param {Component~ReadyCallback} ready
- * Callback function to call when the `HTML5` Tech is ready.
- */
- function Tech() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- var ready = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {
- };
- classCallCheck(this, Tech);
-
- // we don't want the tech to report user activity automatically.
- // This is done manually in addControlsListeners
- options.reportTouchActivity = false;
-
- // keep track of whether the current source has played at all to
- // implement a very limited played()
- var _this = possibleConstructorReturn(this, _Component.call(this, null, options, ready));
-
- _this.hasStarted_ = false;
- _this.on('playing', function () {
- this.hasStarted_ = true;
- });
- _this.on('loadstart', function () {
- this.hasStarted_ = false;
- });
-
- ALL.names.forEach(function (name) {
- var props = ALL[name];
-
- if (options && options[props.getterName]) {
- _this[props.privateName] = options[props.getterName];
- }
- });
-
- // 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();
- }
-
- ['Text', 'Audio', 'Video'].forEach(function (track) {
- if (options['native' + track + 'Tracks'] === false) {
- _this['featuresNative' + track + 'Tracks'] = false;
- }
- });
-
- if (options.nativeCaptions === false || options.nativeTextTracks === false) {
- _this.featuresNativeTextTracks = false;
- } else if (options.nativeCaptions === true || options.nativeTextTracks === true) {
- _this.featuresNativeTextTracks = true;
- }
-
- if (!_this.featuresNativeTextTracks) {
- _this.emulateTextTracks();
- }
-
- _this.autoRemoteTextTracks_ = new ALL.text.ListClass();
-
- _this.initTrackListeners();
-
- // Turn on component tap events only if not using native controls
- if (!options.nativeControlsForTouch) {
- _this.emitTapEvents();
- }
-
- if (_this.constructor) {
- _this.name_ = _this.constructor.name || 'Unknown Tech';
- }
- return _this;
- }
-
- /* Fallbacks for unsupported event types
- ================================================================================ */
-
- /**
- * Polyfill the `progress` event for browsers that don't support it natively.
- *
- * @see {@link Tech#trackProgress}
- */
-
-
- 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 the polyfill for `progress` events that was created in
- * {@link Tech#manualProgressOn}
- */
-
-
- Tech.prototype.manualProgressOff = function manualProgressOff() {
- this.manualProgress = false;
- this.stopTrackingProgress();
-
- this.off('durationchange', this.onDurationChange);
- };
-
- /**
- * This is used to trigger a `progress` event when the buffered percent changes. It
- * sets an interval function that will be called every 500 milliseconds to check if the
- * buffer end percent has changed.
- *
- * > This function is called by {@link Tech#manualProgressOn}
- *
- * @param {EventTarget~Event} event
- * The `ready` event that caused this to run.
- *
- * @listens Tech#ready
- * @fires Tech#progress
- */
-
-
- Tech.prototype.trackProgress = function trackProgress(event) {
- this.stopTrackingProgress();
- this.progressInterval = this.setInterval(bind(this, function () {
- // Don't trigger unless buffered amount is greater than last time
-
- var numBufferedPercent = this.bufferedPercent();
-
- if (this.bufferedPercent_ !== numBufferedPercent) {
- /**
- * See {@link Player#progress}
- *
- * @event Tech#progress
- * @type {EventTarget~Event}
- */
- this.trigger('progress');
- }
-
- this.bufferedPercent_ = numBufferedPercent;
-
- if (numBufferedPercent === 1) {
- this.stopTrackingProgress();
- }
- }), 500);
- };
-
- /**
- * Update our internal duration on a `durationchange` event by calling
- * {@link Tech#duration}.
- *
- * @param {EventTarget~Event} event
- * The `durationchange` event that caused this to run.
- *
- * @listens Tech#durationchange
- */
-
-
- Tech.prototype.onDurationChange = function onDurationChange(event) {
- this.duration_ = this.duration();
- };
-
- /**
- * Get and create a `TimeRange` object for buffering.
- *
- * @return {TimeRange}
- * The time range object that was created.
- */
-
-
- Tech.prototype.buffered = function buffered() {
- return createTimeRanges(0, 0);
- };
-
- /**
- * Get the percentage of the current video that is currently buffered.
- *
- * @return {number}
- * A number from 0 to 1 that represents the decimal percentage of the
- * video that is buffered.
- *
- */
-
-
- Tech.prototype.bufferedPercent = function bufferedPercent$$1() {
- return bufferedPercent(this.buffered(), this.duration_);
- };
-
- /**
- * Turn off the polyfill for `progress` events that was created in
- * {@link Tech#manualProgressOn}
- * Stop manually tracking progress events by clearing the interval that was set in
- * {@link Tech#trackProgress}.
- */
-
-
- Tech.prototype.stopTrackingProgress = function stopTrackingProgress() {
- this.clearInterval(this.progressInterval);
- };
-
- /**
- * Polyfill the `timeupdate` event for browsers that don't support it.
- *
- * @see {@link Tech#trackCurrentTime}
- */
-
-
- Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() {
- this.manualTimeUpdates = true;
-
- this.on('play', this.trackCurrentTime);
- this.on('pause', this.stopTrackingCurrentTime);
- };
-
- /**
- * Turn off the polyfill for `timeupdate` events that was created in
- * {@link Tech#manualTimeUpdatesOn}
- */
-
-
- Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() {
- this.manualTimeUpdates = false;
- this.stopTrackingCurrentTime();
- this.off('play', this.trackCurrentTime);
- this.off('pause', this.stopTrackingCurrentTime);
- };
-
- /**
- * Sets up an interval function to track current time and trigger `timeupdate` every
- * 250 milliseconds.
- *
- * @listens Tech#play
- * @triggers Tech#timeupdate
- */
-
-
- Tech.prototype.trackCurrentTime = function trackCurrentTime() {
- if (this.currentTimeInterval) {
- this.stopTrackingCurrentTime();
- }
- this.currentTimeInterval = this.setInterval(function () {
- /**
- * Triggered at an interval of 250ms to indicated that time is passing in the video.
- *
- * @event Tech#timeupdate
- * @type {EventTarget~Event}
- */
- this.trigger({type: 'timeupdate', target: this, manuallyTriggered: true});
-
- // 42 = 24 fps // 250 is what Webkit uses // FF uses 15
- }, 250);
- };
-
- /**
- * Stop the interval function created in {@link Tech#trackCurrentTime} so that the
- * `timeupdate` event is no longer triggered.
- *
- * @listens {Tech#pause}
- */
-
-
- 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 all event polyfills, clear the `Tech`s {@link AudioTrackList},
- * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech.
- *
- * @fires Component#dispose
- */
-
-
- Tech.prototype.dispose = function dispose() {
-
- // clear out all tracks because we can't reuse them between techs
- this.clearTracks(NORMAL.names);
-
- // Turn off any manual progress or timeupdate tracking
- if (this.manualProgress) {
- this.manualProgressOff();
- }
-
- if (this.manualTimeUpdates) {
- this.manualTimeUpdatesOff();
- }
-
- _Component.prototype.dispose.call(this);
- };
-
- /**
- * Clear out a single `TrackList` or an array of `TrackLists` given their names.
- *
- * > Note: Techs without source handlers should call this between sources for `video`
- * & `audio` tracks. You don't want to use them between tracks!
- *
- * @param {string[]|string} types
- * TrackList names to clear, valid names are `video`, `audio`, and
- * `text`.
- */
-
-
- Tech.prototype.clearTracks = function clearTracks(types) {
- var _this2 = this;
-
- types = [].concat(types);
- // clear out all tracks because we can't reuse them between techs
- types.forEach(function (type) {
- var list = _this2[type + 'Tracks']() || [];
- var i = list.length;
-
- while (i--) {
- var track = list[i];
-
- if (type === 'text') {
- _this2.removeRemoteTextTrack(track);
- }
- list.removeTrack(track);
- }
- });
- };
-
- /**
- * Remove any TextTracks added via addRemoteTextTrack that are
- * flagged for automatic garbage collection
- */
-
-
- Tech.prototype.cleanupAutoTextTracks = function cleanupAutoTextTracks() {
- var list = this.autoRemoteTextTracks_ || [];
- var i = list.length;
-
- while (i--) {
- var track = list[i];
-
- this.removeRemoteTextTrack(track);
- }
- };
-
- /**
- * Reset the tech, which will removes all sources and reset the internal readyState.
- *
- * @abstract
- */
-
-
- Tech.prototype.reset = function reset() {
- };
-
- /**
- * Get or set an error on the Tech.
- *
- * @param {MediaError} [err]
- * Error to set on the Tech
- *
- * @return {MediaError|null}
- * The current error object on the tech, or null if there isn't one.
- */
-
-
- Tech.prototype.error = function error(err) {
- if (err !== undefined) {
- this.error_ = new MediaError(err);
- this.trigger('error');
- }
- return this.error_;
- };
-
- /**
- * Returns the `TimeRange`s that have been played through for the current source.
- *
- * > NOTE: This implementation is incomplete. It does not track the played `TimeRange`.
- * It only checks wether the source has played at all or not.
- *
- * @return {TimeRange}
- * - A single time range if this video has played
- * - An empty set of ranges if not.
- */
-
-
- Tech.prototype.played = function played() {
- if (this.hasStarted_) {
- return createTimeRanges(0, 0);
- }
- return createTimeRanges();
- };
-
- /**
- * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was
- * previously called.
- *
- * @fires Tech#timeupdate
- */
-
-
- Tech.prototype.setCurrentTime = function setCurrentTime() {
- // improve the accuracy of manual timeupdates
- if (this.manualTimeUpdates) {
- /**
- * A manual `timeupdate` event.
- *
- * @event Tech#timeupdate
- * @type {EventTarget~Event}
- */
- this.trigger({type: 'timeupdate', target: this, manuallyTriggered: true});
- }
- };
-
- /**
- * Turn on listeners for {@link VideoTrackList}, {@link {AudioTrackList}, and
- * {@link TextTrackList} events.
- *
- * This adds {@link EventTarget~EventListeners} for `addtrack`, and `removetrack`.
- *
- * @fires Tech#audiotrackchange
- * @fires Tech#videotrackchange
- * @fires Tech#texttrackchange
- */
-
-
- Tech.prototype.initTrackListeners = function initTrackListeners() {
- var _this3 = this;
-
- /**
- * Triggered when tracks are added or removed on the Tech {@link AudioTrackList}
- *
- * @event Tech#audiotrackchange
- * @type {EventTarget~Event}
- */
-
- /**
- * Triggered when tracks are added or removed on the Tech {@link VideoTrackList}
- *
- * @event Tech#videotrackchange
- * @type {EventTarget~Event}
- */
-
- /**
- * Triggered when tracks are added or removed on the Tech {@link TextTrackList}
- *
- * @event Tech#texttrackchange
- * @type {EventTarget~Event}
- */
- NORMAL.names.forEach(function (name) {
- var props = NORMAL[name];
- var trackListChanges = function trackListChanges() {
- _this3.trigger(name + 'trackchange');
- };
-
- var tracks = _this3[props.getterName]();
-
- tracks.addEventListener('removetrack', trackListChanges);
- tracks.addEventListener('addtrack', trackListChanges);
-
- _this3.on('dispose', function () {
- tracks.removeEventListener('removetrack', trackListChanges);
- tracks.removeEventListener('addtrack', trackListChanges);
- });
- });
- };
-
- /**
- * Emulate TextTracks using vtt.js if necessary
- *
- * @fires Tech#vttjsloaded
- * @fires Tech#vttjserror
- */
-
-
- Tech.prototype.addWebVttScript_ = function addWebVttScript_() {
- var _this4 = this;
-
- if (window_1.WebVTT) {
- return;
- }
-
- // Initially, Tech.el_ is a child of a dummy-div wait until the Component system
- // signals that the Tech is ready at which point Tech.el_ is part of the DOM
- // before inserting the WebVTT script
- if (document_1.body.contains(this.el())) {
-
- // load via require if available and vtt.js script location was not passed in
- // as an option. novtt builds will turn the above require call into an empty object
- // which will cause this if check to always fail.
- if (!this.options_['vtt.js'] && isPlain(browserIndex) && Object.keys(browserIndex).length > 0) {
- this.trigger('vttjsloaded');
- return;
- }
-
- // load vtt.js via the script location option or the cdn of no location was
- // passed in
- var script = document_1.createElement('script');
-
- script.src = this.options_['vtt.js'] || 'https://vjs.zencdn.net/vttjs/0.12.4/vtt.min.js';
- script.onload = function () {
- /**
- * Fired when vtt.js is loaded.
- *
- * @event Tech#vttjsloaded
- * @type {EventTarget~Event}
- */
- _this4.trigger('vttjsloaded');
- };
- script.onerror = function () {
- /**
- * Fired when vtt.js was not loaded due to an error
- *
- * @event Tech#vttjsloaded
- * @type {EventTarget~Event}
- */
- _this4.trigger('vttjserror');
- };
- this.on('dispose', function () {
- script.onload = null;
- script.onerror = null;
- });
- // but have not loaded yet and we set it to true before the inject so that
- // we don't overwrite the injected window.WebVTT if it loads right away
- window_1.WebVTT = true;
- this.el().parentNode.appendChild(script);
- } else {
- this.ready(this.addWebVttScript_);
- }
- };
-
- /**
- * Emulate texttracks
- *
- */
-
-
- Tech.prototype.emulateTextTracks = function emulateTextTracks() {
- var _this5 = this;
-
- var tracks = this.textTracks();
- var remoteTracks = this.remoteTextTracks();
- var handleAddTrack = function handleAddTrack(e) {
- return tracks.addTrack(e.track);
- };
- var handleRemoveTrack = function handleRemoveTrack(e) {
- return tracks.removeTrack(e.track);
- };
-
- remoteTracks.on('addtrack', handleAddTrack);
- remoteTracks.on('removetrack', handleRemoveTrack);
-
- this.addWebVttScript_();
-
- var updateDisplay = function updateDisplay() {
- return _this5.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);
- tracks.addEventListener('addtrack', textTracksChanges);
- tracks.addEventListener('removetrack', textTracksChanges);
-
- this.on('dispose', function () {
- remoteTracks.off('addtrack', handleAddTrack);
- remoteTracks.off('removetrack', handleRemoveTrack);
- tracks.removeEventListener('change', textTracksChanges);
- tracks.removeEventListener('addtrack', textTracksChanges);
- tracks.removeEventListener('removetrack', textTracksChanges);
-
- for (var i = 0; i < tracks.length; i++) {
- var track = tracks[i];
-
- track.removeEventListener('cuechange', updateDisplay);
- }
- });
- };
-
- /**
- * Create and returns a remote {@link TextTrack} object.
- *
- * @param {string} kind
- * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
- *
- * @param {string} [label]
- * Label to identify the text track
- *
- * @param {string} [language]
- * Two letter language abbreviation
- *
- * @return {TextTrack}
- * The TextTrack that gets created.
- */
-
-
- 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);
- };
-
- /**
- * Create an emulated TextTrack for use by addRemoteTextTrack
- *
- * This is intended to be overridden by classes that inherit from
- * Tech in order to create native or custom TextTracks.
- *
- * @param {Object} options
- * The object should contain the options to initialize the TextTrack with.
- *
- * @param {string} [options.kind]
- * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
- *
- * @param {string} [options.label].
- * Label to identify the text track
- *
- * @param {string} [options.language]
- * Two letter language abbreviation.
- *
- * @return {HTMLTrackElement}
- * The track element that gets created.
- */
-
-
- Tech.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) {
- var track = mergeOptions(options, {
- tech: this
- });
-
- return new REMOTE.remoteTextEl.TrackClass(track);
- };
-
- /**
- * Creates a remote text track object and returns an html track element.
- *
- * > Note: This can be an emulated {@link HTMLTrackElement} or a native one.
- *
- * @param {Object} options
- * See {@link Tech#createRemoteTextTrack} for more detailed properties.
- *
- * @param {boolean} [manualCleanup=true]
- * - When false: the TextTrack will be automatically removed from the video
- * element whenever the source changes
- * - When True: The TextTrack will have to be cleaned up manually
- *
- * @return {HTMLTrackElement}
- * An Html Track Element.
- *
- * @deprecated The default functionality for this function will be equivalent
- * to "manualCleanup=false" in the future. The manualCleanup parameter will
- * also be removed.
- */
-
-
- Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack() {
- var _this6 = this;
-
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- var manualCleanup = arguments[1];
-
- var htmlTrackElement = this.createRemoteTextTrack(options);
-
- if (manualCleanup !== true && manualCleanup !== false) {
- // deprecation warning
- log$1.warn('Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js');
- manualCleanup = true;
- }
-
- // store HTMLTrackElement and TextTrack to remote list
- this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
- this.remoteTextTracks().addTrack(htmlTrackElement.track);
-
- if (manualCleanup !== true) {
- // create the TextTrackList if it doesn't exist
- this.ready(function () {
- return _this6.autoRemoteTextTracks_.addTrack(htmlTrackElement.track);
- });
- }
-
- return htmlTrackElement;
- };
-
- /**
- * Remove a remote text track from the remote `TextTrackList`.
- *
- * @param {TextTrack} track
- * `TextTrack` to remove from the `TextTrackList`
- */
-
-
- Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
- var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
-
- // remove HTMLTrackElement and TextTrack from remote list
- this.remoteTextTrackEls().removeTrackElement_(trackElement);
- this.remoteTextTracks().removeTrack(track);
- this.autoRemoteTextTracks_.removeTrack(track);
- };
-
- /**
- * Gets available media playback quality metrics as specified by the W3C's Media
- * Playback Quality API.
- *
- * @see [Spec]{@link https://wicg.github.io/media-playback-quality}
- *
- * @return {Object}
- * An object with supported media playback quality metrics
- *
- * @abstract
- */
-
-
- Tech.prototype.getVideoPlaybackQuality = function getVideoPlaybackQuality() {
- return {};
- };
-
- /**
- * A method to set a poster from a `Tech`.
- *
- * @abstract
- */
-
-
- Tech.prototype.setPoster = function setPoster() {
- };
-
- /**
- * A method to check for the presence of the 'playsinine' <video> attribute.
- *
- * @abstract
- */
-
-
- Tech.prototype.playsinline = function playsinline() {
- };
-
- /**
- * A method to set or unset the 'playsinine' <video> attribute.
- *
- * @abstract
- */
-
-
- Tech.prototype.setPlaysinline = function setPlaysinline() {
- };
-
- /*
- * Check if the tech can support the given mime-type.
- *
- * The base tech does not support any type, but source handlers might
- * overwrite this.
- *
- * @param {string} type
- * The mimetype to check for support
- *
- * @return {string}
- * 'probably', 'maybe', or empty string
- *
- * @see [Spec]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType}
- *
- * @abstract
- */
-
-
- Tech.prototype.canPlayType = function canPlayType() {
- return '';
- };
-
- /**
- * Check if the type is supported by this tech.
- *
- * The base tech does not support any type, but source handlers might
- * overwrite this.
- *
- * @param {string} type
- * The media type to check
- * @return {string} Returns the native video element's response
- */
-
-
- Tech.canPlayType = function canPlayType() {
- return '';
- };
-
- /**
- * Check if the tech can support the given source
- * @param {Object} srcObj
- * The source object
- * @param {Object} options
- * The options passed to the tech
- * @return {string} 'probably', 'maybe', or '' (empty string)
- */
-
-
- Tech.canPlaySource = function canPlaySource(srcObj, options) {
- return Tech.canPlayType(srcObj.type);
- };
-
- /*
- * 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
- * The item to check
- *
- * @return {boolean}
- * Whether it is a tech or not
- * - True if it is a tech
- * - False if it is not
- */
-
-
- Tech.isTech = function isTech(component) {
- return component.prototype instanceof Tech || component instanceof Tech || component === Tech;
- };
-
- /**
- * Registers a `Tech` into a shared list for videojs.
- *
- * @param {string} name
- * Name of the `Tech` to register.
- *
- * @param {Object} tech
- * The `Tech` class to register.
- */
-
-
- Tech.registerTech = function registerTech(name, tech) {
- if (!Tech.techs_) {
- Tech.techs_ = {};
- }
-
- if (!Tech.isTech(tech)) {
- throw new Error('Tech ' + name + ' must be a Tech');
- }
-
- if (!Tech.canPlayType) {
- throw new Error('Techs must have a static canPlayType method on them');
- }
- if (!Tech.canPlaySource) {
- throw new Error('Techs must have a static canPlaySource method on them');
- }
-
- name = toTitleCase(name);
-
- Tech.techs_[name] = tech;
- if (name !== 'Tech') {
- // camel case the techName for use in techOrder
- Tech.defaultTechOrder_.push(name);
- }
- return tech;
- };
-
- /**
- * Get a `Tech` from the shared list by name.
- *
- * @param {string} name
- * `camelCase` or `TitleCase` name of the Tech to get
- *
- * @return {Tech|undefined}
- * The `Tech` or undefined if there was no tech with the name requsted.
- */
-
-
- Tech.getTech = function getTech(name) {
- if (!name) {
- return;
- }
-
- name = toTitleCase(name);
-
- if (Tech.techs_ && Tech.techs_[name]) {
- return Tech.techs_[name];
- }
-
- if (window_1 && window_1.videojs && window_1.videojs[name]) {
- log$1.warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)');
- return window_1.videojs[name];
- }
- };
-
- return Tech;
- }(Component);
-
- /**
- * Get the {@link VideoTrackList}
- *
- * @returns {VideoTrackList}
- * @method Tech.prototype.videoTracks
- */
-
- /**
- * Get the {@link AudioTrackList}
- *
- * @returns {AudioTrackList}
- * @method Tech.prototype.audioTracks
- */
-
- /**
- * Get the {@link TextTrackList}
- *
- * @returns {TextTrackList}
- * @method Tech.prototype.textTracks
- */
-
- /**
- * Get the remote element {@link TextTrackList}
- *
- * @returns {TextTrackList}
- * @method Tech.prototype.remoteTextTracks
- */
-
- /**
- * Get the remote element {@link HtmlTrackElementList}
- *
- * @returns {HtmlTrackElementList}
- * @method Tech.prototype.remoteTextTrackEls
- */
-
- ALL.names.forEach(function (name) {
- var props = ALL[name];
-
- Tech.prototype[props.getterName] = function () {
- this[props.privateName] = this[props.privateName] || new props.ListClass();
- return this[props.privateName];
- };
- });
-
- /**
- * List of associated text tracks
- *
- * @type {TextTrackList}
- * @private
- * @property Tech#textTracks_
- */
-
- /**
- * List of associated audio tracks.
- *
- * @type {AudioTrackList}
- * @private
- * @property Tech#audioTracks_
- */
-
- /**
- * List of associated video tracks.
- *
- * @type {VideoTrackList}
- * @private
- * @property Tech#videoTracks_
- */
-
- /**
- * Boolean indicating wether the `Tech` supports volume control.
- *
- * @type {boolean}
- * @default
- */
- Tech.prototype.featuresVolumeControl = true;
-
- /**
- * Boolean indicating wether the `Tech` support fullscreen resize control.
- * Resizing plugins using request fullscreen reloads the plugin
- *
- * @type {boolean}
- * @default
- */
- Tech.prototype.featuresFullscreenResize = false;
-
- /**
- * Boolean indicating wether the `Tech` supports changing the speed at which the video
- * plays. Examples:
- * - Set player to play 2x (twice) as fast
- * - Set player to play 0.5x (half) as fast
- *
- * @type {boolean}
- * @default
- */
- Tech.prototype.featuresPlaybackRate = false;
-
- /**
- * Boolean indicating wether the `Tech` supports the `progress` event. This is currently
- * not triggered by video-js-swf. This will be used to determine if
- * {@link Tech#manualProgressOn} should be called.
- *
- * @type {boolean}
- * @default
- */
- Tech.prototype.featuresProgressEvents = false;
-
- /**
- * Boolean indicating wether the `Tech` supports the `timeupdate` event. This is currently
- * not triggered by video-js-swf. This will be used to determine if
- * {@link Tech#manualTimeUpdates} should be called.
- *
- * @type {boolean}
- * @default
- */
- Tech.prototype.featuresTimeupdateEvents = false;
-
- /**
- * Boolean indicating wether the `Tech` supports the native `TextTrack`s.
- * This will help us integrate with native `TextTrack`s if the browser supports them.
- *
- * @type {boolean}
- * @default
- */
- Tech.prototype.featuresNativeTextTracks = false;
-
- /**
- * A functional mixin for techs that want to use the Source Handler pattern.
- * 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)
- * Example: `Tech.withSourceHandlers.call(MyTech);`
- *
- * @param {Tech} _Tech
- * The tech to add source handler functions to.
- *
- * @mixes Tech~SourceHandlerAdditions
- */
- Tech.withSourceHandlers = function (_Tech) {
-
- /**
- * Register a source handler
- *
- * @param {Function} handler
- * The source handler class
- *
- * @param {number} [index]
- * Register it at the following index
- */
- _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. Also checks the
- * Techs sourceHandlers.
- *
- * @param {string} type
- * The mimetype to check.
- *
- * @return {string}
- * 'probably', 'maybe', or '' (empty string)
- */
- _Tech.canPlayType = function (type) {
- var handlers = _Tech.sourceHandlers || [];
- var can = void 0;
-
- for (var i = 0; i < handlers.length; i++) {
- can = handlers[i].canPlayType(type);
-
- if (can) {
- return can;
- }
- }
-
- return '';
- };
-
- /**
- * Returns the first source handler that supports the source.
- *
- * TODO: Answer question: should 'probably' be prioritized over 'maybe'
- *
- * @param {Tech~SourceObject} source
- * The source object
- *
- * @param {Object} options
- * The options passed to the tech
- *
- * @return {SourceHandler|null}
- * The first source handler that supports the source or null if
- * no SourceHandler supports the source
- */
- _Tech.selectSourceHandler = function (source, options) {
- var handlers = _Tech.sourceHandlers || [];
- var can = void 0;
-
- for (var i = 0; i < handlers.length; i++) {
- can = handlers[i].canHandleSource(source, options);
-
- if (can) {
- return handlers[i];
- }
- }
-
- return null;
- };
-
- /**
- * Check if the tech can support the given source.
- *
- * @param {Tech~SourceObject} srcObj
- * The source object
- *
- * @param {Object} options
- * The options passed to the tech
- *
- * @return {string}
- * 'probably', 'maybe', or '' (empty string)
- */
- _Tech.canPlaySource = function (srcObj, options) {
- var sh = _Tech.selectSourceHandler(srcObj, options);
-
- if (sh) {
- return sh.canHandleSource(srcObj, options);
- }
-
- return '';
- };
-
- /**
- * When using a source handler, prefer its implementation of
- * any function normally provided by the tech.
- */
- var deferrable = ['seekable', 'duration'];
-
- /**
- * A wrapper around {@link Tech#seekable} that will call a `SourceHandler`s seekable
- * function if it exists, with a fallback to the Techs seekable function.
- *
- * @method _Tech.seekable
- */
-
- /**
- * A wrapper around {@link Tech#duration} that will call a `SourceHandler`s duration
- * function if it exists, otherwise it will fallback to the techs duration function.
- *
- * @method _Tech.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 {Tech~SourceObject} source
- * A source object with src and type keys
- */
- _Tech.prototype.setSource = function (source) {
- var sh = _Tech.selectSourceHandler(source, this.options_);
-
- if (!sh) {
- // Fall back to a native source hander when unsupported sources are
- // deliberately set
- if (_Tech.nativeSourceHandler) {
- sh = _Tech.nativeSourceHandler;
- } else {
- log$1.error('No source hander found for the current source.');
- }
- }
-
- // Dispose any existing source handler
- this.disposeSourceHandler();
- this.off('dispose', this.disposeSourceHandler);
-
- if (sh !== _Tech.nativeSourceHandler) {
- this.currentSource_ = source;
- }
-
- this.sourceHandler_ = sh.handleSource(source, this, this.options_);
- this.on('dispose', this.disposeSourceHandler);
- };
-
- /**
- * Clean up any existing SourceHandlers and listeners when the Tech is disposed.
- *
- * @listens Tech#dispose
- */
- _Tech.prototype.disposeSourceHandler = function () {
- // if we have a source and get another one
- // then we are loading something new
- // than clear all of our current tracks
- if (this.currentSource_) {
- this.clearTracks(['audio', 'video']);
- this.currentSource_ = null;
- }
-
- // always clean up auto-text tracks
- this.cleanupAutoTextTracks();
-
- if (this.sourceHandler_) {
-
- if (this.sourceHandler_.dispose) {
- this.sourceHandler_.dispose();
- }
-
- this.sourceHandler_ = null;
- }
- };
- };
-
-// The base Tech class needs to be registered as a Component. It is the only
-// Tech that can be registered as a Component.
- Component.registerComponent('Tech', Tech);
- Tech.registerTech('Tech', Tech);
-
- /**
- * A list of techs that should be added to techOrder on Players
- *
- * @private
- */
- Tech.defaultTechOrder_ = [];
-
- var middlewares = {};
-
- function use(type, middleware) {
- middlewares[type] = middlewares[type] || [];
- middlewares[type].push(middleware);
- }
-
-
- function setSource(player, src, next) {
- player.setTimeout(function () {
- return setSourceHelper(src, middlewares[src.type], next, player);
- }, 1);
- }
-
- function setTech(middleware, tech) {
- middleware.forEach(function (mw) {
- return mw.setTech && mw.setTech(tech);
- });
- }
-
- function get$1(middleware, tech, method) {
- return middleware.reduceRight(middlewareIterator(method), tech[method]());
- }
-
- function set$1(middleware, tech, method, arg) {
- return tech[method](middleware.reduce(middlewareIterator(method), arg));
- }
-
- var allowedGetters = {
- buffered: 1,
- currentTime: 1,
- duration: 1,
- seekable: 1,
- played: 1
- };
-
- var allowedSetters = {
- setCurrentTime: 1
- };
-
- function middlewareIterator(method) {
- return function (value, mw) {
- if (mw[method]) {
- return mw[method](value);
- }
-
- return value;
- };
- }
-
- function setSourceHelper() {
- var src = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- var middleware = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
- var next = arguments[2];
- var player = arguments[3];
- var acc = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];
- var lastRun = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
- var mwFactory = middleware[0],
- mwrest = middleware.slice(1);
-
- // if mwFactory is a string, then we're at a fork in the road
-
- if (typeof mwFactory === 'string') {
- setSourceHelper(src, middlewares[mwFactory], next, player, acc, lastRun);
-
- // if we have an mwFactory, call it with the player to get the mw,
- // then call the mw's setSource method
- } else if (mwFactory) {
- var mw = mwFactory(player);
-
- mw.setSource(assign({}, src), function (err, _src) {
-
- // something happened, try the next middleware on the current level
- // make sure to use the old src
- if (err) {
- return setSourceHelper(src, mwrest, next, player, acc, lastRun);
- }
-
- // we've succeeded, now we need to go deeper
- acc.push(mw);
-
- // if it's the same time, continue does the current chain
- // otherwise, we want to go down the new chain
- setSourceHelper(_src, src.type === _src.type ? mwrest : middlewares[_src.type], next, player, acc, lastRun);
- });
- } else if (mwrest.length) {
- setSourceHelper(src, mwrest, next, player, acc, lastRun);
- } else if (lastRun) {
- next(src, acc);
- } else {
- setSourceHelper(src, middlewares['*'], next, player, acc, true);
- }
- }
-
- /**
- * @module filter-source
- */
- /**
- * Filter out single bad source objects or multiple source objects in an
- * array. Also flattens nested source object arrays into a 1 dimensional
- * array of source objects.
- *
- * @param {Tech~SourceObject|Tech~SourceObject[]} src
- * The src object to filter
- *
- * @return {Tech~SourceObject[]}
- * An array of sourceobjects containing only valid sources
- *
- * @private
- */
- var filterSource = function filterSource(src) {
- // traverse array
- if (Array.isArray(src)) {
- var newsrc = [];
-
- src.forEach(function (srcobj) {
- srcobj = filterSource(srcobj);
-
- if (Array.isArray(srcobj)) {
- newsrc = newsrc.concat(srcobj);
- } else if (isObject(srcobj)) {
- newsrc.push(srcobj);
- }
- });
-
- src = newsrc;
- } else if (typeof src === 'string' && src.trim()) {
- // convert string into object
- src = [{src: src}];
- } else if (isObject(src) && typeof src.src === 'string' && src.src && src.src.trim()) {
- // src is already valid
- src = [src];
- } else {
- // invalid source, turn it into an empty array
- src = [];
- }
-
- return src;
- };
-
- /**
- * @file loader.js
- */
- /**
- * The `MediaLoader` is the `Component` that decides which playback technology to load
- * when a player is initialized.
- *
- * @extends Component
- */
-
- var MediaLoader = function (_Component) {
- inherits(MediaLoader, _Component);
-
- /**
- * Create an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should attach to.
- *
- * @param {Object} [options]
- * The key/value stroe of player options.
- *
- * @param {Component~ReadyCallback} [ready]
- * The function that is run when this component is ready.
- */
- function MediaLoader(player, options, ready) {
- classCallCheck(this, MediaLoader);
-
- // MediaLoader has no element
- var options_ = mergeOptions({createEl: false}, options);
-
- // If there are no sources when the player is initialized,
- // load the first supported playback technology.
-
- var _this = possibleConstructorReturn(this, _Component.call(this, player, options_, ready));
-
- if (!options.playerOptions.sources || options.playerOptions.sources.length === 0) {
- for (var i = 0, j = options.playerOptions.techOrder; i < j.length; i++) {
- var techName = toTitleCase(j[i]);
- var tech = Tech.getTech(techName);
-
- // Support old behavior of techs being registered as components.
- // Remove once that deprecated behavior is removed.
- if (!techName) {
- tech = Component.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 _this;
- }
-
- return MediaLoader;
- }(Component);
-
- Component.registerComponent('MediaLoader', MediaLoader);
-
- /**
- * @file button.js
- */
- /**
- * Clickable Component which is clickable or keyboard actionable,
- * but is not a native HTML button.
- *
- * @extends Component
- */
-
- var ClickableComponent = function (_Component) {
- inherits(ClickableComponent, _Component);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function ClickableComponent(player, options) {
- classCallCheck(this, ClickableComponent);
-
- var _this = possibleConstructorReturn(this, _Component.call(this, player, options));
-
- _this.emitTapEvents();
-
- _this.enable();
- return _this;
- }
-
- /**
- * Create the `Component`s DOM element.
- *
- * @param {string} [tag=div]
- * The element's node type.
- *
- * @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}
- * The element that gets created.
- */
-
-
- ClickableComponent.prototype.createEl = function createEl$$1() {
- var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
- var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-
- props = assign({
- innerHTML: '<span aria-hidden="true" class="vjs-icon-placeholder"></span>',
- className: this.buildCSSClass(),
- tabIndex: 0
- }, props);
-
- if (tag === 'button') {
- log$1.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 = assign({
- 'role': 'button',
-
- // let the screen reader user know that the text of the element may change
- 'aria-live': 'polite'
- }, attributes);
-
- this.tabIndex_ = props.tabIndex;
-
- var el = _Component.prototype.createEl.call(this, tag, props, attributes);
-
- this.createControlTextEl(el);
-
- return el;
- };
-
- /**
- * Create a control text element on this `Component`
- *
- * @param {Element} [el]
- * Parent element for the control text.
- *
- * @return {Element}
- * The control text element that gets created.
- */
-
-
- ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) {
- this.controlTextEl_ = createEl('span', {
- className: 'vjs-control-text'
- });
-
- if (el) {
- el.appendChild(this.controlTextEl_);
- }
-
- this.controlText(this.controlText_, el);
-
- return this.controlTextEl_;
- };
-
- /**
- * Get or set the localize text to use for the controls on the `Component`.
- *
- * @param {string} [text]
- * Control text for element.
- *
- * @param {Element} [el=this.el()]
- * Element to set the title on.
- *
- * @return {string}
- * - The control text when getting
- */
-
-
- ClickableComponent.prototype.controlText = function controlText(text) {
- var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.el();
-
- if (!text) {
- return this.controlText_ || 'Need Text';
- }
-
- var localizedText = this.localize(text);
-
- this.controlText_ = text;
- textContent(this.controlTextEl_, localizedText);
- if (!this.nonIconControl) {
- // Set title attribute if only an icon is shown
- el.setAttribute('title', localizedText);
- }
- };
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- ClickableComponent.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this);
- };
-
- /**
- * Enable this `Component`s element.
- */
-
-
- ClickableComponent.prototype.enable = function enable() {
- if (!this.enabled_) {
- this.enabled_ = true;
- this.removeClass('vjs-disabled');
- this.el_.setAttribute('aria-disabled', 'false');
- if (typeof this.tabIndex_ !== 'undefined') {
- this.el_.setAttribute('tabIndex', this.tabIndex_);
- }
- this.on(['tap', 'click'], this.handleClick);
- this.on('focus', this.handleFocus);
- this.on('blur', this.handleBlur);
- }
- };
-
- /**
- * Disable this `Component`s element.
- */
-
-
- ClickableComponent.prototype.disable = function disable() {
- this.enabled_ = false;
- this.addClass('vjs-disabled');
- this.el_.setAttribute('aria-disabled', 'true');
- if (typeof this.tabIndex_ !== 'undefined') {
- this.el_.removeAttribute('tabIndex');
- }
- this.off(['tap', 'click'], this.handleClick);
- this.off('focus', this.handleFocus);
- this.off('blur', this.handleBlur);
- };
-
- /**
- * This gets called when a `ClickableComponent` gets:
- * - Clicked (via the `click` event, listening starts in the constructor)
- * - Tapped (via the `tap` event, listening starts in the constructor)
- * - The following things happen in order:
- * 1. {@link ClickableComponent#handleFocus} is called via a `focus` event on the
- * `ClickableComponent`.
- * 2. {@link ClickableComponent#handleFocus} adds a listener for `keydown` on using
- * {@link ClickableComponent#handleKeyPress}.
- * 3. `ClickableComponent` has not had a `blur` event (`blur` means that focus was lost). The user presses
- * the space or enter key.
- * 4. {@link ClickableComponent#handleKeyPress} calls this function with the `keydown`
- * event as a parameter.
- *
- * @param {EventTarget~Event} event
- * The `keydown`, `tap`, or `click` event that caused this function to be
- * called.
- *
- * @listens tap
- * @listens click
- * @abstract
- */
-
-
- ClickableComponent.prototype.handleClick = function handleClick(event) {
- };
-
- /**
- * This gets called when a `ClickableComponent` gains focus via a `focus` event.
- * Turns on listening for `keydown` events. When they happen it
- * calls `this.handleKeyPress`.
- *
- * @param {EventTarget~Event} event
- * The `focus` event that caused this function to be called.
- *
- * @listens focus
- */
-
-
- ClickableComponent.prototype.handleFocus = function handleFocus(event) {
- on(document_1, 'keydown', bind(this, this.handleKeyPress));
- };
-
- /**
- * Called when this ClickableComponent has focus and a key gets pressed down. By
- * default it will call `this.handleClick` when the key is space or enter.
- *
- * @param {EventTarget~Event} event
- * The `keydown` event that caused this function to be called.
- *
- * @listens keydown
- */
-
-
- 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.trigger('click');
- } else if (_Component.prototype.handleKeyPress) {
-
- // Pass keypress handling up for unsupported keys
- _Component.prototype.handleKeyPress.call(this, event);
- }
- };
-
- /**
- * Called when a `ClickableComponent` loses focus. Turns off the listener for
- * `keydown` events. Which Stops `this.handleKeyPress` from getting called.
- *
- * @param {EventTarget~Event} event
- * The `blur` event that caused this function to be called.
- *
- * @listens blur
- */
-
-
- ClickableComponent.prototype.handleBlur = function handleBlur(event) {
- off(document_1, 'keydown', bind(this, this.handleKeyPress));
- };
-
- return ClickableComponent;
- }(Component);
-
- Component.registerComponent('ClickableComponent', ClickableComponent);
-
- /**
- * @file poster-image.js
- */
- /**
- * A `ClickableComponent` that handles showing the poster image for the player.
- *
- * @extends ClickableComponent
- */
-
- var PosterImage = function (_ClickableComponent) {
- inherits(PosterImage, _ClickableComponent);
-
- /**
- * Create an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should attach to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function PosterImage(player, options) {
- classCallCheck(this, PosterImage);
-
- var _this = possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
-
- _this.update();
- player.on('posterchange', bind(_this, _this.update));
- return _this;
- }
-
- /**
- * Clean up and dispose of the `PosterImage`.
- */
-
-
- PosterImage.prototype.dispose = function dispose() {
- this.player().off('posterchange', this.update);
- _ClickableComponent.prototype.dispose.call(this);
- };
-
- /**
- * Create the `PosterImage`s DOM element.
- *
- * @return {Element}
- * The element that gets created.
- */
-
-
- PosterImage.prototype.createEl = function createEl$$1() {
- var el = 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 (!BACKGROUND_SIZE_SUPPORTED) {
- this.fallbackImg_ = createEl('img');
- el.appendChild(this.fallbackImg_);
- }
-
- return el;
- };
-
- /**
- * An {@link EventTarget~EventListener} for {@link Player#posterchange} events.
- *
- * @listens Player#posterchange
- *
- * @param {EventTarget~Event} [event]
- * The `Player#posterchange` event that triggered this function.
- */
-
-
- PosterImage.prototype.update = function update(event) {
- 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 source of the `PosterImage` depending on the display method.
- *
- * @param {string} url
- * The URL to the source for the `PosterImage`.
- */
-
-
- 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;
- }
- };
-
- /**
- * An {@link EventTarget~EventListener} for clicks on the `PosterImage`. See
- * {@link ClickableComponent#handleClick} for instances where this will be triggered.
- *
- * @listens tap
- * @listens click
- * @listens keydown
- *
- * @param {EventTarget~Event} event
- + The `click`, `tap` or `keydown` event that caused this function to be called.
- */
-
-
- PosterImage.prototype.handleClick = function handleClick(event) {
- // We don't want a click to trigger playback when controls are disabled
- if (!this.player_.controls()) {
- return;
- }
-
- if (this.player_.paused()) {
- this.player_.play();
- } else {
- this.player_.pause();
- }
- };
-
- return PosterImage;
- }(ClickableComponent);
-
- Component.registerComponent('PosterImage', PosterImage);
-
- /**
- * @file text-track-display.js
- */
- 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'
- };
-
- /**
- * Construct an rgba color from a given hex color code.
- *
- * @param {number} color
- * Hex number for color, like #f0e.
- *
- * @param {number} opacity
- * Value for opacity, 0.0 - 1.0.
- *
- * @return {string}
- * The rgba color that was created, like 'rgba(255, 0, 0, 0.3)'.
- *
- * @private
- */
- 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 the style of a DOM element. Some style changes will throw an error,
- * particularly in IE8. Those should be noops.
- *
- * @param {Element} el
- * The DOM element to be styled.
- *
- * @param {string} style
- * The CSS property on the element that should be styled.
- *
- * @param {string} rule
- * The style rule that should be applied to the property.
- *
- * @private
- */
- function tryUpdateStyle(el, style, rule) {
- try {
- el.style[style] = rule;
- } catch (e) {
-
- // Satisfies linter.
- return;
- }
- }
-
- /**
- * The component for displaying text track cues.
- *
- * @extends Component
- */
-
- var TextTrackDisplay = function (_Component) {
- inherits(TextTrackDisplay, _Component);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- *
- * @param {Component~ReadyCallback} [ready]
- * The function to call when `TextTrackDisplay` is ready.
- */
- function TextTrackDisplay(player, options, ready) {
- classCallCheck(this, TextTrackDisplay);
-
- var _this = possibleConstructorReturn(this, _Component.call(this, player, options, ready));
-
- player.on('loadstart', bind(_this, _this.toggleDisplay));
- player.on('texttrackchange', bind(_this, _this.updateDisplay));
- player.on('loadstart', bind(_this, _this.preselectTrack));
-
- // 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(bind(_this, function () {
- if (player.tech_ && player.tech_.featuresNativeTextTracks) {
- this.hide();
- return;
- }
-
- player.on('fullscreenchange', bind(this, this.updateDisplay));
-
- var tracks = this.options_.playerOptions.tracks || [];
-
- for (var i = 0; i < tracks.length; i++) {
- this.player_.addRemoteTextTrack(tracks[i], true);
- }
-
- this.preselectTrack();
- }));
- return _this;
- }
-
- /**
- * Preselect a track following this precedence:
- * - matches the previously selected {@link TextTrack}'s language and kind
- * - matches the previously selected {@link TextTrack}'s language only
- * - is the first default captions track
- * - is the first default descriptions track
- *
- * @listens Player#loadstart
- */
-
-
- TextTrackDisplay.prototype.preselectTrack = function preselectTrack() {
- var modes = {captions: 1, subtitles: 1};
- var trackList = this.player_.textTracks();
- var userPref = this.player_.cache_.selectedLanguage;
- var firstDesc = void 0;
- var firstCaptions = void 0;
- var preferredTrack = void 0;
-
- for (var i = 0; i < trackList.length; i++) {
- var track = trackList[i];
-
- if (userPref && userPref.enabled && userPref.language === track.language) {
- // Always choose the track that matches both language and kind
- if (track.kind === userPref.kind) {
- preferredTrack = track;
- // or choose the first track that matches language
- } else if (!preferredTrack) {
- preferredTrack = track;
- }
-
- // clear everything if offTextTrackMenuItem was clicked
- } else if (userPref && !userPref.enabled) {
- preferredTrack = null;
- firstDesc = null;
- firstCaptions = null;
- } else if (track['default']) {
- if (track.kind === 'descriptions' && !firstDesc) {
- firstDesc = track;
- } else if (track.kind in modes && !firstCaptions) {
- firstCaptions = track;
- }
- }
- }
-
- // The preferredTrack matches the user preference and takes
- // precendence over all the other tracks.
- // So, display the preferredTrack before the first default track
- // and the subtitles/captions track before the descriptions track
- if (preferredTrack) {
- preferredTrack.mode = 'showing';
- } else if (firstCaptions) {
- firstCaptions.mode = 'showing';
- } else if (firstDesc) {
- firstDesc.mode = 'showing';
- }
- };
-
- /**
- * Turn display of {@link TextTrack}'s from the current state into the other state.
- * There are only two states:
- * - 'shown'
- * - 'hidden'
- *
- * @listens Player#loadstart
- */
-
-
- TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() {
- if (this.player_.tech_ && this.player_.tech_.featuresNativeTextTracks) {
- this.hide();
- } else {
- this.show();
- }
- };
-
- /**
- * Create the {@link Component}'s DOM element.
- *
- * @return {Element}
- * The element that was created.
- */
-
-
- TextTrackDisplay.prototype.createEl = function createEl() {
- return _Component.prototype.createEl.call(this, 'div', {
- className: 'vjs-text-track-display'
- }, {
- 'aria-live': 'off',
- 'aria-atomic': 'true'
- });
- };
-
- /**
- * Clear all displayed {@link TextTrack}s.
- */
-
-
- TextTrackDisplay.prototype.clearDisplay = function clearDisplay() {
- if (typeof window_1.WebVTT === 'function') {
- window_1.WebVTT.processCues(window_1, [], this.el_);
- }
- };
-
- /**
- * Update the displayed TextTrack when a either a {@link Player#texttrackchange} or
- * a {@link Player#fullscreenchange} is fired.
- *
- * @listens Player#texttrackchange
- * @listens Player#fullscreenchange
- */
-
-
- TextTrackDisplay.prototype.updateDisplay = function updateDisplay() {
- var tracks = this.player_.textTracks();
-
- this.clearDisplay();
-
- // Track display prioritization model: if multiple tracks are 'showing',
- // display the first 'subtitles' or 'captions' track which is 'showing',
- // otherwise display the first 'descriptions' track which is 'showing'
-
- var descriptionsTrack = null;
- var captionsSubtitlesTrack = null;
- var i = tracks.length;
-
- while (i--) {
- var track = tracks[i];
-
- if (track.mode === 'showing') {
- if (track.kind === 'descriptions') {
- descriptionsTrack = track;
- } else {
- captionsSubtitlesTrack = track;
- }
- }
- }
-
- if (captionsSubtitlesTrack) {
- if (this.getAttribute('aria-live') !== 'off') {
- this.setAttribute('aria-live', 'off');
- }
- this.updateForTrack(captionsSubtitlesTrack);
- } else if (descriptionsTrack) {
- if (this.getAttribute('aria-live') !== 'assertive') {
- this.setAttribute('aria-live', 'assertive');
- }
- this.updateForTrack(descriptionsTrack);
- }
- };
-
- /**
- * Add an {@link Texttrack} to to the {@link Tech}s {@link TextTrackList}.
- *
- * @param {TextTrack} track
- * Text track object to be added to the list.
- */
-
-
- TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) {
- if (typeof window_1.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]);
- }
-
- window_1.WebVTT.processCues(window_1, cues, 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 = window_1.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;
- }(Component);
-
- Component.registerComponent('TextTrackDisplay', TextTrackDisplay);
-
- /**
- * @file loading-spinner.js
- */
- /**
- * A loading spinner for use during waiting/loading events.
- *
- * @extends Component
- */
-
- var LoadingSpinner = function (_Component) {
- inherits(LoadingSpinner, _Component);
-
- function LoadingSpinner() {
- classCallCheck(this, LoadingSpinner);
- return possibleConstructorReturn(this, _Component.apply(this, arguments));
- }
-
- /**
- * Create the `LoadingSpinner`s DOM element.
- *
- * @return {Element}
- * The dom element that gets created.
- */
- LoadingSpinner.prototype.createEl = function createEl() {
- return _Component.prototype.createEl.call(this, 'div', {
- className: 'vjs-loading-spinner',
- dir: 'ltr'
- });
- };
-
- return LoadingSpinner;
- }(Component);
-
- Component.registerComponent('LoadingSpinner', LoadingSpinner);
-
- /**
- * @file button.js
- */
- /**
- * Base class for all buttons.
- *
- * @extends ClickableComponent
- */
-
- var Button = function (_ClickableComponent) {
- inherits(Button, _ClickableComponent);
-
- function Button() {
- classCallCheck(this, Button);
- return possibleConstructorReturn(this, _ClickableComponent.apply(this, arguments));
- }
-
- /**
- * Create the `Button`s DOM element.
- *
- * @param {string} [tag="button"]
- * The element's node type. This argument is IGNORED: no matter what
- * is passed, it will always create a `button` element.
- *
- * @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}
- * The element that gets created.
- */
- Button.prototype.createEl = function createEl(tag) {
- var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-
- tag = 'button';
-
- props = assign({
- innerHTML: '<span aria-hidden="true" class="vjs-icon-placeholder"></span>',
- className: this.buildCSSClass()
- }, props);
-
- // Add attributes for button element
- attributes = assign({
-
- // Necessary since the default button type is "submit"
- 'type': 'button',
-
- // let the screen reader user know that the text of the button may change
- 'aria-live': 'polite'
- }, attributes);
-
- var el = Component.prototype.createEl.call(this, tag, props, attributes);
-
- this.createControlTextEl(el);
-
- return el;
- };
-
- /**
- * Add a child `Component` inside of this `Button`.
- *
- * @param {string|Component} child
- * The name or instance of a child to add.
- *
- * @param {Object} [options={}]
- * The key/value store of options that will get passed to children of
- * the child.
- *
- * @return {Component}
- * The `Component` that gets added as a child. When using a string the
- * `Component` will get created by this process.
- *
- * @deprecated since version 5
- */
-
-
- Button.prototype.addChild = function addChild(child) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- var className = this.constructor.name;
-
- log$1.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 Component.prototype.addChild.call(this, child, options);
- };
-
- /**
- * Enable the `Button` element so that it can be activated or clicked. Use this with
- * {@link Button#disable}.
- */
-
-
- Button.prototype.enable = function enable() {
- _ClickableComponent.prototype.enable.call(this);
- this.el_.removeAttribute('disabled');
- };
-
- /**
- * Enable the `Button` element so that it cannot be activated or clicked. Use this with
- * {@link Button#enable}.
- */
-
-
- Button.prototype.disable = function disable() {
- _ClickableComponent.prototype.disable.call(this);
- this.el_.setAttribute('disabled', 'disabled');
- };
-
- /**
- * This gets called when a `Button` has focus and `keydown` is triggered via a key
- * press.
- *
- * @param {EventTarget~Event} event
- * The event that caused this function to get called.
- *
- * @listens keydown
- */
-
-
- 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) {
- return;
- }
-
- // Pass keypress handling up for unsupported keys
- _ClickableComponent.prototype.handleKeyPress.call(this, event);
- };
-
- return Button;
- }(ClickableComponent);
-
- Component.registerComponent('Button', Button);
-
- /**
- * @file big-play-button.js
- */
- /**
- * The initial play button that shows before the video has played. The hiding of the
- * `BigPlayButton` get done via CSS and `Player` states.
- *
- * @extends Button
- */
-
- var BigPlayButton = function (_Button) {
- inherits(BigPlayButton, _Button);
-
- function BigPlayButton(player, options) {
- classCallCheck(this, BigPlayButton);
-
- var _this = possibleConstructorReturn(this, _Button.call(this, player, options));
-
- _this.mouseused_ = false;
-
- _this.on('mousedown', _this.handleMouseDown);
- return _this;
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object. Always returns 'vjs-big-play-button'.
- */
-
-
- BigPlayButton.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-big-play-button';
- };
-
- /**
- * This gets called when a `BigPlayButton` "clicked". See {@link ClickableComponent}
- * for more detailed information on what a click can be.
- *
- * @param {EventTarget~Event} event
- * The `keydown`, `tap`, or `click` event that caused this function to be
- * called.
- *
- * @listens tap
- * @listens click
- */
-
-
- BigPlayButton.prototype.handleClick = function handleClick(event) {
- var playPromise = this.player_.play();
-
- // exit early if clicked via the mouse
- if (this.mouseused_ && event.clientX && event.clientY) {
- return;
- }
-
- var cb = this.player_.getChild('controlBar');
- var playToggle = cb && cb.getChild('playToggle');
-
- if (!playToggle) {
- this.player_.focus();
- return;
- }
-
- var playFocus = function playFocus() {
- return playToggle.focus();
- };
-
- if (playPromise && playPromise.then) {
- var ignoreRejectedPlayPromise = function ignoreRejectedPlayPromise() {
- };
-
- playPromise.then(playFocus, ignoreRejectedPlayPromise);
- } else {
- this.setTimeout(playFocus, 1);
- }
- };
-
- BigPlayButton.prototype.handleKeyPress = function handleKeyPress(event) {
- this.mouseused_ = false;
-
- _Button.prototype.handleKeyPress.call(this, event);
- };
-
- BigPlayButton.prototype.handleMouseDown = function handleMouseDown(event) {
- this.mouseused_ = true;
- };
-
- return BigPlayButton;
- }(Button);
-
- /**
- * The text that should display over the `BigPlayButton`s controls. Added to for localization.
- *
- * @type {string}
- * @private
- */
-
-
- BigPlayButton.prototype.controlText_ = 'Play Video';
-
- Component.registerComponent('BigPlayButton', BigPlayButton);
-
- /**
- * @file close-button.js
- */
- /**
- * The `CloseButton` is a `{@link Button}` that fires a `close` event when
- * it gets clicked.
- *
- * @extends Button
- */
-
- var CloseButton = function (_Button) {
- inherits(CloseButton, _Button);
-
- /**
- * Creates an instance of the this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function CloseButton(player, options) {
- classCallCheck(this, CloseButton);
-
- var _this = possibleConstructorReturn(this, _Button.call(this, player, options));
-
- _this.controlText(options && options.controlText || _this.localize('Close'));
- return _this;
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- CloseButton.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this);
- };
-
- /**
- * This gets called when a `CloseButton` gets clicked. See
- * {@link ClickableComponent#handleClick} for more information on when this will be
- * triggered
- *
- * @param {EventTarget~Event} event
- * The `keydown`, `tap`, or `click` event that caused this function to be
- * called.
- *
- * @listens tap
- * @listens click
- * @fires CloseButton#close
- */
-
-
- CloseButton.prototype.handleClick = function handleClick(event) {
-
- /**
- * Triggered when the a `CloseButton` is clicked.
- *
- * @event CloseButton#close
- * @type {EventTarget~Event}
- *
- * @property {boolean} [bubbles=false]
- * set to false so that the close event does not
- * bubble up to parents if there is no listener
- */
- this.trigger({type: 'close', bubbles: false});
- };
-
- return CloseButton;
- }(Button);
-
- Component.registerComponent('CloseButton', CloseButton);
-
- /**
- * @file play-toggle.js
- */
- /**
- * Button to toggle between play and pause.
- *
- * @extends Button
- */
-
- var PlayToggle = function (_Button) {
- inherits(PlayToggle, _Button);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function PlayToggle(player, options) {
- classCallCheck(this, PlayToggle);
-
- var _this = possibleConstructorReturn(this, _Button.call(this, player, options));
-
- _this.on(player, 'play', _this.handlePlay);
- _this.on(player, 'pause', _this.handlePause);
- _this.on(player, 'ended', _this.handleEnded);
- return _this;
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- PlayToggle.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this);
- };
-
- /**
- * This gets called when an `PlayToggle` is "clicked". See
- * {@link ClickableComponent} for more detailed information on what a click can be.
- *
- * @param {EventTarget~Event} [event]
- * The `keydown`, `tap`, or `click` event that caused this function to be
- * called.
- *
- * @listens tap
- * @listens click
- */
-
-
- PlayToggle.prototype.handleClick = function handleClick(event) {
- if (this.player_.paused()) {
- this.player_.play();
- } else {
- this.player_.pause();
- }
- };
-
- /**
- * This gets called once after the video has ended and the user seeks so that
- * we can change the replay button back to a play button.
- *
- * @param {EventTarget~Event} [event]
- * The event that caused this function to run.
- *
- * @listens Player#seeked
- */
-
-
- PlayToggle.prototype.handleSeeked = function handleSeeked(event) {
- this.removeClass('vjs-ended');
-
- if (this.player_.paused()) {
- this.handlePause(event);
- } else {
- this.handlePlay(event);
- }
- };
-
- /**
- * Add the vjs-playing class to the element so it can change appearance.
- *
- * @param {EventTarget~Event} [event]
- * The event that caused this function to run.
- *
- * @listens Player#play
- */
-
-
- PlayToggle.prototype.handlePlay = function handlePlay(event) {
- this.removeClass('vjs-ended');
- this.removeClass('vjs-paused');
- this.addClass('vjs-playing');
- // change the button text to "Pause"
- this.controlText('Pause');
- };
-
- /**
- * Add the vjs-paused class to the element so it can change appearance.
- *
- * @param {EventTarget~Event} [event]
- * The event that caused this function to run.
- *
- * @listens Player#pause
- */
-
-
- PlayToggle.prototype.handlePause = function handlePause(event) {
- this.removeClass('vjs-playing');
- this.addClass('vjs-paused');
- // change the button text to "Play"
- this.controlText('Play');
- };
-
- /**
- * Add the vjs-ended class to the element so it can change appearance
- *
- * @param {EventTarget~Event} [event]
- * The event that caused this function to run.
- *
- * @listens Player#ended
- */
-
-
- PlayToggle.prototype.handleEnded = function handleEnded(event) {
- this.removeClass('vjs-playing');
- this.addClass('vjs-ended');
- // change the button text to "Replay"
- this.controlText('Replay');
-
- // on the next seek remove the replay button
- this.one(this.player_, 'seeked', this.handleSeeked);
- };
-
- return PlayToggle;
- }(Button);
-
- /**
- * The text that should display over the `PlayToggle`s controls. Added for localization.
- *
- * @type {string}
- * @private
- */
-
-
- PlayToggle.prototype.controlText_ = 'Play';
-
- Component.registerComponent('PlayToggle', PlayToggle);
-
- /**
- * @file format-time.js
- * @module Format-time
- */
-
- /**
- * 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
- */
- function formatTime(seconds) {
- var guide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : seconds;
-
- 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;
- }
-
- /**
- * @file time-display.js
- */
- /**
- * Displays the time left in the video
- *
- * @extends Component
- */
-
- var TimeDisplay = function (_Component) {
- inherits(TimeDisplay, _Component);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function TimeDisplay(player, options) {
- classCallCheck(this, TimeDisplay);
-
- var _this = possibleConstructorReturn(this, _Component.call(this, player, options));
-
- _this.throttledUpdateContent = throttle(bind(_this, _this.updateContent), 25);
- _this.on(player, 'timeupdate', _this.throttledUpdateContent);
- return _this;
- }
-
- /**
- * Create the `Component`'s DOM element
- *
- * @return {Element}
- * The element that was created.
- */
-
-
- TimeDisplay.prototype.createEl = function createEl$$1(plainName) {
- var className = this.buildCSSClass();
- var el = _Component.prototype.createEl.call(this, 'div', {
- className: className + ' vjs-time-control vjs-control'
- });
-
- this.contentEl_ = createEl('div', {
- className: className + '-display'
- }, {
- // tell screen readers not to automatically read the time as it changes
- 'aria-live': 'off'
- }, createEl('span', {
- className: 'vjs-control-text',
- textContent: this.localize(this.controlText_)
- }));
-
- this.updateTextNode_();
- el.appendChild(this.contentEl_);
- return el;
- };
-
- /**
- * Updates the "remaining time" text node with new content using the
- * contents of the `formattedTime_` property.
- *
- * @private
- */
-
-
- TimeDisplay.prototype.updateTextNode_ = function updateTextNode_() {
- if (!this.contentEl_) {
- return;
- }
-
- while (this.contentEl_.firstChild) {
- this.contentEl_.removeChild(this.contentEl_.firstChild);
- }
-
- this.textNode_ = document_1.createTextNode(this.formattedTime_ || '0:00');
- this.contentEl_.appendChild(this.textNode_);
- };
-
- /**
- * Generates a formatted time for this component to use in display.
- *
- * @param {number} time
- * A numeric time, in seconds.
- *
- * @return {string}
- * A formatted time
- *
- * @private
- */
-
-
- TimeDisplay.prototype.formatTime_ = function formatTime_(time) {
- return formatTime(time);
- };
-
- /**
- * Updates the time display text node if it has what was passed in changed
- * the formatted time.
- *
- * @param {number} time
- * The time to update to
- *
- * @private
- */
-
-
- TimeDisplay.prototype.updateFormattedTime_ = function updateFormattedTime_(time) {
- var formattedTime = this.formatTime_(time);
-
- if (formattedTime === this.formattedTime_) {
- return;
- }
-
- this.formattedTime_ = formattedTime;
- this.requestAnimationFrame(this.updateTextNode_);
- };
-
- /**
- * To be filled out in the child class, should update the displayed time
- * in accordance with the fact that the current time has changed.
- *
- * @param {EventTarget~Event} [event]
- * The `timeupdate` event that caused this to run.
- *
- * @listens Player#timeupdate
- */
-
-
- TimeDisplay.prototype.updateContent = function updateContent(event) {
- };
-
- return TimeDisplay;
- }(Component);
-
- /**
- * The text that should display over the `TimeDisplay`s controls. Added to for localization.
- *
- * @type {string}
- * @private
- */
-
-
- TimeDisplay.prototype.controlText_ = 'Time';
-
- Component.registerComponent('TimeDisplay', TimeDisplay);
-
- /**
- * @file current-time-display.js
- */
- /**
- * Displays the current time
- *
- * @extends Component
- */
-
- var CurrentTimeDisplay = function (_TimeDisplay) {
- inherits(CurrentTimeDisplay, _TimeDisplay);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function CurrentTimeDisplay(player, options) {
- classCallCheck(this, CurrentTimeDisplay);
-
- var _this = possibleConstructorReturn(this, _TimeDisplay.call(this, player, options));
-
- _this.on(player, 'ended', _this.handleEnded);
- return _this;
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- CurrentTimeDisplay.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-current-time';
- };
-
- /**
- * Update current time display
- *
- * @param {EventTarget~Event} [event]
- * The `timeupdate` event that caused this function to run.
- *
- * @listens Player#timeupdate
- */
-
-
- CurrentTimeDisplay.prototype.updateContent = function updateContent(event) {
- // Allows for smooth scrubbing, when player can't keep up.
- var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
-
- this.updateFormattedTime_(time);
- };
-
- /**
- * When the player fires ended there should be no time left. Sadly
- * this is not always the case, lets make it seem like that is the case
- * for users.
- *
- * @param {EventTarget~Event} [event]
- * The `ended` event that caused this to run.
- *
- * @listens Player#ended
- */
-
-
- CurrentTimeDisplay.prototype.handleEnded = function handleEnded(event) {
- if (!this.player_.duration()) {
- return;
- }
- this.updateFormattedTime_(this.player_.duration());
- };
-
- return CurrentTimeDisplay;
- }(TimeDisplay);
-
- /**
- * The text that should display over the `CurrentTimeDisplay`s controls. Added to for localization.
- *
- * @type {string}
- * @private
- */
-
-
- CurrentTimeDisplay.prototype.controlText_ = 'Current Time';
-
- Component.registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
-
- /**
- * @file duration-display.js
- */
- /**
- * Displays the duration
- *
- * @extends Component
- */
-
- var DurationDisplay = function (_TimeDisplay) {
- inherits(DurationDisplay, _TimeDisplay);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function DurationDisplay(player, options) {
- classCallCheck(this, DurationDisplay);
-
- // we do not want to/need to throttle duration changes,
- // as they should always display the changed duration as
- // it has changed
- var _this = possibleConstructorReturn(this, _TimeDisplay.call(this, player, options));
-
- _this.on(player, 'durationchange', _this.updateContent);
-
- // Also listen for timeupdate (in the parent) and loadedmetadata because removing those
- // listeners could have broken dependent applications/libraries. These
- // can likely be removed for 7.0.
- _this.on(player, 'loadedmetadata', _this.throttledUpdateContent);
- return _this;
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- DurationDisplay.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-duration';
- };
-
- /**
- * Update duration time display.
- *
- * @param {EventTarget~Event} [event]
- * The `durationchange`, `timeupdate`, or `loadedmetadata` event that caused
- * this function to be called.
- *
- * @listens Player#durationchange
- * @listens Player#timeupdate
- * @listens Player#loadedmetadata
- */
-
-
- DurationDisplay.prototype.updateContent = function updateContent(event) {
- var duration = this.player_.duration();
-
- if (duration && this.duration_ !== duration) {
- this.duration_ = duration;
- this.updateFormattedTime_(duration);
- }
- };
-
- return DurationDisplay;
- }(TimeDisplay);
-
- /**
- * The text that should display over the `DurationDisplay`s controls. Added to for localization.
- *
- * @type {string}
- * @private
- */
-
-
- DurationDisplay.prototype.controlText_ = 'Duration Time';
-
- Component.registerComponent('DurationDisplay', DurationDisplay);
-
- /**
- * @file time-divider.js
- */
- /**
- * The separator between the current time and duration.
- * Can be hidden if it's not needed in the design.
- *
- * @extends Component
- */
-
- var TimeDivider = function (_Component) {
- inherits(TimeDivider, _Component);
-
- function TimeDivider() {
- classCallCheck(this, TimeDivider);
- return possibleConstructorReturn(this, _Component.apply(this, arguments));
- }
-
- /**
- * Create the component's DOM element
- *
- * @return {Element}
- * The element that was created.
- */
- 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;
- }(Component);
-
- Component.registerComponent('TimeDivider', TimeDivider);
-
- /**
- * @file remaining-time-display.js
- */
- /**
- * Displays the time left in the video
- *
- * @extends Component
- */
-
- var RemainingTimeDisplay = function (_TimeDisplay) {
- inherits(RemainingTimeDisplay, _TimeDisplay);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function RemainingTimeDisplay(player, options) {
- classCallCheck(this, RemainingTimeDisplay);
-
- var _this = possibleConstructorReturn(this, _TimeDisplay.call(this, player, options));
-
- _this.on(player, 'durationchange', _this.throttledUpdateContent);
- _this.on(player, 'ended', _this.handleEnded);
- return _this;
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- RemainingTimeDisplay.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-remaining-time';
- };
-
- /**
- * The remaining time display prefixes numbers with a "minus" character.
- *
- * @param {number} time
- * A numeric time, in seconds.
- *
- * @return {string}
- * A formatted time
- *
- * @private
- */
-
-
- RemainingTimeDisplay.prototype.formatTime_ = function formatTime_(time) {
- return '-' + _TimeDisplay.prototype.formatTime_.call(this, time);
- };
-
- /**
- * Update remaining time display.
- *
- * @param {EventTarget~Event} [event]
- * The `timeupdate` or `durationchange` event that caused this to run.
- *
- * @listens Player#timeupdate
- * @listens Player#durationchange
- */
-
-
- RemainingTimeDisplay.prototype.updateContent = function updateContent(event) {
- if (!this.player_.duration()) {
- return;
- }
-
- // @deprecated We should only use remainingTimeDisplay
- // as of video.js 7
- if (this.player_.remainingTimeDisplay) {
- this.updateFormattedTime_(this.player_.remainingTimeDisplay());
- } else {
- this.updateFormattedTime_(this.player_.remainingTime());
- }
- };
-
- /**
- * When the player fires ended there should be no time left. Sadly
- * this is not always the case, lets make it seem like that is the case
- * for users.
- *
- * @param {EventTarget~Event} [event]
- * The `ended` event that caused this to run.
- *
- * @listens Player#ended
- */
-
-
- RemainingTimeDisplay.prototype.handleEnded = function handleEnded(event) {
- if (!this.player_.duration()) {
- return;
- }
- this.updateFormattedTime_(0);
- };
-
- return RemainingTimeDisplay;
- }(TimeDisplay);
-
- /**
- * The text that should display over the `RemainingTimeDisplay`s controls. Added to for localization.
- *
- * @type {string}
- * @private
- */
-
-
- RemainingTimeDisplay.prototype.controlText_ = 'Remaining Time';
-
- Component.registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
-
- /**
- * @file live-display.js
- */
-// TODO - Future make it click to snap to live
-
- /**
- * Displays the live indicator when duration is Infinity.
- *
- * @extends Component
- */
-
- var LiveDisplay = function (_Component) {
- inherits(LiveDisplay, _Component);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function LiveDisplay(player, options) {
- classCallCheck(this, LiveDisplay);
-
- var _this = possibleConstructorReturn(this, _Component.call(this, player, options));
-
- _this.updateShowing();
- _this.on(_this.player(), 'durationchange', _this.updateShowing);
- return _this;
- }
-
- /**
- * Create the `Component`'s DOM element
- *
- * @return {Element}
- * The element that was created.
- */
-
-
- LiveDisplay.prototype.createEl = function createEl$$1() {
- var el = _Component.prototype.createEl.call(this, 'div', {
- className: 'vjs-live-control vjs-control'
- });
-
- this.contentEl_ = 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;
- };
-
- /**
- * Check the duration to see if the LiveDisplay should be showing or not. Then show/hide
- * it accordingly
- *
- * @param {EventTarget~Event} [event]
- * The {@link Player#durationchange} event that caused this function to run.
- *
- * @listens Player#durationchange
- */
-
-
- LiveDisplay.prototype.updateShowing = function updateShowing(event) {
- if (this.player().duration() === Infinity) {
- this.show();
- } else {
- this.hide();
- }
- };
-
- return LiveDisplay;
- }(Component);
-
- Component.registerComponent('LiveDisplay', LiveDisplay);
-
- /**
- * @file slider.js
- */
- /**
- * The base functionality for a slider. Can be vertical or horizontal.
- * For instance the volume bar or the seek bar on a video is a slider.
- *
- * @extends Component
- */
-
- var Slider = function (_Component) {
- inherits(Slider, _Component);
-
- /**
- * Create an instance of this class
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function Slider(player, options) {
- classCallCheck(this, Slider);
-
- // Set property names to bar to match with the child Slider class is looking for
- var _this = possibleConstructorReturn(this, _Component.call(this, player, options));
-
- _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.enable();
- return _this;
- }
-
- /**
- * Are controls are currently enabled for this slider or not.
- *
- * @return {boolean}
- * true if controls are enabled, false otherwise
- */
-
-
- Slider.prototype.enabled = function enabled() {
- return this.enabled_;
- };
-
- /**
- * Enable controls for this slider if they are disabled
- */
-
-
- Slider.prototype.enable = function enable() {
- if (this.enabled()) {
- return;
- }
-
- 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(this.player_, 'controlsvisible', this.update);
-
- if (this.playerEvent) {
- this.on(this.player_, this.playerEvent, this.update);
- }
-
- this.removeClass('disabled');
- this.setAttribute('tabindex', 0);
-
- this.enabled_ = true;
- };
-
- /**
- * Disable controls for this slider if they are enabled
- */
-
-
- Slider.prototype.disable = function disable() {
- if (!this.enabled()) {
- return;
- }
- var doc = this.bar.el_.ownerDocument;
-
- this.off('mousedown', this.handleMouseDown);
- this.off('touchstart', this.handleMouseDown);
- this.off('focus', this.handleFocus);
- this.off('blur', this.handleBlur);
- this.off('click', this.handleClick);
- this.off(this.player_, 'controlsvisible', this.update);
- this.off(doc, 'mousemove', this.handleMouseMove);
- this.off(doc, 'mouseup', this.handleMouseUp);
- this.off(doc, 'touchmove', this.handleMouseMove);
- this.off(doc, 'touchend', this.handleMouseUp);
- this.removeAttribute('tabindex');
-
- this.addClass('disabled');
-
- if (this.playerEvent) {
- this.off(this.player_, this.playerEvent, this.update);
- }
- this.enabled_ = false;
- };
-
- /**
- * Create the `Button`s DOM element.
- *
- * @param {string} type
- * Type of element to create.
- *
- * @param {Object} [props={}]
- * List of properties in Object form.
- *
- * @param {Object} [attributes={}]
- * list of attributes in Object form.
- *
- * @return {Element}
- * The element that gets created.
- */
-
-
- Slider.prototype.createEl = function createEl$$1(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 = assign({
- tabIndex: 0
- }, props);
-
- attributes = assign({
- 'role': 'slider',
- 'aria-valuenow': 0,
- 'aria-valuemin': 0,
- 'aria-valuemax': 100,
- 'tabIndex': 0
- }, attributes);
-
- return _Component.prototype.createEl.call(this, type, props, attributes);
- };
-
- /**
- * Handle `mousedown` or `touchstart` events on the `Slider`.
- *
- * @param {EventTarget~Event} event
- * `mousedown` or `touchstart` event that triggered this function
- *
- * @listens mousedown
- * @listens touchstart
- * @fires Slider#slideractive
- */
-
-
- Slider.prototype.handleMouseDown = function handleMouseDown(event) {
- var doc = this.bar.el_.ownerDocument;
-
- event.preventDefault();
- blockTextSelection();
-
- this.addClass('vjs-sliding');
- /**
- * Triggered when the slider is in an active state
- *
- * @event Slider#slideractive
- * @type {EventTarget~Event}
- */
- this.trigger('slideractive');
-
- this.on(doc, 'mousemove', this.handleMouseMove);
- this.on(doc, 'mouseup', this.handleMouseUp);
- this.on(doc, 'touchmove', this.handleMouseMove);
- this.on(doc, 'touchend', this.handleMouseUp);
-
- this.handleMouseMove(event);
- };
-
- /**
- * Handle the `mousemove`, `touchmove`, and `mousedown` events on this `Slider`.
- * The `mousemove` and `touchmove` events will only only trigger this function during
- * `mousedown` and `touchstart`. This is due to {@link Slider#handleMouseDown} and
- * {@link Slider#handleMouseUp}.
- *
- * @param {EventTarget~Event} event
- * `mousedown`, `mousemove`, `touchstart`, or `touchmove` event that triggered
- * this function
- *
- * @listens mousemove
- * @listens touchmove
- */
-
-
- Slider.prototype.handleMouseMove = function handleMouseMove(event) {
- };
-
- /**
- * Handle `mouseup` or `touchend` events on the `Slider`.
- *
- * @param {EventTarget~Event} event
- * `mouseup` or `touchend` event that triggered this function.
- *
- * @listens touchend
- * @listens mouseup
- * @fires Slider#sliderinactive
- */
-
-
- Slider.prototype.handleMouseUp = function handleMouseUp() {
- var doc = this.bar.el_.ownerDocument;
-
- unblockTextSelection();
-
- this.removeClass('vjs-sliding');
- /**
- * Triggered when the slider is no longer in an active state.
- *
- * @event Slider#sliderinactive
- * @type {EventTarget~Event}
- */
- this.trigger('sliderinactive');
-
- this.off(doc, 'mousemove', this.handleMouseMove);
- this.off(doc, 'mouseup', this.handleMouseUp);
- this.off(doc, 'touchmove', this.handleMouseMove);
- this.off(doc, 'touchend', this.handleMouseUp);
-
- this.update();
- };
-
- /**
- * Update the progress bar of the `Slider`.
- *
- * @returns {number}
- * The percentage of progress the progress bar represents as a
- * number from 0 to 1.
- */
-
-
- 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) + '%';
- var style = bar.el().style;
-
- // Set the new bar width or height
- if (this.vertical()) {
- style.height = percentage;
- } else {
- style.width = percentage;
- }
-
- return progress;
- };
-
- /**
- * Calculate distance for slider
- *
- * @param {EventTarget~Event} event
- * The event that caused this function to run.
- *
- * @return {number}
- * The current position of the Slider.
- * - postition.x for vertical `Slider`s
- * - postition.y for horizontal `Slider`s
- */
-
-
- Slider.prototype.calculateDistance = function calculateDistance(event) {
- var position = getPointerPosition(this.el_, event);
-
- if (this.vertical()) {
- return position.y;
- }
- return position.x;
- };
-
- /**
- * Handle a `focus` event on this `Slider`.
- *
- * @param {EventTarget~Event} event
- * The `focus` event that caused this function to run.
- *
- * @listens focus
- */
-
-
- Slider.prototype.handleFocus = function handleFocus() {
- this.on(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
- };
-
- /**
- * Handle a `keydown` event on the `Slider`. Watches for left, rigth, up, and down
- * arrow keys. This function will only be called when the slider has focus. See
- * {@link Slider#handleFocus} and {@link Slider#handleBlur}.
- *
- * @param {EventTarget~Event} event
- * the `keydown` event that caused this function to run.
- *
- * @listens keydown
- */
-
-
- Slider.prototype.handleKeyPress = function handleKeyPress(event) {
- // Left and Down Arrows
- if (event.which === 37 || event.which === 40) {
- event.preventDefault();
- this.stepBack();
-
- // Up and Right Arrows
- } else if (event.which === 38 || event.which === 39) {
- event.preventDefault();
- this.stepForward();
- }
- };
-
- /**
- * Handle a `blur` event on this `Slider`.
- *
- * @param {EventTarget~Event} event
- * The `blur` event that caused this function to run.
- *
- * @listens blur
- */
-
- Slider.prototype.handleBlur = function handleBlur() {
- this.off(this.bar.el_.ownerDocument, '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 that caused this object to run
- */
-
-
- 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, and getting
- * - false if the slider is horizontal, and getting
- */
-
-
- 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 Slider;
- }(Component);
-
- Component.registerComponent('Slider', Slider);
-
- /**
- * @file load-progress-bar.js
- */
- /**
- * Shows loading progress
- *
- * @extends Component
- */
-
- var LoadProgressBar = function (_Component) {
- inherits(LoadProgressBar, _Component);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function LoadProgressBar(player, options) {
- classCallCheck(this, LoadProgressBar);
-
- var _this = possibleConstructorReturn(this, _Component.call(this, player, options));
-
- _this.partEls_ = [];
- _this.on(player, 'progress', _this.update);
- return _this;
- }
-
- /**
- * Create the `Component`'s DOM element
- *
- * @return {Element}
- * The element that was created.
- */
-
-
- LoadProgressBar.prototype.createEl = function createEl$$1() {
- 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
- *
- * @param {EventTarget~Event} [event]
- * The `progress` event that caused this function to run.
- *
- * @listens Player#progress
- */
-
-
- LoadProgressBar.prototype.update = function update(event) {
- var buffered = this.player_.buffered();
- var duration = this.player_.duration();
- var bufferedEnd = this.player_.bufferedEnd();
- var children = this.partEls_;
-
- // get the percent width of a time compared to the total end
- var percentify = function percentify(time, end) {
- // no NaN
- var percent = time / end || 0;
-
- 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(createEl());
- children[i] = part;
- }
-
- // 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]);
- }
- children.length = buffered.length;
- };
-
- return LoadProgressBar;
- }(Component);
-
- Component.registerComponent('LoadProgressBar', LoadProgressBar);
-
- /**
- * @file time-tooltip.js
- */
- /**
- * Time tooltips display a time above the progress bar.
- *
- * @extends Component
- */
-
- var TimeTooltip = function (_Component) {
- inherits(TimeTooltip, _Component);
-
- function TimeTooltip() {
- classCallCheck(this, TimeTooltip);
- return possibleConstructorReturn(this, _Component.apply(this, arguments));
- }
-
- /**
- * Create the time tooltip DOM element
- *
- * @return {Element}
- * The element that was created.
- */
- TimeTooltip.prototype.createEl = function createEl$$1() {
- return _Component.prototype.createEl.call(this, 'div', {
- className: 'vjs-time-tooltip'
- });
- };
-
- /**
- * Updates the position of the time tooltip relative to the `SeekBar`.
- *
- * @param {Object} seekBarRect
- * The `ClientRect` for the {@link SeekBar} element.
- *
- * @param {number} seekBarPoint
- * A number from 0 to 1, representing a horizontal reference point
- * from the left edge of the {@link SeekBar}
- */
-
-
- TimeTooltip.prototype.update = function update(seekBarRect, seekBarPoint, content) {
- var tooltipRect = getBoundingClientRect(this.el_);
- var playerRect = getBoundingClientRect(this.player_.el());
- var seekBarPointPx = seekBarRect.width * seekBarPoint;
-
- // do nothing if either rect isn't available
- // for example, if the player isn't in the DOM for testing
- if (!playerRect || !tooltipRect) {
- return;
- }
-
- // This is the space left of the `seekBarPoint` available within the bounds
- // of the player. We calculate any gap between the left edge of the player
- // and the left edge of the `SeekBar` and add the number of pixels in the
- // `SeekBar` before hitting the `seekBarPoint`
- var spaceLeftOfPoint = seekBarRect.left - playerRect.left + seekBarPointPx;
-
- // This is the space right of the `seekBarPoint` available within the bounds
- // of the player. We calculate the number of pixels from the `seekBarPoint`
- // to the right edge of the `SeekBar` and add to that any gap between the
- // right edge of the `SeekBar` and the player.
- var spaceRightOfPoint = seekBarRect.width - seekBarPointPx + (playerRect.right - seekBarRect.right);
-
- // This is the number of pixels by which the tooltip will need to be pulled
- // further to the right to center it over the `seekBarPoint`.
- var pullTooltipBy = tooltipRect.width / 2;
-
- // Adjust the `pullTooltipBy` distance to the left or right depending on
- // the results of the space calculations above.
- if (spaceLeftOfPoint < pullTooltipBy) {
- pullTooltipBy += pullTooltipBy - spaceLeftOfPoint;
- } else if (spaceRightOfPoint < pullTooltipBy) {
- pullTooltipBy = spaceRightOfPoint;
- }
-
- // Due to the imprecision of decimal/ratio based calculations and varying
- // rounding behaviors, there are cases where the spacing adjustment is off
- // by a pixel or two. This adds insurance to these calculations.
- if (pullTooltipBy < 0) {
- pullTooltipBy = 0;
- } else if (pullTooltipBy > tooltipRect.width) {
- pullTooltipBy = tooltipRect.width;
- }
-
- this.el_.style.right = '-' + pullTooltipBy + 'px';
- textContent(this.el_, content);
- };
-
- return TimeTooltip;
- }(Component);
-
- Component.registerComponent('TimeTooltip', TimeTooltip);
-
- /**
- * @file play-progress-bar.js
- */
- /**
- * Used by {@link SeekBar} to display media playback progress as part of the
- * {@link ProgressControl}.
- *
- * @extends Component
- */
-
- var PlayProgressBar = function (_Component) {
- inherits(PlayProgressBar, _Component);
-
- function PlayProgressBar() {
- classCallCheck(this, PlayProgressBar);
- return possibleConstructorReturn(this, _Component.apply(this, arguments));
- }
-
- /**
- * Create the the DOM element for this class.
- *
- * @return {Element}
- * The element that was created.
- */
- 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>'
- });
- };
-
- /**
- * Enqueues updates to its own DOM as well as the DOM of its
- * {@link TimeTooltip} child.
- *
- * @param {Object} seekBarRect
- * The `ClientRect` for the {@link SeekBar} element.
- *
- * @param {number} seekBarPoint
- * A number from 0 to 1, representing a horizontal reference point
- * from the left edge of the {@link SeekBar}
- */
-
-
- PlayProgressBar.prototype.update = function update(seekBarRect, seekBarPoint) {
- var _this2 = this;
-
- // If there is an existing rAF ID, cancel it so we don't over-queue.
- if (this.rafId_) {
- this.cancelAnimationFrame(this.rafId_);
- }
-
- this.rafId_ = this.requestAnimationFrame(function () {
- var time = _this2.player_.scrubbing() ? _this2.player_.getCache().currentTime : _this2.player_.currentTime();
-
- var content = formatTime(time, _this2.player_.duration());
- var timeTooltip = _this2.getChild('timeTooltip');
-
- if (timeTooltip) {
- timeTooltip.update(seekBarRect, seekBarPoint, content);
- }
- });
- };
-
- return PlayProgressBar;
- }(Component);
-
- /**
- * Default options for {@link PlayProgressBar}.
- *
- * @type {Object}
- * @private
- */
-
-
- PlayProgressBar.prototype.options_ = {
- children: []
- };
-
-// Time tooltips should not be added to a player on mobile devices or IE8
- if ((!IE_VERSION || IE_VERSION > 8) && !IS_IOS && !IS_ANDROID) {
- PlayProgressBar.prototype.options_.children.push('timeTooltip');
- }
-
- Component.registerComponent('PlayProgressBar', PlayProgressBar);
-
- /**
- * @file mouse-time-display.js
- */
- /**
- * The {@link MouseTimeDisplay} component tracks mouse movement over the
- * {@link ProgressControl}. It displays an indicator and a {@link TimeTooltip}
- * indicating the time which is represented by a given point in the
- * {@link ProgressControl}.
- *
- * @extends Component
- */
-
- var MouseTimeDisplay = function (_Component) {
- inherits(MouseTimeDisplay, _Component);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The {@link Player} that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function MouseTimeDisplay(player, options) {
- classCallCheck(this, MouseTimeDisplay);
-
- var _this = possibleConstructorReturn(this, _Component.call(this, player, options));
-
- _this.update = throttle(bind(_this, _this.update), 25);
- return _this;
- }
-
- /**
- * Create the DOM element for this class.
- *
- * @return {Element}
- * The element that was created.
- */
-
-
- MouseTimeDisplay.prototype.createEl = function createEl() {
- return _Component.prototype.createEl.call(this, 'div', {
- className: 'vjs-mouse-display'
- });
- };
-
- /**
- * Enqueues updates to its own DOM as well as the DOM of its
- * {@link TimeTooltip} child.
- *
- * @param {Object} seekBarRect
- * The `ClientRect` for the {@link SeekBar} element.
- *
- * @param {number} seekBarPoint
- * A number from 0 to 1, representing a horizontal reference point
- * from the left edge of the {@link SeekBar}
- */
-
-
- MouseTimeDisplay.prototype.update = function update(seekBarRect, seekBarPoint) {
- var _this2 = this;
-
- // If there is an existing rAF ID, cancel it so we don't over-queue.
- if (this.rafId_) {
- this.cancelAnimationFrame(this.rafId_);
- }
-
- this.rafId_ = this.requestAnimationFrame(function () {
- var duration = _this2.player_.duration();
- var content = formatTime(seekBarPoint * duration, duration);
-
- var scaleX = _this2.el_.getBoundingClientRect().width / _this2.el_.offsetWidth;
-
- _this2.el_.style.left = (seekBarRect.width * seekBarPoint) / scaleX + 'px';
- _this2.getChild('timeTooltip').update(seekBarRect, seekBarPoint, content);
- });
- };
-
- return MouseTimeDisplay;
- }(Component);
-
- /**
- * Default options for `MouseTimeDisplay`
- *
- * @type {Object}
- * @private
- */
-
-
- MouseTimeDisplay.prototype.options_ = {
- children: ['timeTooltip']
- };
-
- Component.registerComponent('MouseTimeDisplay', MouseTimeDisplay);
-
- /**
- * @file seek-bar.js
- */
-// The number of seconds the `step*` functions move the timeline.
- var STEP_SECONDS = 5;
-
- /**
- * Seek bar and container for the progress bars. Uses {@link PlayProgressBar}
- * as its `bar`.
- *
- * @extends Slider
- */
-
- var SeekBar = function (_Slider) {
- inherits(SeekBar, _Slider);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function SeekBar(player, options) {
- classCallCheck(this, SeekBar);
-
- var _this = possibleConstructorReturn(this, _Slider.call(this, player, options));
-
- _this.update = throttle(bind(_this, _this.update), 50);
- _this.on(player, 'timeupdate', _this.update);
- _this.on(player, 'ended', _this.handleEnded);
-
- return _this;
- }
-
- /**
- * Create the `Component`'s DOM element
- *
- * @return {Element}
- * The element that was created.
- */
-
-
- SeekBar.prototype.createEl = function createEl$$1() {
- return _Slider.prototype.createEl.call(this, 'div', {
- className: 'vjs-progress-holder'
- }, {
- 'aria-label': this.localize('Progress Bar')
- });
- };
-
- /**
- * This function updates the play progress bar and accessiblity
- * attributes to whatever is passed in.
- *
- * @param {number} currentTime
- * The currentTime value that should be used for accessiblity
- *
- * @param {number} percent
- * The percentage as a decimal that the bar should be filled from 0-1.
- *
- * @private
- */
-
-
- SeekBar.prototype.update_ = function update_(currentTime, percent) {
- var duration = this.player_.duration();
-
- // machine readable value of progress bar (percentage complete)
- this.el_.setAttribute('aria-valuenow', (percent * 100).toFixed(2));
-
- // human readable value of progress bar (time complete)
- this.el_.setAttribute('aria-valuetext', this.localize('progress bar timing: currentTime={1} duration={2}', [formatTime(currentTime, duration), formatTime(duration, duration)], '{1} of {2}'));
-
- // Update the `PlayProgressBar`.
- this.bar.update(getBoundingClientRect(this.el_), percent);
- };
-
- /**
- * Update the seek bar's UI.
- *
- * @param {EventTarget~Event} [event]
- * The `timeupdate` or `ended` event that caused this to run.
- *
- * @listens Player#timeupdate
- *
- * @returns {number}
- * The current percent at a number from 0-1
- */
-
-
- SeekBar.prototype.update = function update(event) {
- var percent = _Slider.prototype.update.call(this);
-
- this.update_(this.getCurrentTime_(), percent);
- return percent;
- };
-
- /**
- * Get the value of current time but allows for smooth scrubbing,
- * when player can't keep up.
- *
- * @return {number}
- * The current time value to display
- *
- * @private
- */
-
-
- SeekBar.prototype.getCurrentTime_ = function getCurrentTime_() {
- return this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
- };
-
- /**
- * We want the seek bar to be full on ended
- * no matter what the actual internal values are. so we force it.
- *
- * @param {EventTarget~Event} [event]
- * The `timeupdate` or `ended` event that caused this to run.
- *
- * @listens Player#ended
- */
-
-
- SeekBar.prototype.handleEnded = function handleEnded(event) {
- this.update_(this.player_.duration(), 1);
- };
-
- /**
- * Get the percentage of media played so far.
- *
- * @return {number}
- * The percentage of media played so far (0 to 1).
- */
-
-
- SeekBar.prototype.getPercent = function getPercent() {
- var percent = this.getCurrentTime_() / this.player_.duration();
-
- return percent >= 1 ? 1 : percent;
- };
-
- /**
- * Handle mouse down on seek bar
- *
- * @param {EventTarget~Event} event
- * The `mousedown` event that caused this to run.
- *
- * @listens mousedown
- */
-
-
- SeekBar.prototype.handleMouseDown = function handleMouseDown(event) {
- this.player_.scrubbing(true);
-
- this.videoWasPlaying = !this.player_.paused();
- this.player_.pause();
-
- _Slider.prototype.handleMouseDown.call(this, event);
- };
-
- /**
- * Handle mouse move on seek bar
- *
- * @param {EventTarget~Event} event
- * The `mousemove` event that caused this to run.
- *
- * @listens mousemove
- */
-
-
- 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);
- };
-
- SeekBar.prototype.enable = function enable() {
- _Slider.prototype.enable.call(this);
- var mouseTimeDisplay = this.getChild('mouseTimeDisplay');
-
- if (!mouseTimeDisplay) {
- return;
- }
-
- mouseTimeDisplay.show();
- };
-
- SeekBar.prototype.disable = function disable() {
- _Slider.prototype.disable.call(this);
- var mouseTimeDisplay = this.getChild('mouseTimeDisplay');
-
- if (!mouseTimeDisplay) {
- return;
- }
-
- mouseTimeDisplay.hide();
- };
-
- /**
- * Handle mouse up on seek bar
- *
- * @param {EventTarget~Event} event
- * The `mouseup` event that caused this to run.
- *
- * @listens mouseup
- */
-
-
- 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
- */
-
-
- SeekBar.prototype.stepForward = function stepForward() {
- this.player_.currentTime(this.player_.currentTime() + STEP_SECONDS);
- };
-
- /**
- * Move more quickly rewind for keyboard-only users
- */
-
-
- SeekBar.prototype.stepBack = function stepBack() {
- this.player_.currentTime(this.player_.currentTime() - STEP_SECONDS);
- };
-
- /**
- * Toggles the playback state of the player
- * This gets called when enter or space is used on the seekbar
- *
- * @param {EventTarget~Event} event
- * The `keydown` event that caused this function to be called
- *
- */
-
-
- SeekBar.prototype.handleAction = function handleAction(event) {
- if (this.player_.paused()) {
- this.player_.play();
- } else {
- this.player_.pause();
- }
- };
-
- /**
- * Called when this SeekBar has focus and a key gets pressed down. By
- * default it will call `this.handleAction` when the key is space or enter.
- *
- * @param {EventTarget~Event} event
- * The `keydown` event that caused this function to be called.
- *
- * @listens keydown
- */
-
-
- SeekBar.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.handleAction(event);
- } else if (_Slider.prototype.handleKeyPress) {
-
- // Pass keypress handling up for unsupported keys
- _Slider.prototype.handleKeyPress.call(this, event);
- }
- };
-
- return SeekBar;
- }(Slider);
-
- /**
- * Default options for the `SeekBar`
- *
- * @type {Object}
- * @private
- */
-
-
- SeekBar.prototype.options_ = {
- children: ['loadProgressBar', 'playProgressBar'],
- barName: 'playProgressBar'
- };
-
-// MouseTimeDisplay tooltips should not be added to a player on mobile devices or IE8
- if ((!IE_VERSION || IE_VERSION > 8) && !IS_IOS && !IS_ANDROID) {
- SeekBar.prototype.options_.children.splice(1, 0, 'mouseTimeDisplay');
- }
-
- /**
- * Call the update event for this Slider when this event happens on the player.
- *
- * @type {string}
- */
- SeekBar.prototype.playerEvent = 'timeupdate';
-
- Component.registerComponent('SeekBar', SeekBar);
-
- /**
- * @file progress-control.js
- */
- /**
- * The Progress Control component contains the seek bar, load progress,
- * and play progress.
- *
- * @extends Component
- */
-
- var ProgressControl = function (_Component) {
- inherits(ProgressControl, _Component);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function ProgressControl(player, options) {
- classCallCheck(this, ProgressControl);
-
- var _this = possibleConstructorReturn(this, _Component.call(this, player, options));
-
- _this.handleMouseMove = throttle(bind(_this, _this.handleMouseMove), 25);
- _this.throttledHandleMouseSeek = throttle(bind(_this, _this.handleMouseSeek), 25);
-
- _this.enable();
- return _this;
- }
-
- /**
- * Create the `Component`'s DOM element
- *
- * @return {Element}
- * The element that was created.
- */
-
-
- ProgressControl.prototype.createEl = function createEl$$1() {
- return _Component.prototype.createEl.call(this, 'div', {
- className: 'vjs-progress-control vjs-control'
- });
- };
-
- /**
- * When the mouse moves over the `ProgressControl`, the pointer position
- * gets passed down to the `MouseTimeDisplay` component.
- *
- * @param {EventTarget~Event} event
- * The `mousemove` event that caused this function to run.
- *
- * @listen mousemove
- */
-
-
- ProgressControl.prototype.handleMouseMove = function handleMouseMove(event) {
- var seekBar = this.getChild('seekBar');
- var mouseTimeDisplay = seekBar.getChild('mouseTimeDisplay');
- var seekBarEl = seekBar.el();
- var seekBarRect = getBoundingClientRect(seekBarEl);
- var seekBarPoint = getPointerPosition(seekBarEl, event).x;
-
- // The default skin has a gap on either side of the `SeekBar`. This means
- // that it's possible to trigger this behavior outside the boundaries of
- // the `SeekBar`. This ensures we stay within it at all times.
- if (seekBarPoint > 1) {
- seekBarPoint = 1;
- } else if (seekBarPoint < 0) {
- seekBarPoint = 0;
- }
-
- if (mouseTimeDisplay) {
- mouseTimeDisplay.update(seekBarRect, seekBarPoint);
- }
- };
-
- /**
- * A throttled version of the {@link ProgressControl#handleMouseSeek} listener.
- *
- * @method ProgressControl#throttledHandleMouseSeek
- * @param {EventTarget~Event} event
- * The `mousemove` event that caused this function to run.
- *
- * @listen mousemove
- * @listen touchmove
- */
-
- /**
- * Handle `mousemove` or `touchmove` events on the `ProgressControl`.
- *
- * @param {EventTarget~Event} event
- * `mousedown` or `touchstart` event that triggered this function
- *
- * @listens mousemove
- * @listens touchmove
- */
-
-
- ProgressControl.prototype.handleMouseSeek = function handleMouseSeek(event) {
- var seekBar = this.getChild('seekBar');
-
- seekBar.handleMouseMove(event);
- };
-
- /**
- * Are controls are currently enabled for this progress control.
- *
- * @return {boolean}
- * true if controls are enabled, false otherwise
- */
-
-
- ProgressControl.prototype.enabled = function enabled() {
- return this.enabled_;
- };
-
- /**
- * Disable all controls on the progress control and its children
- */
-
-
- ProgressControl.prototype.disable = function disable() {
- this.children().forEach(function (child) {
- return child.disable && child.disable();
- });
-
- if (!this.enabled()) {
- return;
- }
-
- this.off(['mousedown', 'touchstart'], this.handleMouseDown);
- this.off(this.el_, 'mousemove', this.handleMouseMove);
- this.handleMouseUp();
-
- this.addClass('disabled');
-
- this.enabled_ = false;
- };
-
- /**
- * Enable all controls on the progress control and its children
- */
-
-
- ProgressControl.prototype.enable = function enable() {
- this.children().forEach(function (child) {
- return child.enable && child.enable();
- });
-
- if (this.enabled()) {
- return;
- }
-
- this.on(['mousedown', 'touchstart'], this.handleMouseDown);
- this.on(this.el_, 'mousemove', this.handleMouseMove);
- this.removeClass('disabled');
-
- this.enabled_ = true;
- };
-
- /**
- * Handle `mousedown` or `touchstart` events on the `ProgressControl`.
- *
- * @param {EventTarget~Event} event
- * `mousedown` or `touchstart` event that triggered this function
- *
- * @listens mousedown
- * @listens touchstart
- */
-
-
- ProgressControl.prototype.handleMouseDown = function handleMouseDown(event) {
- var doc = this.el_.ownerDocument;
-
- this.on(doc, 'mousemove', this.throttledHandleMouseSeek);
- this.on(doc, 'touchmove', this.throttledHandleMouseSeek);
- this.on(doc, 'mouseup', this.handleMouseUp);
- this.on(doc, 'touchend', this.handleMouseUp);
- };
-
- /**
- * Handle `mouseup` or `touchend` events on the `ProgressControl`.
- *
- * @param {EventTarget~Event} event
- * `mouseup` or `touchend` event that triggered this function.
- *
- * @listens touchend
- * @listens mouseup
- */
-
-
- ProgressControl.prototype.handleMouseUp = function handleMouseUp(event) {
- var doc = this.el_.ownerDocument;
-
- this.off(doc, 'mousemove', this.throttledHandleMouseSeek);
- this.off(doc, 'touchmove', this.throttledHandleMouseSeek);
- this.off(doc, 'mouseup', this.handleMouseUp);
- this.off(doc, 'touchend', this.handleMouseUp);
- };
-
- return ProgressControl;
- }(Component);
-
- /**
- * Default options for `ProgressControl`
- *
- * @type {Object}
- * @private
- */
-
-
- ProgressControl.prototype.options_ = {
- children: ['seekBar']
- };
-
- Component.registerComponent('ProgressControl', ProgressControl);
-
- /**
- * @file fullscreen-toggle.js
- */
- /**
- * Toggle fullscreen video
- *
- * @extends Button
- */
-
- var FullscreenToggle = function (_Button) {
- inherits(FullscreenToggle, _Button);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function FullscreenToggle(player, options) {
- classCallCheck(this, FullscreenToggle);
-
- var _this = possibleConstructorReturn(this, _Button.call(this, player, options));
-
- _this.on(player, 'fullscreenchange', _this.handleFullscreenChange);
- return _this;
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this);
- };
-
- /**
- * Handles fullscreenchange on the player and change control text accordingly.
- *
- * @param {EventTarget~Event} [event]
- * The {@link Player#fullscreenchange} event that caused this function to be
- * called.
- *
- * @listens Player#fullscreenchange
- */
-
-
- FullscreenToggle.prototype.handleFullscreenChange = function handleFullscreenChange(event) {
- if (this.player_.isFullscreen()) {
- this.controlText('Non-Fullscreen');
- } else {
- this.controlText('Fullscreen');
- }
- };
-
- /**
- * This gets called when an `FullscreenToggle` is "clicked". See
- * {@link ClickableComponent} for more detailed information on what a click can be.
- *
- * @param {EventTarget~Event} [event]
- * The `keydown`, `tap`, or `click` event that caused this function to be
- * called.
- *
- * @listens tap
- * @listens click
- */
-
-
- FullscreenToggle.prototype.handleClick = function handleClick(event) {
- if (!this.player_.isFullscreen()) {
- this.player_.requestFullscreen();
- } else {
- this.player_.exitFullscreen();
- }
- };
-
- return FullscreenToggle;
- }(Button);
-
- /**
- * The text that should display over the `FullscreenToggle`s controls. Added for localization.
- *
- * @type {string}
- * @private
- */
-
-
- FullscreenToggle.prototype.controlText_ = 'Fullscreen';
-
- Component.registerComponent('FullscreenToggle', FullscreenToggle);
-
- /**
- * Check if volume control is supported and if it isn't hide the
- * `Component` that was passed using the `vjs-hidden` class.
- *
- * @param {Component} self
- * The component that should be hidden if volume is unsupported
- *
- * @param {Player} player
- * A reference to the player
- *
- * @private
- */
- var checkVolumeSupport = function checkVolumeSupport(self, player) {
- // hide volume controls when they're not supported by the current tech
- if (player.tech_ && !player.tech_.featuresVolumeControl) {
- self.addClass('vjs-hidden');
- }
-
- self.on(player, 'loadstart', function () {
- if (!player.tech_.featuresVolumeControl) {
- self.addClass('vjs-hidden');
- } else {
- self.removeClass('vjs-hidden');
- }
- });
- };
-
- /**
- * @file volume-level.js
- */
- /**
- * Shows volume level
- *
- * @extends Component
- */
-
- var VolumeLevel = function (_Component) {
- inherits(VolumeLevel, _Component);
-
- function VolumeLevel() {
- classCallCheck(this, VolumeLevel);
- return possibleConstructorReturn(this, _Component.apply(this, arguments));
- }
-
- /**
- * Create the `Component`'s DOM element
- *
- * @return {Element}
- * The element that was created.
- */
- 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;
- }(Component);
-
- Component.registerComponent('VolumeLevel', VolumeLevel);
-
- /**
- * @file volume-bar.js
- */
-// Required children
- /**
- * The bar that contains the volume level and can be clicked on to adjust the level
- *
- * @extends Slider
- */
-
- var VolumeBar = function (_Slider) {
- inherits(VolumeBar, _Slider);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function VolumeBar(player, options) {
- classCallCheck(this, VolumeBar);
-
- var _this = possibleConstructorReturn(this, _Slider.call(this, player, options));
-
- _this.on('slideractive', _this.updateLastVolume_);
- _this.on(player, 'volumechange', _this.updateARIAAttributes);
- player.ready(function () {
- return _this.updateARIAAttributes();
- });
- return _this;
- }
-
- /**
- * Create the `Component`'s DOM element
- *
- * @return {Element}
- * The element that was created.
- */
-
-
- VolumeBar.prototype.createEl = function createEl() {
- return _Slider.prototype.createEl.call(this, 'div', {
- className: 'vjs-volume-bar vjs-slider-bar'
- }, {
- 'aria-label': this.localize('Volume Level'),
- 'aria-live': 'polite'
- });
- };
-
- /**
- * Handle movement events on the {@link VolumeMenuButton}.
- *
- * @param {EventTarget~Event} event
- * The event that caused this function to run.
- *
- * @listens mousemove
- */
-
-
- VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) {
- this.checkMuted();
- this.player_.volume(this.calculateDistance(event));
- };
-
- /**
- * If the player is muted unmute it.
- */
-
-
- VolumeBar.prototype.checkMuted = function checkMuted() {
- if (this.player_.muted()) {
- this.player_.muted(false);
- }
- };
-
- /**
- * Get percent of volume level
- *
- * @return {number}
- * Volume level percent as a decimal number.
- */
-
-
- VolumeBar.prototype.getPercent = function getPercent() {
- if (this.player_.muted()) {
- return 0;
- }
- return this.player_.volume();
- };
-
- /**
- * Increase volume level for keyboard users
- */
-
-
- VolumeBar.prototype.stepForward = function stepForward() {
- this.checkMuted();
- this.player_.volume(this.player_.volume() + 0.1);
- };
-
- /**
- * Decrease volume level for keyboard users
- */
-
-
- VolumeBar.prototype.stepBack = function stepBack() {
- this.checkMuted();
- this.player_.volume(this.player_.volume() - 0.1);
- };
-
- /**
- * Update ARIA accessibility attributes
- *
- * @param {EventTarget~Event} [event]
- * The `volumechange` event that caused this function to run.
- *
- * @listens Player#volumechange
- */
-
-
- VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes(event) {
- var ariaValue = this.player_.muted() ? 0 : this.volumeAsPercentage_();
-
- this.el_.setAttribute('aria-valuenow', ariaValue);
- this.el_.setAttribute('aria-valuetext', ariaValue + '%');
- };
-
- /**
- * Returns the current value of the player volume as a percentage
- *
- * @private
- */
-
-
- VolumeBar.prototype.volumeAsPercentage_ = function volumeAsPercentage_() {
- return Math.round(this.player_.volume() * 100);
- };
-
- /**
- * When user starts dragging the VolumeBar, store the volume and listen for
- * the end of the drag. When the drag ends, if the volume was set to zero,
- * set lastVolume to the stored volume.
- *
- * @listens slideractive
- * @private
- */
-
-
- VolumeBar.prototype.updateLastVolume_ = function updateLastVolume_() {
- var _this2 = this;
-
- var volumeBeforeDrag = this.player_.volume();
-
- this.one('sliderinactive', function () {
- if (_this2.player_.volume() === 0) {
- _this2.player_.lastVolume_(volumeBeforeDrag);
- }
- });
- };
-
- return VolumeBar;
- }(Slider);
-
- /**
- * Default options for the `VolumeBar`
- *
- * @type {Object}
- * @private
- */
-
-
- VolumeBar.prototype.options_ = {
- children: ['volumeLevel'],
- barName: 'volumeLevel'
- };
-
- /**
- * Call the update event for this Slider when this event happens on the player.
- *
- * @type {string}
- */
- VolumeBar.prototype.playerEvent = 'volumechange';
-
- Component.registerComponent('VolumeBar', VolumeBar);
-
- /**
- * @file volume-control.js
- */
-// Required children
- /**
- * The component for controlling the volume level
- *
- * @extends Component
- */
-
- var VolumeControl = function (_Component) {
- inherits(VolumeControl, _Component);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options={}]
- * The key/value store of player options.
- */
- function VolumeControl(player) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- classCallCheck(this, VolumeControl);
-
- options.vertical = options.vertical || false;
-
- // Pass the vertical option down to the VolumeBar if
- // the VolumeBar is turned on.
- if (typeof options.volumeBar === 'undefined' || isPlain(options.volumeBar)) {
- options.volumeBar = options.volumeBar || {};
- options.volumeBar.vertical = options.vertical;
- }
-
- // hide this control if volume support is missing
- var _this = possibleConstructorReturn(this, _Component.call(this, player, options));
-
- checkVolumeSupport(_this, player);
-
- _this.throttledHandleMouseMove = throttle(bind(_this, _this.handleMouseMove), 25);
-
- _this.on('mousedown', _this.handleMouseDown);
- _this.on('touchstart', _this.handleMouseDown);
-
- // while the slider is active (the mouse has been pressed down and
- // is dragging) or in focus we do not want to hide the VolumeBar
- _this.on(_this.volumeBar, ['focus', 'slideractive'], function () {
- _this.volumeBar.addClass('vjs-slider-active');
- _this.addClass('vjs-slider-active');
- _this.trigger('slideractive');
- });
-
- _this.on(_this.volumeBar, ['blur', 'sliderinactive'], function () {
- _this.volumeBar.removeClass('vjs-slider-active');
- _this.removeClass('vjs-slider-active');
- _this.trigger('sliderinactive');
- });
- return _this;
- }
-
- /**
- * Create the `Component`'s DOM element
- *
- * @return {Element}
- * The element that was created.
- */
-
-
- VolumeControl.prototype.createEl = function createEl() {
- var orientationClass = 'vjs-volume-horizontal';
-
- if (this.options_.vertical) {
- orientationClass = 'vjs-volume-vertical';
- }
-
- return _Component.prototype.createEl.call(this, 'div', {
- className: 'vjs-volume-control vjs-control ' + orientationClass
- });
- };
-
- /**
- * Handle `mousedown` or `touchstart` events on the `VolumeControl`.
- *
- * @param {EventTarget~Event} event
- * `mousedown` or `touchstart` event that triggered this function
- *
- * @listens mousedown
- * @listens touchstart
- */
-
-
- VolumeControl.prototype.handleMouseDown = function handleMouseDown(event) {
- var doc = this.el_.ownerDocument;
-
- this.on(doc, 'mousemove', this.throttledHandleMouseMove);
- this.on(doc, 'touchmove', this.throttledHandleMouseMove);
- this.on(doc, 'mouseup', this.handleMouseUp);
- this.on(doc, 'touchend', this.handleMouseUp);
- };
-
- /**
- * Handle `mouseup` or `touchend` events on the `VolumeControl`.
- *
- * @param {EventTarget~Event} event
- * `mouseup` or `touchend` event that triggered this function.
- *
- * @listens touchend
- * @listens mouseup
- */
-
-
- VolumeControl.prototype.handleMouseUp = function handleMouseUp(event) {
- var doc = this.el_.ownerDocument;
-
- this.off(doc, 'mousemove', this.throttledHandleMouseMove);
- this.off(doc, 'touchmove', this.throttledHandleMouseMove);
- this.off(doc, 'mouseup', this.handleMouseUp);
- this.off(doc, 'touchend', this.handleMouseUp);
- };
-
- /**
- * Handle `mousedown` or `touchstart` events on the `VolumeControl`.
- *
- * @param {EventTarget~Event} event
- * `mousedown` or `touchstart` event that triggered this function
- *
- * @listens mousedown
- * @listens touchstart
- */
-
-
- VolumeControl.prototype.handleMouseMove = function handleMouseMove(event) {
- this.volumeBar.handleMouseMove(event);
- };
-
- return VolumeControl;
- }(Component);
-
- /**
- * Default options for the `VolumeControl`
- *
- * @type {Object}
- * @private
- */
-
-
- VolumeControl.prototype.options_ = {
- children: ['volumeBar']
- };
-
- Component.registerComponent('VolumeControl', VolumeControl);
-
- /**
- * @file mute-toggle.js
- */
- /**
- * A button component for muting the audio.
- *
- * @extends Button
- */
-
- var MuteToggle = function (_Button) {
- inherits(MuteToggle, _Button);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function MuteToggle(player, options) {
- classCallCheck(this, MuteToggle);
-
- // hide this control if volume support is missing
- var _this = possibleConstructorReturn(this, _Button.call(this, player, options));
-
- checkVolumeSupport(_this, player);
-
- _this.on(player, ['loadstart', 'volumechange'], _this.update);
- return _this;
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- MuteToggle.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this);
- };
-
- /**
- * This gets called when an `MuteToggle` is "clicked". See
- * {@link ClickableComponent} for more detailed information on what a click can be.
- *
- * @param {EventTarget~Event} [event]
- * The `keydown`, `tap`, or `click` event that caused this function to be
- * called.
- *
- * @listens tap
- * @listens click
- */
-
-
- MuteToggle.prototype.handleClick = function handleClick(event) {
- var vol = this.player_.volume();
- var lastVolume = this.player_.lastVolume_();
-
- if (vol === 0) {
- var volumeToSet = lastVolume < 0.1 ? 0.1 : lastVolume;
-
- this.player_.volume(volumeToSet);
- this.player_.muted(false);
- } else {
- this.player_.muted(this.player_.muted() ? false : true);
- }
- };
-
- /**
- * Update the `MuteToggle` button based on the state of `volume` and `muted`
- * on the player.
- *
- * @param {EventTarget~Event} [event]
- * The {@link Player#loadstart} event if this function was called
- * through an event.
- *
- * @listens Player#loadstart
- * @listens Player#volumechange
- */
-
-
- MuteToggle.prototype.update = function update(event) {
- this.updateIcon_();
- this.updateControlText_();
- };
-
- /**
- * Update the appearance of the `MuteToggle` icon.
- *
- * Possible states (given `level` variable below):
- * - 0: crossed out
- * - 1: zero bars of volume
- * - 2: one bar of volume
- * - 3: two bars of volume
- *
- * @private
- */
-
-
- MuteToggle.prototype.updateIcon_ = function updateIcon_() {
- var vol = this.player_.volume();
- var level = 3;
-
- if (vol === 0 || this.player_.muted()) {
- level = 0;
- } else if (vol < 0.33) {
- level = 1;
- } else if (vol < 0.67) {
- level = 2;
- }
-
- // TODO improve muted icon classes
- for (var i = 0; i < 4; i++) {
- removeClass(this.el_, 'vjs-vol-' + i);
- }
- addClass(this.el_, 'vjs-vol-' + level);
- };
-
- /**
- * If `muted` has changed on the player, update the control text
- * (`title` attribute on `vjs-mute-control` element and content of
- * `vjs-control-text` element).
- *
- * @private
- */
-
-
- MuteToggle.prototype.updateControlText_ = function updateControlText_() {
- var soundOff = this.player_.muted() || this.player_.volume() === 0;
- var text = soundOff ? 'Unmute' : 'Mute';
-
- if (this.controlText() !== text) {
- this.controlText(text);
- }
- };
-
- return MuteToggle;
- }(Button);
-
- /**
- * The text that should display over the `MuteToggle`s controls. Added for localization.
- *
- * @type {string}
- * @private
- */
-
-
- MuteToggle.prototype.controlText_ = 'Mute';
-
- Component.registerComponent('MuteToggle', MuteToggle);
-
- /**
- * @file volume-control.js
- */
-// Required children
- /**
- * A Component to contain the MuteToggle and VolumeControl so that
- * they can work together.
- *
- * @extends Component
- */
-
- var VolumePanel = function (_Component) {
- inherits(VolumePanel, _Component);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options={}]
- * The key/value store of player options.
- */
- function VolumePanel(player) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- classCallCheck(this, VolumePanel);
-
- if (typeof options.inline !== 'undefined') {
- options.inline = options.inline;
- } else {
- options.inline = true;
- }
-
- // pass the inline option down to the VolumeControl as vertical if
- // the VolumeControl is on.
- if (typeof options.volumeControl === 'undefined' || isPlain(options.volumeControl)) {
- options.volumeControl = options.volumeControl || {};
- options.volumeControl.vertical = !options.inline;
- }
-
- // hide this control if volume support is missing
- var _this = possibleConstructorReturn(this, _Component.call(this, player, options));
-
- checkVolumeSupport(_this, player);
-
- // while the slider is active (the mouse has been pressed down and
- // is dragging) or in focus we do not want to hide the VolumeBar
- _this.on(_this.volumeControl, ['slideractive'], _this.sliderActive_);
- _this.on(_this.muteToggle, 'focus', _this.sliderActive_);
-
- _this.on(_this.volumeControl, ['sliderinactive'], _this.sliderInactive_);
- _this.on(_this.muteToggle, 'blur', _this.sliderInactive_);
- return _this;
- }
-
- /**
- * Add vjs-slider-active class to the VolumePanel
- *
- * @listens VolumeControl#slideractive
- * @private
- */
-
-
- VolumePanel.prototype.sliderActive_ = function sliderActive_() {
- this.addClass('vjs-slider-active');
- };
-
- /**
- * Removes vjs-slider-active class to the VolumePanel
- *
- * @listens VolumeControl#sliderinactive
- * @private
- */
-
-
- VolumePanel.prototype.sliderInactive_ = function sliderInactive_() {
- this.removeClass('vjs-slider-active');
- };
-
- /**
- * Create the `Component`'s DOM element
- *
- * @return {Element}
- * The element that was created.
- */
-
-
- VolumePanel.prototype.createEl = function createEl() {
- var orientationClass = 'vjs-volume-panel-horizontal';
-
- if (!this.options_.inline) {
- orientationClass = 'vjs-volume-panel-vertical';
- }
-
- return _Component.prototype.createEl.call(this, 'div', {
- className: 'vjs-volume-panel vjs-control ' + orientationClass
- });
- };
-
- return VolumePanel;
- }(Component);
-
- /**
- * Default options for the `VolumeControl`
- *
- * @type {Object}
- * @private
- */
-
-
- VolumePanel.prototype.options_ = {
- children: ['muteToggle', 'volumeControl']
- };
-
- Component.registerComponent('VolumePanel', VolumePanel);
-
- /**
- * @file menu.js
- */
- /**
- * The Menu component is used to build popup menus, including subtitle and
- * captions selection menus.
- *
- * @extends Component
- */
-
- var Menu = function (_Component) {
- inherits(Menu, _Component);
-
- /**
- * Create an instance of this class.
- *
- * @param {Player} player
- * the player that this component should attach to
- *
- * @param {Object} [options]
- * Object of option names and values
- *
- */
- function Menu(player, options) {
- classCallCheck(this, Menu);
-
- var _this = possibleConstructorReturn(this, _Component.call(this, player, options));
-
- if (options) {
- _this.menuButton_ = options.menuButton;
- }
-
- _this.focusedChild_ = -1;
-
- _this.on('keydown', _this.handleKeyPress);
- return _this;
- }
-
- /**
- * Add a {@link MenuItem} to the menu.
- *
- * @param {Object|string} component
- * The name or instance of the `MenuItem` to add.
- *
- */
-
-
- Menu.prototype.addItem = function addItem(component) {
- this.addChild(component);
- component.on('click', bind(this, function (event) {
- // Unpress the associated MenuButton, and move focus back to it
- if (this.menuButton_) {
- this.menuButton_.unpressButton();
-
- // don't focus menu button if item is a caption settings item
- // because focus will move elsewhere and it logs an error on IE8
- if (component.name() !== 'CaptionSettingsMenuItem') {
- this.menuButton_.focus();
- }
- }
- }));
- };
-
- /**
- * Create the `Menu`s DOM element.
- *
- * @return {Element}
- * the element that was created
- */
-
-
- Menu.prototype.createEl = function createEl$$1() {
- var contentElType = this.options_.contentElType || 'ul';
-
- this.contentEl_ = 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.appendChild(this.contentEl_);
-
- // Prevent clicks from bubbling up. Needed for Menu Buttons,
- // where a click on the parent is significant
- on(el, 'click', function (event) {
- event.preventDefault();
- event.stopImmediatePropagation();
- });
-
- return el;
- };
-
- /**
- * Handle a `keydown` event on this menu. This listener is added in the constructor.
- *
- * @param {EventTarget~Event} event
- * A `keydown` event that happened on the menu.
- *
- * @listens keydown
- */
-
-
- Menu.prototype.handleKeyPress = function handleKeyPress(event) {
- // Left and Down Arrows
- if (event.which === 37 || event.which === 40) {
- event.preventDefault();
- this.stepForward();
-
- // Up and Right Arrows
- } else if (event.which === 38 || event.which === 39) {
- event.preventDefault();
- this.stepBack();
- }
- };
-
- /**
- * Move to next (lower) menu item for keyboard users.
- */
-
-
- 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.
- */
-
-
- Menu.prototype.stepBack = function stepBack() {
- var stepChild = 0;
-
- if (this.focusedChild_ !== undefined) {
- stepChild = this.focusedChild_ - 1;
- }
- this.focus(stepChild);
- };
-
- /**
- * Set focus on a {@link MenuItem} in the `Menu`.
- *
- * @param {Object|string} [item=0]
- * Index of child item set focus on.
- */
-
-
- Menu.prototype.focus = function focus() {
- var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 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;
- }(Component);
-
- Component.registerComponent('Menu', Menu);
-
- /**
- * @file menu-button.js
- */
- /**
- * A `MenuButton` class for any popup {@link Menu}.
- *
- * @extends Component
- */
-
- var MenuButton = function (_Component) {
- inherits(MenuButton, _Component);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options={}]
- * The key/value store of player options.
- */
- function MenuButton(player) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- classCallCheck(this, MenuButton);
-
- var _this = possibleConstructorReturn(this, _Component.call(this, player, options));
-
- _this.menuButton_ = new Button(player, options);
-
- _this.menuButton_.controlText(_this.controlText_);
- _this.menuButton_.el_.setAttribute('aria-haspopup', 'true');
-
- // Add buildCSSClass values to the button, not the wrapper
- var buttonClass = Button.prototype.buildCSSClass();
-
- _this.menuButton_.el_.className = _this.buildCSSClass() + ' ' + buttonClass;
- _this.menuButton_.removeClass('vjs-control');
-
- _this.addChild(_this.menuButton_);
-
- _this.update();
-
- _this.enabled_ = true;
-
- _this.on(_this.menuButton_, 'tap', _this.handleClick);
- _this.on(_this.menuButton_, 'click', _this.handleClick);
- _this.on(_this.menuButton_, 'focus', _this.handleFocus);
- _this.on(_this.menuButton_, 'blur', _this.handleBlur);
-
- _this.on('keydown', _this.handleSubmenuKeyPress);
- return _this;
- }
-
- /**
- * Update the menu based on the current state of its items.
- */
-
-
- 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.menuButton_.el_.setAttribute('aria-expanded', 'false');
-
- if (this.items && this.items.length <= this.hideThreshold_) {
- this.hide();
- } else {
- this.show();
- }
- };
-
- /**
- * Create the menu and add all items to it.
- *
- * @return {Menu}
- * The constructed menu
- */
-
-
- MenuButton.prototype.createMenu = function createMenu() {
- var menu = new Menu(this.player_, {menuButton: this});
-
- /**
- * Hide the menu if the number of items is less than or equal to this threshold. This defaults
- * to 0 and whenever we add items which can be hidden to the menu we'll increment it. We list
- * it here because every time we run `createMenu` we need to reset the value.
- *
- * @protected
- * @type {Number}
- */
- this.hideThreshold_ = 0;
-
- // Add a title list item to the top
- if (this.options_.title) {
- var title = createEl('li', {
- className: 'vjs-menu-title',
- innerHTML: toTitleCase(this.options_.title),
- tabIndex: -1
- });
-
- this.hideThreshold_ += 1;
-
- menu.children_.unshift(title);
- prependTo(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.
- *
- * @abstract
- */
-
-
- MenuButton.prototype.createItems = function createItems() {
- };
-
- /**
- * Create the `MenuButtons`s DOM element.
- *
- * @return {Element}
- * The element that gets created.
- */
-
-
- MenuButton.prototype.createEl = function createEl$$1() {
- return _Component.prototype.createEl.call(this, 'div', {
- className: this.buildWrapperCSSClass()
- }, {});
- };
-
- /**
- * Allow sub components to stack CSS class names for the wrapper element
- *
- * @return {string}
- * The constructed wrapper DOM `className`
- */
-
-
- MenuButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
- 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';
- }
-
- // TODO: Fix the CSS so that this isn't necessary
- var buttonClass = Button.prototype.buildCSSClass();
-
- return 'vjs-menu-button ' + menuButtonClass + ' ' + buttonClass + ' ' + _Component.prototype.buildCSSClass.call(this);
- };
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- 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 + ' ' + _Component.prototype.buildCSSClass.call(this);
- };
-
- /**
- * Get or set the localized control text that will be used for accessibility.
- *
- * > NOTE: This will come from the internal `menuButton_` element.
- *
- * @param {string} [text]
- * Control text for element.
- *
- * @param {Element} [el=this.menuButton_.el()]
- * Element to set the title on.
- *
- * @return {string}
- * - The control text when getting
- */
-
-
- MenuButton.prototype.controlText = function controlText(text) {
- var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.menuButton_.el();
-
- return this.menuButton_.controlText(text, el);
- };
-
- /**
- * Handle a click on a `MenuButton`.
- * See {@link ClickableComponent#handleClick} for instances where this is called.
- *
- * @param {EventTarget~Event} event
- * The `keydown`, `tap`, or `click` event that caused this function to be
- * called.
- *
- * @listens tap
- * @listens click
- */
-
-
- MenuButton.prototype.handleClick = function handleClick(event) {
- // When you click the button it adds focus, which will show the menu.
- // So we'll remove focus when the mouse leaves the button. Focus is needed
- // for tab navigation.
-
- this.one(this.menu.contentEl(), 'mouseleave', bind(this, function (e) {
- this.unpressButton();
- this.el_.blur();
- }));
- if (this.buttonPressed_) {
- this.unpressButton();
- } else {
- this.pressButton();
- }
- };
-
- /**
- * Set the focus to the actual button, not to this element
- */
-
-
- MenuButton.prototype.focus = function focus() {
- this.menuButton_.focus();
- };
-
- /**
- * Remove the focus from the actual button, not this element
- */
-
-
- MenuButton.prototype.blur = function blur() {
- this.menuButton_.blur();
- };
-
- /**
- * This gets called when a `MenuButton` gains focus via a `focus` event.
- * Turns on listening for `keydown` events. When they happen it
- * calls `this.handleKeyPress`.
- *
- * @param {EventTarget~Event} event
- * The `focus` event that caused this function to be called.
- *
- * @listens focus
- */
-
-
- MenuButton.prototype.handleFocus = function handleFocus() {
- on(document_1, 'keydown', bind(this, this.handleKeyPress));
- };
-
- /**
- * Called when a `MenuButton` loses focus. Turns off the listener for
- * `keydown` events. Which Stops `this.handleKeyPress` from getting called.
- *
- * @param {EventTarget~Event} event
- * The `blur` event that caused this function to be called.
- *
- * @listens blur
- */
-
-
- MenuButton.prototype.handleBlur = function handleBlur() {
- off(document_1, 'keydown', bind(this, this.handleKeyPress));
- };
-
- /**
- * Handle tab, escape, down arrow, and up arrow keys for `MenuButton`. See
- * {@link ClickableComponent#handleKeyPress} for instances where this is called.
- *
- * @param {EventTarget~Event} event
- * The `keydown` event that caused this function to be called.
- *
- * @listens keydown
- */
-
-
- 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();
- // Set focus back to the menu button's button
- this.menuButton_.el_.focus();
- }
- // 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();
- }
- }
- };
-
- /**
- * Handle a `keydown` event on a sub-menu. The listener for this is added in
- * the constructor.
- *
- * @param {EventTarget~Event} event
- * Key press event
- *
- * @listens keydown
- */
-
-
- 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();
- // Set focus back to the menu button's button
- this.menuButton_.el_.focus();
- }
- }
- };
-
- /**
- * Put the current `MenuButton` into a pressed state.
- */
-
-
- MenuButton.prototype.pressButton = function pressButton() {
- if (this.enabled_) {
- this.buttonPressed_ = true;
- this.menu.lockShowing();
- this.menuButton_.el_.setAttribute('aria-expanded', 'true');
-
- // set the focus into the submenu, except on iOS where it is resulting in
- // undesired scrolling behavior when the player is in an iframe
- if (!IS_IOS && !isInFrame()) {
- this.menu.focus();
- }
- }
- };
-
- /**
- * Take the current `MenuButton` out of a pressed state.
- */
-
-
- MenuButton.prototype.unpressButton = function unpressButton() {
- if (this.enabled_) {
- this.buttonPressed_ = false;
- this.menu.unlockShowing();
- this.menuButton_.el_.setAttribute('aria-expanded', 'false');
- }
- };
-
- /**
- * Disable the `MenuButton`. Don't allow it to be clicked.
- */
-
-
- MenuButton.prototype.disable = function disable() {
- this.unpressButton();
-
- this.enabled_ = false;
- this.addClass('vjs-disabled');
-
- this.menuButton_.disable();
- };
-
- /**
- * Enable the `MenuButton`. Allow it to be clicked.
- */
-
-
- MenuButton.prototype.enable = function enable() {
- this.enabled_ = true;
- this.removeClass('vjs-disabled');
-
- this.menuButton_.enable();
- };
-
- return MenuButton;
- }(Component);
-
- Component.registerComponent('MenuButton', MenuButton);
-
- /**
- * @file track-button.js
- */
- /**
- * The base class for buttons that toggle specific track types (e.g. subtitles).
- *
- * @extends MenuButton
- */
-
- var TrackButton = function (_MenuButton) {
- inherits(TrackButton, _MenuButton);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function TrackButton(player, options) {
- classCallCheck(this, TrackButton);
-
- var tracks = options.tracks;
-
- var _this = possibleConstructorReturn(this, _MenuButton.call(this, player, options));
-
- if (_this.items.length <= 1) {
- _this.hide();
- }
-
- if (!tracks) {
- return possibleConstructorReturn(_this);
- }
-
- var updateHandler = bind(_this, _this.update);
-
- tracks.addEventListener('removetrack', updateHandler);
- tracks.addEventListener('addtrack', updateHandler);
- _this.player_.on('ready', updateHandler);
-
- _this.player_.on('dispose', function () {
- tracks.removeEventListener('removetrack', updateHandler);
- tracks.removeEventListener('addtrack', updateHandler);
- });
- return _this;
- }
-
- return TrackButton;
- }(MenuButton);
-
- Component.registerComponent('TrackButton', TrackButton);
-
- /**
- * @file menu-item.js
- */
- /**
- * The component for a menu item. `<li>`
- *
- * @extends ClickableComponent
- */
-
- var MenuItem = function (_ClickableComponent) {
- inherits(MenuItem, _ClickableComponent);
-
- /**
- * Creates an instance of the this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options={}]
- * The key/value store of player options.
- *
- */
- function MenuItem(player, options) {
- classCallCheck(this, MenuItem);
-
- var _this = possibleConstructorReturn(this, _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');
- }
- return _this;
- }
-
- /**
- * Create the `MenuItem's DOM element
- *
- * @param {string} [type=li]
- * Element's node type, not actually used, always set to `li`.
- *
- * @param {Object} [props={}]
- * An object of properties that should be set on the element
- *
- * @param {Object} [attrs={}]
- * An object of attributes that should be set on the element
- *
- * @return {Element}
- * The element that gets created.
- */
-
-
- MenuItem.prototype.createEl = function createEl(type, props, attrs) {
- // The control is textual, not just an icon
- this.nonIconControl = true;
-
- return _ClickableComponent.prototype.createEl.call(this, 'li', assign({
- className: 'vjs-menu-item',
- innerHTML: '<span class="vjs-menu-item-text">' + this.localize(this.options_.label) + '</span>',
- tabIndex: -1
- }, props), attrs);
- };
-
- /**
- * Any click on a `MenuItem` puts int into the selected state.
- * See {@link ClickableComponent#handleClick} for instances where this is called.
- *
- * @param {EventTarget~Event} event
- * The `keydown`, `tap`, or `click` event that caused this function to be
- * called.
- *
- * @listens tap
- * @listens click
- */
-
-
- MenuItem.prototype.handleClick = function handleClick(event) {
- this.selected(true);
- };
-
- /**
- * Set the state for this menu item as selected or not.
- *
- * @param {boolean} selected
- * if the menu item is selected or not
- */
-
-
- 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;
- }(ClickableComponent);
-
- Component.registerComponent('MenuItem', MenuItem);
-
- /**
- * @file text-track-menu-item.js
- */
- /**
- * The specific menu item type for selecting a language within a text track kind
- *
- * @extends MenuItem
- */
-
- var TextTrackMenuItem = function (_MenuItem) {
- inherits(TextTrackMenuItem, _MenuItem);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function TextTrackMenuItem(player, options) {
- 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.mode === 'showing';
-
- var _this = possibleConstructorReturn(this, _MenuItem.call(this, player, options));
-
- _this.track = track;
- var changeHandler = bind(_this, _this.handleTracksChange);
- var selectedLanguageChangeHandler = bind(_this, _this.handleSelectedLanguageChange);
-
- player.on(['loadstart', 'texttrackchange'], changeHandler);
- tracks.addEventListener('change', changeHandler);
- tracks.addEventListener('selectedlanguagechange', selectedLanguageChangeHandler);
- _this.on('dispose', function () {
- tracks.removeEventListener('change', changeHandler);
- tracks.removeEventListener('selectedlanguagechange', selectedLanguageChangeHandler);
- });
-
- // 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.onchange === undefined) {
- var event = void 0;
-
- _this.on(['tap', 'click'], function () {
- if (_typeof(window_1.Event) !== 'object') {
- // Android 2.3 throws an Illegal Constructor error for window.Event
- try {
- event = new window_1.Event('change');
- } catch (err) {
- // continue regardless of error
- }
- }
-
- if (!event) {
- event = document_1.createEvent('Event');
- event.initEvent('change', true, true);
- }
-
- tracks.dispatchEvent(event);
- });
- }
- return _this;
- }
-
- /**
- * This gets called when an `TextTrackMenuItem` is "clicked". See
- * {@link ClickableComponent} for more detailed information on what a click can be.
- *
- * @param {EventTarget~Event} event
- * The `keydown`, `tap`, or `click` event that caused this function to be
- * called.
- *
- * @listens tap
- * @listens click
- */
-
-
- TextTrackMenuItem.prototype.handleClick = function handleClick(event) {
- var kind = this.track.kind;
- var kinds = this.track.kinds;
- var tracks = this.player_.textTracks();
-
- if (!kinds) {
- kinds = [kind];
- }
-
- _MenuItem.prototype.handleClick.call(this, event);
-
- if (!tracks) {
- return;
- }
-
- for (var i = 0; i < tracks.length; i++) {
- var track = tracks[i];
-
- if (track === this.track && kinds.indexOf(track.kind) > -1) {
- if (track.mode !== 'showing') {
- track.mode = 'showing';
- }
- } else if (track.mode !== 'disabled') {
- track.mode = 'disabled';
- }
- }
- };
-
- /**
- * Handle text track list change
- *
- * @param {EventTarget~Event} event
- * The `change` event that caused this function to be called.
- *
- * @listens TextTrackList#change
- */
-
-
- TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
- this.selected(this.track.mode === 'showing');
- };
-
- TextTrackMenuItem.prototype.handleSelectedLanguageChange = function handleSelectedLanguageChange(event) {
- if (this.track.mode === 'showing') {
- var selectedLanguage = this.player_.cache_.selectedLanguage;
-
- // Don't replace the kind of track across the same language
- if (selectedLanguage && selectedLanguage.enabled && selectedLanguage.language === this.track.language && selectedLanguage.kind !== this.track.kind) {
- return;
- }
-
- this.player_.cache_.selectedLanguage = {
- enabled: true,
- language: this.track.language,
- kind: this.track.kind
- };
- }
- };
-
- return TextTrackMenuItem;
- }(MenuItem);
-
- Component.registerComponent('TextTrackMenuItem', TextTrackMenuItem);
-
- /**
- * @file off-text-track-menu-item.js
- */
- /**
- * A special menu item for turning of a specific type of text track
- *
- * @extends TextTrackMenuItem
- */
-
- var OffTextTrackMenuItem = function (_TextTrackMenuItem) {
- inherits(OffTextTrackMenuItem, _TextTrackMenuItem);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function OffTextTrackMenuItem(player, options) {
- classCallCheck(this, OffTextTrackMenuItem);
-
- // Create pseudo track info
- // Requires options['kind']
- options.track = {
- player: player,
- kind: options.kind,
- kinds: options.kinds,
- 'default': false,
- mode: 'disabled'
- };
-
- if (!options.kinds) {
- options.kinds = [options.kind];
- }
-
- if (options.label) {
- options.track.label = options.label;
- } else {
- options.track.label = options.kinds.join(' and ') + ' off';
- }
-
- // MenuItem is selectable
- options.selectable = true;
-
- var _this = possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
-
- _this.selected(true);
- return _this;
- }
-
- /**
- * Handle text track change
- *
- * @param {EventTarget~Event} event
- * The event that caused this function to run
- */
-
-
- 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 (this.options_.kinds.indexOf(track.kind) > -1 && track.mode === 'showing') {
- selected = false;
- break;
- }
- }
-
- this.selected(selected);
- };
-
- OffTextTrackMenuItem.prototype.handleSelectedLanguageChange = function handleSelectedLanguageChange(event) {
- var tracks = this.player().textTracks();
- var allHidden = true;
-
- for (var i = 0, l = tracks.length; i < l; i++) {
- var track = tracks[i];
-
- if (['captions', 'descriptions', 'subtitles'].indexOf(track.kind) > -1 && track.mode === 'showing') {
- allHidden = false;
- break;
- }
- }
-
- if (allHidden) {
- this.player_.cache_.selectedLanguage = {
- enabled: false
- };
- }
- };
-
- return OffTextTrackMenuItem;
- }(TextTrackMenuItem);
-
- Component.registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem);
-
- /**
- * @file text-track-button.js
- */
- /**
- * The base class for buttons that toggle specific text track types (e.g. subtitles)
- *
- * @extends MenuButton
- */
-
- var TextTrackButton = function (_TrackButton) {
- inherits(TextTrackButton, _TrackButton);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options={}]
- * The key/value store of player options.
- */
- function TextTrackButton(player) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- classCallCheck(this, TextTrackButton);
-
- options.tracks = player.textTracks();
-
- return possibleConstructorReturn(this, _TrackButton.call(this, player, options));
- }
-
- /**
- * Create a menu item for each text track
- *
- * @param {TextTrackMenuItem[]} [items=[]]
- * Existing array of items to use during creation
- *
- * @return {TextTrackMenuItem[]}
- * Array of menu items that were created
- */
-
-
- TextTrackButton.prototype.createItems = function createItems() {
- var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
- var TrackMenuItem = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : TextTrackMenuItem;
-
-
- // Label is an overide for the [track] off label
- // USed to localise captions/subtitles
- var label = void 0;
-
- if (this.label_) {
- label = this.label_ + ' off';
- }
- // Add an OFF menu item to turn all tracks off
- items.push(new OffTextTrackMenuItem(this.player_, {
- kinds: this.kinds_,
- kind: this.kind_,
- label: label
- }));
-
- this.hideThreshold_ += 1;
-
- var tracks = this.player_.textTracks();
-
- if (!Array.isArray(this.kinds_)) {
- this.kinds_ = [this.kind_];
- }
-
- for (var i = 0; i < tracks.length; i++) {
- var track = tracks[i];
-
- // only add tracks that are of an appropriate kind and have a label
- if (this.kinds_.indexOf(track.kind) > -1) {
-
- var item = new TrackMenuItem(this.player_, {
- track: track,
- // MenuItem is selectable
- selectable: true
- });
-
- item.addClass('vjs-' + track.kind + '-menu-item');
- items.push(item);
- }
- }
-
- return items;
- };
-
- return TextTrackButton;
- }(TrackButton);
-
- Component.registerComponent('TextTrackButton', TextTrackButton);
-
- /**
- * @file chapters-track-menu-item.js
- */
- /**
- * The chapter track menu item
- *
- * @extends MenuItem
- */
-
- var ChaptersTrackMenuItem = function (_MenuItem) {
- inherits(ChaptersTrackMenuItem, _MenuItem);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- 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.selectable = true;
- options.label = cue.text;
- options.selected = cue.startTime <= currentTime && currentTime < cue.endTime;
-
- var _this = possibleConstructorReturn(this, _MenuItem.call(this, player, options));
-
- _this.track = track;
- _this.cue = cue;
- track.addEventListener('cuechange', bind(_this, _this.update));
- return _this;
- }
-
- /**
- * This gets called when an `ChaptersTrackMenuItem` is "clicked". See
- * {@link ClickableComponent} for more detailed information on what a click can be.
- *
- * @param {EventTarget~Event} [event]
- * The `keydown`, `tap`, or `click` event that caused this function to be
- * called.
- *
- * @listens tap
- * @listens click
- */
-
-
- ChaptersTrackMenuItem.prototype.handleClick = function handleClick(event) {
- _MenuItem.prototype.handleClick.call(this);
- this.player_.currentTime(this.cue.startTime);
- this.update(this.cue.startTime);
- };
-
- /**
- * Update chapter menu item
- *
- * @param {EventTarget~Event} [event]
- * The `cuechange` event that caused this function to run.
- *
- * @listens TextTrack#cuechange
- */
-
-
- ChaptersTrackMenuItem.prototype.update = function update(event) {
- var cue = this.cue;
- var currentTime = this.player_.currentTime();
-
- // vjs.log(currentTime, cue.startTime);
- this.selected(cue.startTime <= currentTime && currentTime < cue.endTime);
- };
-
- return ChaptersTrackMenuItem;
- }(MenuItem);
-
- Component.registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem);
-
- /**
- * @file chapters-button.js
- */
- /**
- * 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
- *
- * @extends TextTrackButton
- */
-
- var ChaptersButton = function (_TextTrackButton) {
- inherits(ChaptersButton, _TextTrackButton);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- *
- * @param {Component~ReadyCallback} [ready]
- * The function to call when this function is ready.
- */
- function ChaptersButton(player, options, ready) {
- classCallCheck(this, ChaptersButton);
- return possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- ChaptersButton.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
- };
-
- ChaptersButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
- return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildWrapperCSSClass.call(this);
- };
-
- /**
- * Update the menu based on the current state of its items.
- *
- * @param {EventTarget~Event} [event]
- * An event that triggered this function to run.
- *
- * @listens TextTrackList#addtrack
- * @listens TextTrackList#removetrack
- * @listens TextTrackList#change
- */
-
-
- ChaptersButton.prototype.update = function update(event) {
- if (!this.track_ || event && (event.type === 'addtrack' || event.type === 'removetrack')) {
- this.setTrack(this.findChaptersTrack());
- }
- _TextTrackButton.prototype.update.call(this);
- };
-
- /**
- * Set the currently selected track for the chapters button.
- *
- * @param {TextTrack} track
- * The new track to select. Nothing will change if this is the currently selected
- * track.
- */
-
-
- ChaptersButton.prototype.setTrack = function setTrack(track) {
- if (this.track_ === track) {
- return;
- }
-
- if (!this.updateHandler_) {
- this.updateHandler_ = this.update.bind(this);
- }
-
- // here this.track_ refers to the old track instance
- if (this.track_) {
- var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
-
- if (remoteTextTrackEl) {
- remoteTextTrackEl.removeEventListener('load', this.updateHandler_);
- }
-
- this.track_ = null;
- }
-
- this.track_ = track;
-
- // here this.track_ refers to the new track instance
- if (this.track_) {
- this.track_.mode = 'hidden';
-
- var _remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
-
- if (_remoteTextTrackEl) {
- _remoteTextTrackEl.addEventListener('load', this.updateHandler_);
- }
- }
- };
-
- /**
- * Find the track object that is currently in use by this ChaptersButton
- *
- * @return {TextTrack|undefined}
- * The current track or undefined if none was found.
- */
-
-
- ChaptersButton.prototype.findChaptersTrack = function findChaptersTrack() {
- var tracks = this.player_.textTracks() || [];
-
- for (var i = tracks.length - 1; i >= 0; i--) {
- // We will always choose the last track as our chaptersTrack
- var track = tracks[i];
-
- if (track.kind === this.kind_) {
- return track;
- }
- }
- };
-
- /**
- * Get the caption for the ChaptersButton based on the track label. This will also
- * use the current tracks localized kind as a fallback if a label does not exist.
- *
- * @return {string}
- * The tracks current label or the localized track kind.
- */
-
-
- ChaptersButton.prototype.getMenuCaption = function getMenuCaption() {
- if (this.track_ && this.track_.label) {
- return this.track_.label;
- }
- return this.localize(toTitleCase(this.kind_));
- };
-
- /**
- * Create menu from chapter track
- *
- * @return {Menu}
- * New menu for the chapter buttons
- */
-
-
- ChaptersButton.prototype.createMenu = function createMenu() {
- this.options_.title = this.getMenuCaption();
- return _TextTrackButton.prototype.createMenu.call(this);
- };
-
- /**
- * Create a menu item for each text track
- *
- * @return {TextTrackMenuItem[]}
- * Array of menu items
- */
-
-
- ChaptersButton.prototype.createItems = function createItems() {
- var items = [];
-
- if (!this.track_) {
- return items;
- }
-
- var cues = this.track_.cues;
-
- if (!cues) {
- return items;
- }
-
- for (var i = 0, l = cues.length; i < l; i++) {
- var cue = cues[i];
- var mi = new ChaptersTrackMenuItem(this.player_, {track: this.track_, cue: cue});
-
- items.push(mi);
- }
-
- return items;
- };
-
- return ChaptersButton;
- }(TextTrackButton);
-
- /**
- * `kind` of TextTrack to look for to associate it with this menu.
- *
- * @type {string}
- * @private
- */
-
-
- ChaptersButton.prototype.kind_ = 'chapters';
-
- /**
- * The text that should display over the `ChaptersButton`s controls. Added for localization.
- *
- * @type {string}
- * @private
- */
- ChaptersButton.prototype.controlText_ = 'Chapters';
-
- Component.registerComponent('ChaptersButton', ChaptersButton);
-
- /**
- * @file descriptions-button.js
- */
- /**
- * The button component for toggling and selecting descriptions
- *
- * @extends TextTrackButton
- */
-
- var DescriptionsButton = function (_TextTrackButton) {
- inherits(DescriptionsButton, _TextTrackButton);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- *
- * @param {Component~ReadyCallback} [ready]
- * The function to call when this component is ready.
- */
- function DescriptionsButton(player, options, ready) {
- classCallCheck(this, DescriptionsButton);
-
- var _this = possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
-
- var tracks = player.textTracks();
- var changeHandler = bind(_this, _this.handleTracksChange);
-
- tracks.addEventListener('change', changeHandler);
- _this.on('dispose', function () {
- tracks.removeEventListener('change', changeHandler);
- });
- return _this;
- }
-
- /**
- * Handle text track change
- *
- * @param {EventTarget~Event} event
- * The event that caused this function to run
- *
- * @listens TextTrackList#change
- */
-
-
- DescriptionsButton.prototype.handleTracksChange = function handleTracksChange(event) {
- var tracks = this.player().textTracks();
- var disabled = false;
-
- // Check whether a track of a different kind is showing
- for (var i = 0, l = tracks.length; i < l; i++) {
- var track = tracks[i];
-
- if (track.kind !== this.kind_ && track.mode === 'showing') {
- disabled = true;
- break;
- }
- }
-
- // If another track is showing, disable this menu button
- if (disabled) {
- this.disable();
- } else {
- this.enable();
- }
- };
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- DescriptionsButton.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
- };
-
- DescriptionsButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
- return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildWrapperCSSClass.call(this);
- };
-
- return DescriptionsButton;
- }(TextTrackButton);
-
- /**
- * `kind` of TextTrack to look for to associate it with this menu.
- *
- * @type {string}
- * @private
- */
-
-
- DescriptionsButton.prototype.kind_ = 'descriptions';
-
- /**
- * The text that should display over the `DescriptionsButton`s controls. Added for localization.
- *
- * @type {string}
- * @private
- */
- DescriptionsButton.prototype.controlText_ = 'Descriptions';
-
- Component.registerComponent('DescriptionsButton', DescriptionsButton);
-
- /**
- * @file subtitles-button.js
- */
- /**
- * The button component for toggling and selecting subtitles
- *
- * @extends TextTrackButton
- */
-
- var SubtitlesButton = function (_TextTrackButton) {
- inherits(SubtitlesButton, _TextTrackButton);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- *
- * @param {Component~ReadyCallback} [ready]
- * The function to call when this component is ready.
- */
- function SubtitlesButton(player, options, ready) {
- classCallCheck(this, SubtitlesButton);
- return possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
- };
-
- SubtitlesButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
- return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildWrapperCSSClass.call(this);
- };
-
- return SubtitlesButton;
- }(TextTrackButton);
-
- /**
- * `kind` of TextTrack to look for to associate it with this menu.
- *
- * @type {string}
- * @private
- */
-
-
- SubtitlesButton.prototype.kind_ = 'subtitles';
-
- /**
- * The text that should display over the `SubtitlesButton`s controls. Added for localization.
- *
- * @type {string}
- * @private
- */
- SubtitlesButton.prototype.controlText_ = 'Subtitles';
-
- Component.registerComponent('SubtitlesButton', SubtitlesButton);
-
- /**
- * @file caption-settings-menu-item.js
- */
- /**
- * The menu item for caption track settings menu
- *
- * @extends TextTrackMenuItem
- */
-
- var CaptionSettingsMenuItem = function (_TextTrackMenuItem) {
- inherits(CaptionSettingsMenuItem, _TextTrackMenuItem);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function CaptionSettingsMenuItem(player, options) {
- classCallCheck(this, CaptionSettingsMenuItem);
-
- options.track = {
- player: player,
- kind: options.kind,
- label: options.kind + ' settings',
- selectable: false,
- 'default': false,
- mode: 'disabled'
- };
-
- // CaptionSettingsMenuItem has no concept of 'selected'
- options.selectable = false;
-
- options.name = 'CaptionSettingsMenuItem';
-
- var _this = possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
-
- _this.addClass('vjs-texttrack-settings');
- _this.controlText(', opens ' + options.kind + ' settings dialog');
- return _this;
- }
-
- /**
- * This gets called when an `CaptionSettingsMenuItem` is "clicked". See
- * {@link ClickableComponent} for more detailed information on what a click can be.
- *
- * @param {EventTarget~Event} [event]
- * The `keydown`, `tap`, or `click` event that caused this function to be
- * called.
- *
- * @listens tap
- * @listens click
- */
-
-
- CaptionSettingsMenuItem.prototype.handleClick = function handleClick(event) {
- this.player().getChild('textTrackSettings').open();
- };
-
- return CaptionSettingsMenuItem;
- }(TextTrackMenuItem);
-
- Component.registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem);
-
- /**
- * @file captions-button.js
- */
- /**
- * The button component for toggling and selecting captions
- *
- * @extends TextTrackButton
- */
-
- var CaptionsButton = function (_TextTrackButton) {
- inherits(CaptionsButton, _TextTrackButton);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- *
- * @param {Component~ReadyCallback} [ready]
- * The function to call when this component is ready.
- */
- function CaptionsButton(player, options, ready) {
- classCallCheck(this, CaptionsButton);
- return possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- CaptionsButton.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
- };
-
- CaptionsButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
- return 'vjs-captions-button ' + _TextTrackButton.prototype.buildWrapperCSSClass.call(this);
- };
-
- /**
- * Create caption menu items
- *
- * @return {CaptionSettingsMenuItem[]}
- * The array of current menu items.
- */
-
-
- CaptionsButton.prototype.createItems = function createItems() {
- var items = [];
-
- if (!(this.player().tech_ && this.player().tech_.featuresNativeTextTracks)) {
- items.push(new CaptionSettingsMenuItem(this.player_, {kind: this.kind_}));
-
- this.hideThreshold_ += 1;
- }
-
- return _TextTrackButton.prototype.createItems.call(this, items);
- };
-
- return CaptionsButton;
- }(TextTrackButton);
-
- /**
- * `kind` of TextTrack to look for to associate it with this menu.
- *
- * @type {string}
- * @private
- */
-
-
- CaptionsButton.prototype.kind_ = 'captions';
-
- /**
- * The text that should display over the `CaptionsButton`s controls. Added for localization.
- *
- * @type {string}
- * @private
- */
- CaptionsButton.prototype.controlText_ = 'Captions';
-
- Component.registerComponent('CaptionsButton', CaptionsButton);
-
- /**
- * @file subs-caps-menu-item.js
- */
- /**
- * SubsCapsMenuItem has an [cc] icon to distinguish captions from subtitles
- * in the SubsCapsMenu.
- *
- * @extends TextTrackMenuItem
- */
-
- var SubsCapsMenuItem = function (_TextTrackMenuItem) {
- inherits(SubsCapsMenuItem, _TextTrackMenuItem);
-
- function SubsCapsMenuItem() {
- classCallCheck(this, SubsCapsMenuItem);
- return possibleConstructorReturn(this, _TextTrackMenuItem.apply(this, arguments));
- }
-
- SubsCapsMenuItem.prototype.createEl = function createEl(type, props, attrs) {
- var innerHTML = '<span class="vjs-menu-item-text">' + this.localize(this.options_.label);
-
- if (this.options_.track.kind === 'captions') {
- innerHTML += '\n <span aria-hidden="true" class="vjs-icon-placeholder"></span>\n <span class="vjs-control-text"> ' + this.localize('Captions') + '</span>\n ';
- }
-
- innerHTML += '</span>';
-
- var el = _TextTrackMenuItem.prototype.createEl.call(this, type, assign({
- innerHTML: innerHTML
- }, props), attrs);
-
- return el;
- };
-
- return SubsCapsMenuItem;
- }(TextTrackMenuItem);
-
- Component.registerComponent('SubsCapsMenuItem', SubsCapsMenuItem);
-
- /**
- * @file sub-caps-button.js
- */
- /**
- * The button component for toggling and selecting captions and/or subtitles
- *
- * @extends TextTrackButton
- */
-
- var SubsCapsButton = function (_TextTrackButton) {
- inherits(SubsCapsButton, _TextTrackButton);
-
- function SubsCapsButton(player) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- classCallCheck(this, SubsCapsButton);
-
- // Although North America uses "captions" in most cases for
- // "captions and subtitles" other locales use "subtitles"
- var _this = possibleConstructorReturn(this, _TextTrackButton.call(this, player, options));
-
- _this.label_ = 'subtitles';
- if (['en', 'en-us', 'en-ca', 'fr-ca'].indexOf(_this.player_.language_) > -1) {
- _this.label_ = 'captions';
- }
- _this.menuButton_.controlText(toTitleCase(_this.label_));
- return _this;
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- SubsCapsButton.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-subs-caps-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
- };
-
- SubsCapsButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
- return 'vjs-subs-caps-button ' + _TextTrackButton.prototype.buildWrapperCSSClass.call(this);
- };
-
- /**
- * Create caption/subtitles menu items
- *
- * @return {CaptionSettingsMenuItem[]}
- * The array of current menu items.
- */
-
-
- SubsCapsButton.prototype.createItems = function createItems() {
- var items = [];
-
- if (!(this.player().tech_ && this.player().tech_.featuresNativeTextTracks)) {
- items.push(new CaptionSettingsMenuItem(this.player_, {kind: this.label_}));
-
- this.hideThreshold_ += 1;
- }
-
- items = _TextTrackButton.prototype.createItems.call(this, items, SubsCapsMenuItem);
- return items;
- };
-
- return SubsCapsButton;
- }(TextTrackButton);
-
- /**
- * `kind`s of TextTrack to look for to associate it with this menu.
- *
- * @type {array}
- * @private
- */
-
-
- SubsCapsButton.prototype.kinds_ = ['captions', 'subtitles'];
-
- /**
- * The text that should display over the `SubsCapsButton`s controls.
- *
- *
- * @type {string}
- * @private
- */
- SubsCapsButton.prototype.controlText_ = 'Subtitles';
-
- Component.registerComponent('SubsCapsButton', SubsCapsButton);
-
- /**
- * @file audio-track-menu-item.js
- */
- /**
- * An {@link AudioTrack} {@link MenuItem}
- *
- * @extends MenuItem
- */
-
- var AudioTrackMenuItem = function (_MenuItem) {
- inherits(AudioTrackMenuItem, _MenuItem);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function AudioTrackMenuItem(player, options) {
- classCallCheck(this, AudioTrackMenuItem);
-
- var track = options.track;
- var tracks = player.audioTracks();
-
- // Modify options for parent MenuItem class's init.
- options.label = track.label || track.language || 'Unknown';
- options.selected = track.enabled;
-
- var _this = possibleConstructorReturn(this, _MenuItem.call(this, player, options));
-
- _this.track = track;
-
- var changeHandler = bind(_this, _this.handleTracksChange);
-
- tracks.addEventListener('change', changeHandler);
- _this.on('dispose', function () {
- tracks.removeEventListener('change', changeHandler);
- });
- return _this;
- }
-
- /**
- * This gets called when an `AudioTrackMenuItem is "clicked". See {@link ClickableComponent}
- * for more detailed information on what a click can be.
- *
- * @param {EventTarget~Event} [event]
- * The `keydown`, `tap`, or `click` event that caused this function to be
- * called.
- *
- * @listens tap
- * @listens click
- */
-
-
- AudioTrackMenuItem.prototype.handleClick = function handleClick(event) {
- var tracks = this.player_.audioTracks();
-
- _MenuItem.prototype.handleClick.call(this, event);
-
- for (var i = 0; i < tracks.length; i++) {
- var track = tracks[i];
-
- track.enabled = track === this.track;
- }
- };
-
- /**
- * Handle any {@link AudioTrack} change.
- *
- * @param {EventTarget~Event} [event]
- * The {@link AudioTrackList#change} event that caused this to run.
- *
- * @listens AudioTrackList#change
- */
-
-
- AudioTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
- this.selected(this.track.enabled);
- };
-
- return AudioTrackMenuItem;
- }(MenuItem);
-
- Component.registerComponent('AudioTrackMenuItem', AudioTrackMenuItem);
-
- /**
- * @file audio-track-button.js
- */
- /**
- * The base class for buttons that toggle specific {@link AudioTrack} types.
- *
- * @extends TrackButton
- */
-
- var AudioTrackButton = function (_TrackButton) {
- inherits(AudioTrackButton, _TrackButton);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options={}]
- * The key/value store of player options.
- */
- function AudioTrackButton(player) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- classCallCheck(this, AudioTrackButton);
-
- options.tracks = player.audioTracks();
-
- return possibleConstructorReturn(this, _TrackButton.call(this, player, options));
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- AudioTrackButton.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-audio-button ' + _TrackButton.prototype.buildCSSClass.call(this);
- };
-
- AudioTrackButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
- return 'vjs-audio-button ' + _TrackButton.prototype.buildWrapperCSSClass.call(this);
- };
-
- /**
- * Create a menu item for each audio track
- *
- * @param {AudioTrackMenuItem[]} [items=[]]
- * An array of existing menu items to use.
- *
- * @return {AudioTrackMenuItem[]}
- * An array of menu items
- */
-
-
- AudioTrackButton.prototype.createItems = function createItems() {
- var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
-
- // if there's only one audio track, there no point in showing it
- this.hideThreshold_ = 1;
-
- var tracks = this.player_.audioTracks();
-
- for (var i = 0; i < tracks.length; i++) {
- var track = tracks[i];
-
- items.push(new AudioTrackMenuItem(this.player_, {
- track: track,
- // MenuItem is selectable
- selectable: true
- }));
- }
-
- return items;
- };
-
- return AudioTrackButton;
- }(TrackButton);
-
- /**
- * The text that should display over the `AudioTrackButton`s controls. Added for localization.
- *
- * @type {string}
- * @private
- */
-
-
- AudioTrackButton.prototype.controlText_ = 'Audio Track';
- Component.registerComponent('AudioTrackButton', AudioTrackButton);
-
- /**
- * @file playback-rate-menu-item.js
- */
- /**
- * The specific menu item type for selecting a playback rate.
- *
- * @extends MenuItem
- */
-
- var PlaybackRateMenuItem = function (_MenuItem) {
- inherits(PlaybackRateMenuItem, _MenuItem);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- 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;
- options.selectable = true;
-
- var _this = possibleConstructorReturn(this, _MenuItem.call(this, player, options));
-
- _this.label = label;
- _this.rate = rate;
-
- _this.on(player, 'ratechange', _this.update);
- return _this;
- }
-
- /**
- * This gets called when an `PlaybackRateMenuItem` is "clicked". See
- * {@link ClickableComponent} for more detailed information on what a click can be.
- *
- * @param {EventTarget~Event} [event]
- * The `keydown`, `tap`, or `click` event that caused this function to be
- * called.
- *
- * @listens tap
- * @listens click
- */
-
-
- PlaybackRateMenuItem.prototype.handleClick = function handleClick(event) {
- _MenuItem.prototype.handleClick.call(this);
- this.player().playbackRate(this.rate);
- };
-
- /**
- * Update the PlaybackRateMenuItem when the playbackrate changes.
- *
- * @param {EventTarget~Event} [event]
- * The `ratechange` event that caused this function to run.
- *
- * @listens Player#ratechange
- */
-
-
- PlaybackRateMenuItem.prototype.update = function update(event) {
- this.selected(this.player().playbackRate() === this.rate);
- };
-
- return PlaybackRateMenuItem;
- }(MenuItem);
-
- /**
- * The text that should display over the `PlaybackRateMenuItem`s controls. Added for localization.
- *
- * @type {string}
- * @private
- */
-
-
- PlaybackRateMenuItem.prototype.contentElType = 'button';
-
- Component.registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem);
-
- /**
- * @file playback-rate-menu-button.js
- */
- /**
- * The component for controlling the playback rate.
- *
- * @extends MenuButton
- */
-
- var PlaybackRateMenuButton = function (_MenuButton) {
- inherits(PlaybackRateMenuButton, _MenuButton);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function PlaybackRateMenuButton(player, options) {
- classCallCheck(this, PlaybackRateMenuButton);
-
- var _this = possibleConstructorReturn(this, _MenuButton.call(this, player, options));
-
- _this.updateVisibility();
- _this.updateLabel();
-
- _this.on(player, 'loadstart', _this.updateVisibility);
- _this.on(player, 'ratechange', _this.updateLabel);
- return _this;
- }
-
- /**
- * Create the `Component`'s DOM element
- *
- * @return {Element}
- * The element that was created.
- */
-
-
- PlaybackRateMenuButton.prototype.createEl = function createEl$$1() {
- var el = _MenuButton.prototype.createEl.call(this);
-
- this.labelEl_ = createEl('div', {
- className: 'vjs-playback-rate-value',
- innerHTML: '1x'
- });
-
- el.appendChild(this.labelEl_);
-
- return el;
- };
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
-
-
- PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this);
- };
-
- PlaybackRateMenuButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
- return 'vjs-playback-rate ' + _MenuButton.prototype.buildWrapperCSSClass.call(this);
- };
-
- /**
- * Create the playback rate menu
- *
- * @return {Menu}
- * Menu object populated with {@link PlaybackRateMenuItem}s
- */
-
-
- PlaybackRateMenuButton.prototype.createMenu = function createMenu() {
- var menu = new Menu(this.player());
- var rates = this.playbackRates();
-
- if (rates) {
- for (var i = rates.length - 1; i >= 0; i--) {
- menu.addChild(new PlaybackRateMenuItem(this.player(), {rate: rates[i] + 'x'}));
- }
- }
-
- return menu;
- };
-
- /**
- * Updates ARIA accessibility attributes
- */
-
-
- PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() {
- // Current playback rate
- this.el().setAttribute('aria-valuenow', this.player().playbackRate());
- };
-
- /**
- * This gets called when an `PlaybackRateMenuButton` is "clicked". See
- * {@link ClickableComponent} for more detailed information on what a click can be.
- *
- * @param {EventTarget~Event} [event]
- * The `keydown`, `tap`, or `click` event that caused this function to be
- * called.
- *
- * @listens tap
- * @listens click
- */
-
-
- PlaybackRateMenuButton.prototype.handleClick = function handleClick(event) {
- // 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}
- * All possible playback rates
- */
-
-
- PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() {
- return this.options_.playbackRates || this.options_.playerOptions && this.options_.playerOptions.playbackRates;
- };
-
- /**
- * Get whether playback rates is supported by the tech
- * and an array of playback rates exists
- *
- * @return {boolean}
- * Whether changing playback rate is supported
- */
-
-
- 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
- *
- * @param {EventTarget~Event} [event]
- * The event that caused this function to run.
- *
- * @listens Player#loadstart
- */
-
-
- PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility(event) {
- if (this.playbackRateSupported()) {
- this.removeClass('vjs-hidden');
- } else {
- this.addClass('vjs-hidden');
- }
- };
-
- /**
- * Update button label when rate changed
- *
- * @param {EventTarget~Event} [event]
- * The event that caused this function to run.
- *
- * @listens Player#ratechange
- */
-
-
- PlaybackRateMenuButton.prototype.updateLabel = function updateLabel(event) {
- if (this.playbackRateSupported()) {
- this.labelEl_.innerHTML = this.player().playbackRate() + 'x';
- }
- };
-
- return PlaybackRateMenuButton;
- }(MenuButton);
-
- /**
- * The text that should display over the `FullscreenToggle`s controls. Added for localization.
- *
- * @type {string}
- * @private
- */
-
-
- PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate';
-
- Component.registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton);
-
- /**
- * @file spacer.js
- */
- /**
- * 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
- */
-
- var Spacer = function (_Component) {
- inherits(Spacer, _Component);
-
- function Spacer() {
- classCallCheck(this, Spacer);
- return possibleConstructorReturn(this, _Component.apply(this, arguments));
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
- Spacer.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this);
- };
-
- /**
- * Create the `Component`'s DOM element
- *
- * @return {Element}
- * The element that was created.
- */
-
-
- Spacer.prototype.createEl = function createEl() {
- return _Component.prototype.createEl.call(this, 'div', {
- className: this.buildCSSClass()
- });
- };
-
- return Spacer;
- }(Component);
-
- Component.registerComponent('Spacer', Spacer);
-
- /**
- * @file custom-control-spacer.js
- */
- /**
- * Spacer specifically meant to be used as an insertion point for new plugins, etc.
- *
- * @extends Spacer
- */
-
- var CustomControlSpacer = function (_Spacer) {
- inherits(CustomControlSpacer, _Spacer);
-
- function CustomControlSpacer() {
- classCallCheck(this, CustomControlSpacer);
- return possibleConstructorReturn(this, _Spacer.apply(this, arguments));
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- */
- CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this);
- };
-
- /**
- * Create the `Component`'s DOM element
- *
- * @return {Element}
- * The element that was created.
- */
-
-
- 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 = ' ';
- return el;
- };
-
- return CustomControlSpacer;
- }(Spacer);
-
- Component.registerComponent('CustomControlSpacer', CustomControlSpacer);
-
- /**
- * @file control-bar.js
- */
-// Required children
- /**
- * Container of main controls.
- *
- * @extends Component
- */
-
- var ControlBar = function (_Component) {
- inherits(ControlBar, _Component);
-
- function ControlBar() {
- classCallCheck(this, ControlBar);
- return possibleConstructorReturn(this, _Component.apply(this, arguments));
- }
-
- /**
- * Create the `Component`'s DOM element
- *
- * @return {Element}
- * The element that was created.
- */
- ControlBar.prototype.createEl = function createEl() {
- return _Component.prototype.createEl.call(this, 'div', {
- className: 'vjs-control-bar',
- dir: 'ltr'
- }, {
- // The control bar is a group, but we don't aria-label it to avoid
- // over-announcing by JAWS
- role: 'group'
- });
- };
-
- return ControlBar;
- }(Component);
-
- /**
- * Default options for `ControlBar`
- *
- * @type {Object}
- * @private
- */
-
-
- ControlBar.prototype.options_ = {
- children: ['playToggle', 'volumePanel', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subsCapsButton', 'audioTrackButton', 'fullscreenToggle']
- };
-
- Component.registerComponent('ControlBar', ControlBar);
-
- /**
- * @file error-display.js
- */
- /**
- * A display that indicates an error has occurred. This means that the video
- * is unplayable.
- *
- * @extends ModalDialog
- */
-
- var ErrorDisplay = function (_ModalDialog) {
- inherits(ErrorDisplay, _ModalDialog);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function ErrorDisplay(player, options) {
- classCallCheck(this, ErrorDisplay);
-
- var _this = possibleConstructorReturn(this, _ModalDialog.call(this, player, options));
-
- _this.on(player, 'error', _this.open);
- return _this;
- }
-
- /**
- * Builds the default DOM `className`.
- *
- * @return {string}
- * The DOM `className` for this object.
- *
- * @deprecated Since version 5.
- */
-
-
- ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() {
- return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this);
- };
-
- /**
- * Gets the localized error message based on the `Player`s error.
- *
- * @return {string}
- * The `Player`s error message localized or an empty string.
- */
-
-
- ErrorDisplay.prototype.content = function content() {
- var error = this.player().error();
-
- return error ? this.localize(error.message) : '';
- };
-
- return ErrorDisplay;
- }(ModalDialog);
-
- /**
- * The default options for an `ErrorDisplay`.
- *
- * @private
- */
-
-
- ErrorDisplay.prototype.options_ = mergeOptions(ModalDialog.prototype.options_, {
- pauseOnOpen: false,
- fillAlways: true,
- temporary: false,
- uncloseable: true
- });
-
- Component.registerComponent('ErrorDisplay', ErrorDisplay);
-
- /**
- * @file text-track-settings.js
- */
- var LOCAL_STORAGE_KEY = 'vjs-text-track-settings';
-
- var COLOR_BLACK = ['#000', 'Black'];
- var COLOR_BLUE = ['#00F', 'Blue'];
- var COLOR_CYAN = ['#0FF', 'Cyan'];
- var COLOR_GREEN = ['#0F0', 'Green'];
- var COLOR_MAGENTA = ['#F0F', 'Magenta'];
- var COLOR_RED = ['#F00', 'Red'];
- var COLOR_WHITE = ['#FFF', 'White'];
- var COLOR_YELLOW = ['#FF0', 'Yellow'];
-
- var OPACITY_OPAQUE = ['1', 'Opaque'];
- var OPACITY_SEMI = ['0.5', 'Semi-Transparent'];
- var OPACITY_TRANS = ['0', 'Transparent'];
-
-// Configuration for the various <select> elements in the DOM of this component.
-//
-// Possible keys include:
-//
-// `default`:
-// The default option index. Only needs to be provided if not zero.
-// `parser`:
-// A function which is used to parse the value from the selected option in
-// a customized way.
-// `selector`:
-// The selector used to find the associated <select> element.
- var selectConfigs = {
- backgroundColor: {
- selector: '.vjs-bg-color > select',
- id: 'captions-background-color-%s',
- label: 'Color',
- options: [COLOR_BLACK, COLOR_WHITE, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
- },
-
- backgroundOpacity: {
- selector: '.vjs-bg-opacity > select',
- id: 'captions-background-opacity-%s',
- label: 'Transparency',
- options: [OPACITY_OPAQUE, OPACITY_SEMI, OPACITY_TRANS]
- },
-
- color: {
- selector: '.vjs-fg-color > select',
- id: 'captions-foreground-color-%s',
- label: 'Color',
- options: [COLOR_WHITE, COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
- },
-
- edgeStyle: {
- selector: '.vjs-edge-style > select',
- id: '%s',
- label: 'Text Edge Style',
- options: [['none', 'None'], ['raised', 'Raised'], ['depressed', 'Depressed'], ['uniform', 'Uniform'], ['dropshadow', 'Dropshadow']]
- },
-
- fontFamily: {
- selector: '.vjs-font-family > select',
- id: 'captions-font-family-%s',
- label: 'Font Family',
- options: [['proportionalSansSerif', 'Proportional Sans-Serif'], ['monospaceSansSerif', 'Monospace Sans-Serif'], ['proportionalSerif', 'Proportional Serif'], ['monospaceSerif', 'Monospace Serif'], ['casual', 'Casual'], ['script', 'Script'], ['small-caps', 'Small Caps']]
- },
-
- fontPercent: {
- selector: '.vjs-font-percent > select',
- id: 'captions-font-size-%s',
- label: 'Font Size',
- options: [['0.50', '50%'], ['0.75', '75%'], ['1.00', '100%'], ['1.25', '125%'], ['1.50', '150%'], ['1.75', '175%'], ['2.00', '200%'], ['3.00', '300%'], ['4.00', '400%']],
- 'default': 2,
- parser: function parser(v) {
- return v === '1.00' ? null : Number(v);
- }
- },
-
- textOpacity: {
- selector: '.vjs-text-opacity > select',
- id: 'captions-foreground-opacity-%s',
- label: 'Transparency',
- options: [OPACITY_OPAQUE, OPACITY_SEMI]
- },
-
- // Options for this object are defined below.
- windowColor: {
- selector: '.vjs-window-color > select',
- id: 'captions-window-color-%s',
- label: 'Color'
- },
-
- // Options for this object are defined below.
- windowOpacity: {
- selector: '.vjs-window-opacity > select',
- id: 'captions-window-opacity-%s',
- label: 'Transparency',
- options: [OPACITY_TRANS, OPACITY_SEMI, OPACITY_OPAQUE]
- }
- };
-
- selectConfigs.windowColor.options = selectConfigs.backgroundColor.options;
-
- /**
- * Get the actual value of an option.
- *
- * @param {string} value
- * The value to get
- *
- * @param {Function} [parser]
- * Optional function to adjust the value.
- *
- * @return {Mixed}
- * - Will be `undefined` if no value exists
- * - Will be `undefined` if the given value is "none".
- * - Will be the actual value otherwise.
- *
- * @private
- */
- function parseOptionValue(value, parser) {
- if (parser) {
- value = parser(value);
- }
-
- if (value && value !== 'none') {
- return value;
- }
- }
-
- /**
- * Gets the value of the selected <option> element within a <select> element.
- *
- * @param {Element} el
- * the element to look in
- *
- * @param {Function} [parser]
- * Optional function to adjust the value.
- *
- * @return {Mixed}
- * - Will be `undefined` if no value exists
- * - Will be `undefined` if the given value is "none".
- * - Will be the actual value otherwise.
- *
- * @private
- */
- function getSelectedOptionValue(el, parser) {
- var value = el.options[el.options.selectedIndex].value;
-
- return parseOptionValue(value, parser);
- }
-
- /**
- * Sets the selected <option> element within a <select> element based on a
- * given value.
- *
- * @param {Element} el
- * The element to look in.
- *
- * @param {string} value
- * the property to look on.
- *
- * @param {Function} [parser]
- * Optional function to adjust the value before comparing.
- *
- * @private
- */
- function setSelectedOption(el, value, parser) {
- if (!value) {
- return;
- }
-
- for (var i = 0; i < el.options.length; i++) {
- if (parseOptionValue(el.options[i].value, parser) === value) {
- el.selectedIndex = i;
- break;
- }
- }
- }
-
- /**
- * Manipulate Text Tracks settings.
- *
- * @extends ModalDialog
- */
-
- var TextTrackSettings = function (_ModalDialog) {
- inherits(TextTrackSettings, _ModalDialog);
-
- /**
- * Creates an instance of this class.
- *
- * @param {Player} player
- * The `Player` that this class should be attached to.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- */
- function TextTrackSettings(player, options) {
- classCallCheck(this, TextTrackSettings);
-
- options.temporary = false;
-
- var _this = possibleConstructorReturn(this, _ModalDialog.call(this, player, options));
-
- _this.updateDisplay = bind(_this, _this.updateDisplay);
-
- // fill the modal and pretend we have opened it
- _this.fill();
- _this.hasBeenOpened_ = _this.hasBeenFilled_ = true;
-
- _this.endDialog = createEl('p', {
- className: 'vjs-control-text',
- textContent: _this.localize('End of dialog window.')
- });
- _this.el().appendChild(_this.endDialog);
-
- _this.setDefaults();
-
- // Grab `persistTextTrackSettings` from the player options if not passed in child options
- if (options.persistTextTrackSettings === undefined) {
- _this.options_.persistTextTrackSettings = _this.options_.playerOptions.persistTextTrackSettings;
- }
-
- _this.on(_this.$('.vjs-done-button'), 'click', function () {
- _this.saveSettings();
- _this.close();
- });
-
- _this.on(_this.$('.vjs-default-button'), 'click', function () {
- _this.setDefaults();
- _this.updateDisplay();
- });
-
- each(selectConfigs, function (config) {
- _this.on(_this.$(config.selector), 'change', _this.updateDisplay);
- });
-
- if (_this.options_.persistTextTrackSettings) {
- _this.restoreSettings();
- }
- return _this;
- }
-
- /**
- * Create a <select> element with configured options.
- *
- * @param {string} key
- * Configuration key to use during creation.
- *
- * @return {string}
- * An HTML string.
- *
- * @private
- */
-
-
- TextTrackSettings.prototype.createElSelect_ = function createElSelect_(key) {
- var _this2 = this;
-
- var legendId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
- var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'label';
-
- var config = selectConfigs[key];
- var id = config.id.replace('%s', this.id_);
-
- return ['<' + type + ' id="' + id + '" class="' + (type === 'label' ? 'vjs-label' : '') + '">', this.localize(config.label), '</' + type + '>', '<select aria-labelledby="' + (legendId !== '' ? legendId + ' ' : '') + id + '">'].concat(config.options.map(function (o) {
- var optionId = id + '-' + o[1];
-
- return ['<option id="' + optionId + '" value="' + o[0] + '" ', 'aria-labelledby="' + (legendId !== '' ? legendId + ' ' : '') + id + ' ' + optionId + '">', _this2.localize(o[1]), '</option>'].join('');
- })).concat('</select>').join('');
- };
-
- /**
- * Create foreground color element for the component
- *
- * @return {string}
- * An HTML string.
- *
- * @private
- */
-
-
- TextTrackSettings.prototype.createElFgColor_ = function createElFgColor_() {
- var legendId = 'captions-text-legend-' + this.id_;
-
- return ['<fieldset class="vjs-fg-color vjs-track-setting">', '<legend id="' + legendId + '">', this.localize('Text'), '</legend>', this.createElSelect_('color', legendId), '<span class="vjs-text-opacity vjs-opacity">', this.createElSelect_('textOpacity', legendId), '</span>', '</fieldset>'].join('');
- };
-
- /**
- * Create background color element for the component
- *
- * @return {string}
- * An HTML string.
- *
- * @private
- */
-
-
- TextTrackSettings.prototype.createElBgColor_ = function createElBgColor_() {
- var legendId = 'captions-background-' + this.id_;
-
- return ['<fieldset class="vjs-bg-color vjs-track-setting">', '<legend id="' + legendId + '">', this.localize('Background'), '</legend>', this.createElSelect_('backgroundColor', legendId), '<span class="vjs-bg-opacity vjs-opacity">', this.createElSelect_('backgroundOpacity', legendId), '</span>', '</fieldset>'].join('');
- };
-
- /**
- * Create window color element for the component
- *
- * @return {string}
- * An HTML string.
- *
- * @private
- */
-
-
- TextTrackSettings.prototype.createElWinColor_ = function createElWinColor_() {
- var legendId = 'captions-window-' + this.id_;
-
- return ['<fieldset class="vjs-window-color vjs-track-setting">', '<legend id="' + legendId + '">', this.localize('Window'), '</legend>', this.createElSelect_('windowColor', legendId), '<span class="vjs-window-opacity vjs-opacity">', this.createElSelect_('windowOpacity', legendId), '</span>', '</fieldset>'].join('');
- };
-
- /**
- * Create color elements for the component
- *
- * @return {Element}
- * The element that was created
- *
- * @private
- */
-
-
- TextTrackSettings.prototype.createElColors_ = function createElColors_() {
- return createEl('div', {
- className: 'vjs-track-settings-colors',
- innerHTML: [this.createElFgColor_(), this.createElBgColor_(), this.createElWinColor_()].join('')
- });
- };
-
- /**
- * Create font elements for the component
- *
- * @return {Element}
- * The element that was created.
- *
- * @private
- */
-
-
- TextTrackSettings.prototype.createElFont_ = function createElFont_() {
- return createEl('div', {
- className: 'vjs-track-settings-font">',
- innerHTML: ['<fieldset class="vjs-font-percent vjs-track-setting">', this.createElSelect_('fontPercent', '', 'legend'), '</fieldset>', '<fieldset class="vjs-edge-style vjs-track-setting">', this.createElSelect_('edgeStyle', '', 'legend'), '</fieldset>', '<fieldset class="vjs-font-family vjs-track-setting">', this.createElSelect_('fontFamily', '', 'legend'), '</fieldset>'].join('')
- });
- };
-
- /**
- * Create controls for the component
- *
- * @return {Element}
- * The element that was created.
- *
- * @private
- */
-
-
- TextTrackSettings.prototype.createElControls_ = function createElControls_() {
- var defaultsDescription = this.localize('restore all settings to the default values');
-
- return createEl('div', {
- className: 'vjs-track-settings-controls',
- innerHTML: ['<button class="vjs-default-button" title="' + defaultsDescription + '">', this.localize('Reset'), '<span class="vjs-control-text"> ' + defaultsDescription + '</span>', '</button>', '<button class="vjs-done-button">' + this.localize('Done') + '</button>'].join('')
- });
- };
-
- TextTrackSettings.prototype.content = function content() {
- return [this.createElColors_(), this.createElFont_(), this.createElControls_()];
- };
-
- TextTrackSettings.prototype.label = function label() {
- return this.localize('Caption Settings Dialog');
- };
-
- TextTrackSettings.prototype.description = function description() {
- return this.localize('Beginning of dialog window. Escape will cancel and close the window.');
- };
-
- TextTrackSettings.prototype.buildCSSClass = function buildCSSClass() {
- return _ModalDialog.prototype.buildCSSClass.call(this) + ' vjs-text-track-settings';
- };
-
- /**
- * Gets an object of text track settings (or null).
- *
- * @return {Object}
- * An object with config values parsed from the DOM or localStorage.
- */
-
-
- TextTrackSettings.prototype.getValues = function getValues() {
- var _this3 = this;
-
- return reduce(selectConfigs, function (accum, config, key) {
- var value = getSelectedOptionValue(_this3.$(config.selector), config.parser);
-
- if (value !== undefined) {
- accum[key] = value;
- }
-
- return accum;
- }, {});
- };
-
- /**
- * Sets text track settings from an object of values.
- *
- * @param {Object} values
- * An object with config values parsed from the DOM or localStorage.
- */
-
-
- TextTrackSettings.prototype.setValues = function setValues(values) {
- var _this4 = this;
-
- each(selectConfigs, function (config, key) {
- setSelectedOption(_this4.$(config.selector), values[key], config.parser);
- });
- };
-
- /**
- * Sets all `<select>` elements to their default values.
- */
-
-
- TextTrackSettings.prototype.setDefaults = function setDefaults() {
- var _this5 = this;
-
- each(selectConfigs, function (config) {
- var index = config.hasOwnProperty('default') ? config['default'] : 0;
-
- _this5.$(config.selector).selectedIndex = index;
- });
- };
-
- /**
- * Restore texttrack settings from localStorage
- */
-
-
- TextTrackSettings.prototype.restoreSettings = function restoreSettings() {
- var values = void 0;
-
- try {
- values = JSON.parse(window_1.localStorage.getItem(LOCAL_STORAGE_KEY));
- } catch (err) {
- log$1.warn(err);
- }
-
- if (values) {
- this.setValues(values);
- }
- };
-
- /**
- * Save text track settings to localStorage
- */
-
-
- TextTrackSettings.prototype.saveSettings = function saveSettings() {
- if (!this.options_.persistTextTrackSettings) {
- return;
- }
-
- var values = this.getValues();
-
- try {
- if (Object.keys(values).length) {
- window_1.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(values));
- } else {
- window_1.localStorage.removeItem(LOCAL_STORAGE_KEY);
- }
- } catch (err) {
- log$1.warn(err);
- }
- };
-
- /**
- * Update display of text track settings
- */
-
-
- TextTrackSettings.prototype.updateDisplay = function updateDisplay() {
- var ttDisplay = this.player_.getChild('textTrackDisplay');
-
- if (ttDisplay) {
- ttDisplay.updateDisplay();
- }
- };
-
- /**
- * conditionally blur the element and refocus the captions button
- *
- * @private
- */
-
-
- TextTrackSettings.prototype.conditionalBlur_ = function conditionalBlur_() {
- this.previouslyActiveEl_ = null;
- this.off(document_1, 'keydown', this.handleKeyDown);
-
- var cb = this.player_.controlBar;
- var subsCapsBtn = cb && cb.subsCapsButton;
- var ccBtn = cb && cb.captionsButton;
-
- if (subsCapsBtn) {
- subsCapsBtn.focus();
- } else if (ccBtn) {
- ccBtn.focus();
- }
- };
-
- return TextTrackSettings;
- }(ModalDialog);
-
- Component.registerComponent('TextTrackSettings', TextTrackSettings);
-
- var _templateObject$2 = taggedTemplateLiteralLoose(['Text Tracks are being loaded from another origin but the crossorigin attribute isn\'t used.\n This may prevent text tracks from loading.'], ['Text Tracks are being loaded from another origin but the crossorigin attribute isn\'t used.\n This may prevent text tracks from loading.']);
-
- /**
- * @file html5.js
- */
- /**
- * HTML5 Media Controller - Wrapper for HTML5 Media API
- *
- * @mixes Tech~SouceHandlerAdditions
- * @extends Tech
- */
-
- var Html5 = function (_Tech) {
- inherits(Html5, _Tech);
-
- /**
- * Create an instance of this Tech.
- *
- * @param {Object} [options]
- * The key/value store of player options.
- *
- * @param {Component~ReadyCallback} ready
- * Callback function to call when the `HTML5` Tech is ready.
- */
- function Html5(options, ready) {
- classCallCheck(this, Html5);
-
- var _this = possibleConstructorReturn(this, _Tech.call(this, options, ready));
-
- var source = options.source;
- var crossoriginTracks = false;
-
- // 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);
- _this.textTracks().addTrack(node.track);
- if (!crossoriginTracks && !_this.el_.hasAttribute('crossorigin') && isCrossOrigin(node.src)) {
- crossoriginTracks = true;
- }
- }
- }
- }
-
- for (var i = 0; i < removeNodes.length; i++) {
- _this.el_.removeChild(removeNodes[i]);
- }
- }
-
- _this.proxyNativeTracks_();
- if (_this.featuresNativeTextTracks && crossoriginTracks) {
- log$1.warn(tsml(_templateObject$2));
- }
-
- // prevent iOS Safari from disabling metadata text tracks during native playback
- _this.restoreMetadataTracksInIOSNativePlayer_();
-
- // 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 ((TOUCH_ENABLED || IS_IPHONE || IS_NATIVE_ANDROID) && options.nativeControlsForTouch === true) {
- _this.setControls(true);
- }
-
- // on iOS, we want to proxy `webkitbeginfullscreen` and `webkitendfullscreen`
- // into a `fullscreenchange` event
- _this.proxyWebkitFullscreen_();
-
- _this.triggerReady();
- return _this;
- }
-
- /**
- * Dispose of `HTML5` media element and remove all tracks.
- */
-
-
- Html5.prototype.dispose = function dispose() {
- Html5.disposeMediaElement(this.el_);
- // tech will handle clearing of the emulated track list
- _Tech.prototype.dispose.call(this);
- };
-
- /**
- * When a captions track is enabled in the iOS Safari native player, all other
- * tracks are disabled (including metadata tracks), which nulls all of their
- * associated cue points. This will restore metadata tracks to their pre-fullscreen
- * state in those cases so that cue points are not needlessly lost.
- *
- * @private
- */
-
-
- Html5.prototype.restoreMetadataTracksInIOSNativePlayer_ = function restoreMetadataTracksInIOSNativePlayer_() {
- var textTracks = this.textTracks();
- var metadataTracksPreFullscreenState = void 0;
-
- // captures a snapshot of every metadata track's current state
- var takeMetadataTrackSnapshot = function takeMetadataTrackSnapshot() {
- metadataTracksPreFullscreenState = [];
-
- for (var i = 0; i < textTracks.length; i++) {
- var track = textTracks[i];
-
- if (track.kind === 'metadata') {
- metadataTracksPreFullscreenState.push({
- track: track,
- storedMode: track.mode
- });
- }
- }
- };
-
- // snapshot each metadata track's initial state, and update the snapshot
- // each time there is a track 'change' event
- takeMetadataTrackSnapshot();
- textTracks.addEventListener('change', takeMetadataTrackSnapshot);
-
- var restoreTrackMode = function restoreTrackMode() {
- for (var i = 0; i < metadataTracksPreFullscreenState.length; i++) {
- var storedTrack = metadataTracksPreFullscreenState[i];
-
- if (storedTrack.track.mode === 'disabled' && storedTrack.track.mode !== storedTrack.storedMode) {
- storedTrack.track.mode = storedTrack.storedMode;
- }
- }
- // we only want this handler to be executed on the first 'change' event
- textTracks.removeEventListener('change', restoreTrackMode);
- };
-
- // when we enter fullscreen playback, stop updating the snapshot and
- // restore all track modes to their pre-fullscreen state
- this.on('webkitbeginfullscreen', function () {
- textTracks.removeEventListener('change', takeMetadataTrackSnapshot);
-
- // remove the listener before adding it just in case it wasn't previously removed
- textTracks.removeEventListener('change', restoreTrackMode);
- textTracks.addEventListener('change', restoreTrackMode);
- });
-
- // start updating the snapshot again after leaving fullscreen
- this.on('webkitendfullscreen', function () {
- // remove the listener before adding it just in case it wasn't previously removed
- textTracks.removeEventListener('change', takeMetadataTrackSnapshot);
- textTracks.addEventListener('change', takeMetadataTrackSnapshot);
-
- // remove the restoreTrackMode handler in case it wasn't triggered during fullscreen playback
- textTracks.removeEventListener('change', restoreTrackMode);
- });
- };
-
- /**
- * Proxy all native track list events to our track lists if the browser we are playing
- * in supports that type of track list.
- *
- * @private
- */
-
-
- Html5.prototype.proxyNativeTracks_ = function proxyNativeTracks_() {
- var _this2 = this;
-
- NORMAL.names.forEach(function (name) {
- var props = NORMAL[name];
- var elTracks = _this2.el()[props.getterName];
- var techTracks = _this2[props.getterName]();
-
- if (!_this2['featuresNative' + props.capitalName + 'Tracks'] || !elTracks || !elTracks.addEventListener) {
- return;
- }
- var listeners = {
- change: function change(e) {
- techTracks.trigger({
- type: 'change',
- target: techTracks,
- currentTarget: techTracks,
- srcElement: techTracks
- });
- },
- addtrack: function addtrack(e) {
- techTracks.addTrack(e.track);
- },
- removetrack: function removetrack(e) {
- techTracks.removeTrack(e.track);
- }
- };
- var removeOldTracks = function removeOldTracks() {
- var removeTracks = [];
-
- for (var i = 0; i < techTracks.length; i++) {
- var found = false;
-
- for (var j = 0; j < elTracks.length; j++) {
- if (elTracks[j] === techTracks[i]) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- removeTracks.push(techTracks[i]);
- }
- }
-
- while (removeTracks.length) {
- techTracks.removeTrack(removeTracks.shift());
- }
- };
-
- Object.keys(listeners).forEach(function (eventName) {
- var listener = listeners[eventName];
-
- elTracks.addEventListener(eventName, listener);
- _this2.on('dispose', function (e) {
- return elTracks.removeEventListener(eventName, listener);
- });
- });
-
- // Remove (native) tracks that are not used anymore
- _this2.on('loadstart', removeOldTracks);
- _this2.on('dispose', function (e) {
- return _this2.off('loadstart', removeOldTracks);
- });
- });
- };
-
- /**
- * Create the `Html5` Tech's DOM element.
- *
- * @return {Element}
- * The element that gets created.
- */
-
-
- Html5.prototype.createEl = function createEl$$1() {
- 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 we ingested the player div, we do not need to move the media element.
- if (!el || !(this.options_.playerElIngest || this.movingMediaElementInDOM)) {
-
- // If the original tag is still there, clone and remove it.
- if (el) {
- var clone = el.cloneNode(true);
-
- if (el.parentNode) {
- el.parentNode.insertBefore(clone, el);
- }
- Html5.disposeMediaElement(el);
- el = clone;
- } else {
- el = document_1.createElement('video');
-
- // determine if native controls should be used
- var tagAttributes = this.options_.tag && getAttributes(this.options_.tag);
- var attributes = mergeOptions({}, tagAttributes);
-
- if (!TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) {
- delete attributes.controls;
- }
-
- setAttributes(el, assign(attributes, {
- id: this.options_.techId,
- 'class': 'vjs-tech'
- }));
- }
-
- el.playerId = this.options_.playerId;
- }
-
- if (typeof this.options_.preload !== 'undefined') {
- setAttribute(el, 'preload', this.options_.preload);
- }
-
- // Update specific tag settings, in case they were overridden
- // `autoplay` has to be *last* so that `muted` and `playsinline` are present
- // when iOS/Safari or other browsers attempt to autoplay.
- var settingsAttrs = ['loop', 'muted', 'playsinline', 'autoplay'];
-
- for (var i = settingsAttrs.length - 1; i >= 0; i--) {
- var attr = settingsAttrs[i];
- var value = this.options_[attr];
-
- if (typeof value !== 'undefined') {
- if (value) {
- setAttribute(el, attr, attr);
- } else {
- removeAttribute(el, attr);
- }
- el[attr] = value;
- }
- }
-
- return el;
- };
-
- /**
- * This will be triggered if the loadstart event has already fired, before videojs was
- * ready. Two known examples of when this can happen are:
- * 1. If we're loading the playback object after it has started loading
- * 2. The media is already playing the (often with autoplay on) then
- *
- * This function will fire another loadstart so that videojs can catchup.
- *
- * @fires Tech#loadstart
- *
- * @return {undefined}
- * returns nothing.
- */
-
-
- Html5.prototype.handleLateInit_ = function handleLateInit_(el) {
- 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) {
- // 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;
- }
-
- // 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);
- });
- };
-
- /**
- * Set current time for the `HTML5` tech.
- *
- * @param {number} seconds
- * Set the current time of the media to this.
- */
-
-
- Html5.prototype.setCurrentTime = function setCurrentTime(seconds) {
- try {
- this.el_.currentTime = seconds;
- } catch (e) {
- log$1(e, 'Video is not ready. (Video.js)');
- // this.warning(VideoJS.warnings.videoNotReady);
- }
- };
-
- /**
- * Get the current duration of the HTML5 media element.
- *
- * @return {number}
- * The duration of the media or 0 if there is no duration.
- */
-
-
- Html5.prototype.duration = function duration() {
- var _this3 = this;
-
- // Android Chrome will report duration as Infinity for VOD HLS until after
- // playback has started, which triggers the live display erroneously.
- // Return NaN if playback has not started and trigger a durationupdate once
- // the duration can be reliably known.
- if (this.el_.duration === Infinity && IS_ANDROID && IS_CHROME && this.el_.currentTime === 0) {
- // Wait for the first `timeupdate` with currentTime > 0 - there may be
- // several with 0
- var checkProgress = function checkProgress() {
- if (_this3.el_.currentTime > 0) {
- // Trigger durationchange for genuinely live video
- if (_this3.el_.duration === Infinity) {
- _this3.trigger('durationchange');
- }
- _this3.off('timeupdate', checkProgress);
- }
- };
-
- this.on('timeupdate', checkProgress);
- return NaN;
- }
- return this.el_.duration || NaN;
- };
-
- /**
- * Get the current width of the HTML5 media element.
- *
- * @return {number}
- * The width of the HTML5 media element.
- */
-
-
- Html5.prototype.width = function width() {
- return this.el_.offsetWidth;
- };
-
- /**
- * Get the current height of the HTML5 media element.
- *
- * @return {number}
- * The heigth of the HTML5 media element.
- */
-
-
- Html5.prototype.height = function height() {
- return this.el_.offsetHeight;
- };
-
- /**
- * Proxy iOS `webkitbeginfullscreen` and `webkitendfullscreen` into
- * `fullscreenchange` event.
- *
- * @private
- * @fires fullscreenchange
- * @listens webkitendfullscreen
- * @listens webkitbeginfullscreen
- * @listens webkitbeginfullscreen
- */
-
-
- Html5.prototype.proxyWebkitFullscreen_ = function proxyWebkitFullscreen_() {
- var _this4 = this;
-
- if (!('webkitDisplayingFullscreen' in this.el_)) {
- return;
- }
-
- var endFn = function endFn() {
- this.trigger('fullscreenchange', {isFullscreen: false});
- };
-
- var beginFn = function beginFn() {
- if ('webkitPresentationMode' in this.el_ && this.el_.webkitPresentationMode !== 'picture-in-picture') {
- this.one('webkitendfullscreen', endFn);
-
- this.trigger('fullscreenchange', {isFullscreen: true});
- }
- };
-
- this.on('webkitbeginfullscreen', beginFn);
- this.on('dispose', function () {
- _this4.off('webkitbeginfullscreen', beginFn);
- _this4.off('webkitendfullscreen', endFn);
- });
- };
-
- /**
- * Check if fullscreen is supported on the current playback device.
- *
- * @return {boolean}
- * - True if fullscreen is supported.
- * - False if fullscreen is not supported.
- */
-
-
- Html5.prototype.supportsFullScreen = function supportsFullScreen() {
- if (typeof this.el_.webkitEnterFullScreen === 'function') {
- var userAgent = window_1.navigator && window_1.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 that the `HTML5` Tech enter fullscreen.
- */
-
-
- Html5.prototype.enterFullScreen = function enterFullScreen() {
- var video = this.el_;
-
- 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 that the `HTML5` Tech exit fullscreen.
- */
-
-
- Html5.prototype.exitFullScreen = function exitFullScreen() {
- this.el_.webkitExitFullScreen();
- };
-
- /**
- * A getter/setter for the `Html5` Tech's source object.
- * > Note: Please use {@link Html5#setSource}
- *
- * @param {Tech~SourceObject} [src]
- * The source object you want to set on the `HTML5` techs element.
- *
- * @return {Tech~SourceObject|undefined}
- * - The current source object when a source is not passed in.
- * - undefined when setting
- *
- * @deprecated Since version 5.
- */
-
-
- Html5.prototype.src = function src(_src) {
- if (_src === undefined) {
- return this.el_.src;
- }
-
- // Setting src through `src` instead of `setSrc` will be deprecated
- this.setSrc(_src);
- };
-
- /**
- * Reset the tech by removing all sources and then calling
- * {@link Html5.resetMediaElement}.
- */
-
-
- Html5.prototype.reset = function reset() {
- Html5.resetMediaElement(this.el_);
- };
-
- /**
- * Get the current source on the `HTML5` Tech. Falls back to returning the source from
- * the HTML5 media element.
- *
- * @return {Tech~SourceObject}
- * The current source object from the HTML5 tech. With a fallback to the
- * elements source.
- */
-
-
- Html5.prototype.currentSrc = function currentSrc() {
- if (this.currentSource_) {
- return this.currentSource_.src;
- }
- return this.el_.currentSrc;
- };
-
- /**
- * Set controls attribute for the HTML5 media Element.
- *
- * @param {string} val
- * Value to set the controls attribute to
- */
-
-
- Html5.prototype.setControls = function setControls(val) {
- this.el_.controls = !!val;
- };
-
- /**
- * Create and returns a remote {@link TextTrack} object.
- *
- * @param {string} kind
- * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
- *
- * @param {string} [label]
- * Label to identify the text track
- *
- * @param {string} [language]
- * Two letter language abbreviation
- *
- * @return {TextTrack}
- * The TextTrack that gets created.
- */
-
-
- 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 either native TextTrack or an emulated TextTrack depending
- * on the value of `featuresNativeTextTracks`
- *
- * @param {Object} options
- * The object should contain the options to intialize the TextTrack with.
- *
- * @param {string} [options.kind]
- * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
- *
- * @param {string} [options.label].
- * Label to identify the text track
- *
- * @param {string} [options.language]
- * Two letter language abbreviation.
- *
- * @param {boolean} [options.default]
- * Default this track to on.
- *
- * @param {string} [options.id]
- * The internal id to assign this track.
- *
- * @param {string} [options.src]
- * A source url for the track.
- *
- * @return {HTMLTrackElement}
- * The track element that gets created.
- */
-
-
- Html5.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) {
- if (!this.featuresNativeTextTracks) {
- return _Tech.prototype.createRemoteTextTrack.call(this, options);
- }
- var htmlTrackElement = document_1.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;
- }
-
- return htmlTrackElement;
- };
-
- /**
- * Creates a remote text track object and returns an html track element.
- *
- * @param {Object} options The object should contain values for
- * kind, language, label, and src (location of the WebVTT file)
- * @param {Boolean} [manualCleanup=true] if set to false, the TextTrack will be
- * automatically removed from the video element whenever the source changes
- * @return {HTMLTrackElement} An Html Track Element.
- * This can be an emulated {@link HTMLTrackElement} or a native one.
- * @deprecated The default value of the "manualCleanup" parameter will default
- * to "false" in upcoming versions of Video.js
- */
-
-
- Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) {
- var htmlTrackElement = _Tech.prototype.addRemoteTextTrack.call(this, options, manualCleanup);
-
- if (this.featuresNativeTextTracks) {
- this.el().appendChild(htmlTrackElement);
- }
-
- return htmlTrackElement;
- };
-
- /**
- * Remove remote `TextTrack` from `TextTrackList` object
- *
- * @param {TextTrack} track
- * `TextTrack` object to remove
- */
-
-
- Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
- _Tech.prototype.removeRemoteTextTrack.call(this, track);
-
- if (this.featuresNativeTextTracks) {
- var tracks = this.$$('track');
-
- var i = tracks.length;
-
- while (i--) {
- if (track === tracks[i] || track === tracks[i].track) {
- this.el().removeChild(tracks[i]);
- }
- }
- }
- };
-
- /**
- * Gets available media playback quality metrics as specified by the W3C's Media
- * Playback Quality API.
- *
- * @see [Spec]{@link https://wicg.github.io/media-playback-quality}
- *
- * @return {Object}
- * An object with supported media playback quality metrics
- */
-
-
- Html5.prototype.getVideoPlaybackQuality = function getVideoPlaybackQuality() {
- if (typeof this.el().getVideoPlaybackQuality === 'function') {
- return this.el().getVideoPlaybackQuality();
- }
-
- var videoPlaybackQuality = {};
-
- if (typeof this.el().webkitDroppedFrameCount !== 'undefined' && typeof this.el().webkitDecodedFrameCount !== 'undefined') {
- videoPlaybackQuality.droppedVideoFrames = this.el().webkitDroppedFrameCount;
- videoPlaybackQuality.totalVideoFrames = this.el().webkitDecodedFrameCount;
- }
-
- if (window_1.performance && typeof window_1.performance.now === 'function') {
- videoPlaybackQuality.creationTime = window_1.performance.now();
- } else if (window_1.performance && window_1.performance.timing && typeof window_1.performance.timing.navigationStart === 'number') {
- videoPlaybackQuality.creationTime = window_1.Date.now() - window_1.performance.timing.navigationStart;
- }
-
- return videoPlaybackQuality;
- };
-
- return Html5;
- }(Tech);
-
- /* HTML5 Support Testing ---------------------------------------------------- */
-
- if (isReal()) {
-
- /**
- * Element for testing browser HTML5 media capabilities
- *
- * @type {Element}
- * @constant
- * @private
- */
- Html5.TEST_VID = document_1.createElement('video');
- var track = document_1.createElement('track');
-
- track.kind = 'captions';
- track.srclang = 'en';
- track.label = 'English';
- Html5.TEST_VID.appendChild(track);
- }
-
- /**
- * Check if HTML5 media is supported by this browser/device.
- *
- * @return {boolean}
- * - True if HTML5 media is supported.
- * - False if HTML5 media is not supported.
- */
- 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 && Html5.TEST_VID.canPlayType);
- };
-
- /**
- * Check if the tech can support the given type
- *
- * @param {string} type
- * The mimetype to check
- * @return {string} 'probably', 'maybe', or '' (empty string)
- */
- Html5.canPlayType = function (type) {
- return Html5.TEST_VID.canPlayType(type);
- };
-
- /**
- * Check if the tech can support the given source
- * @param {Object} srcObj
- * The source object
- * @param {Object} options
- * The options passed to the tech
- * @return {string} 'probably', 'maybe', or '' (empty string)
- */
- Html5.canPlaySource = function (srcObj, options) {
- return Html5.canPlayType(srcObj.type);
- };
-
- /**
- * 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}
- * - True if volume can be controlled
- * - False otherwise
- */
- Html5.canControlVolume = function () {
- // IE will error if Windows Media Player not installed #3315
- try {
- var volume = Html5.TEST_VID.volume;
-
- Html5.TEST_VID.volume = volume / 2 + 0.1;
- return volume !== Html5.TEST_VID.volume;
- } catch (e) {
- return false;
- }
- };
-
- /**
- * Check if the playback rate can be changed in this browser/device.
- *
- * @return {boolean}
- * - True if playback rate can be controlled
- * - False otherwise
- */
- Html5.canControlPlaybackRate = function () {
- // Playback rate API is implemented in Android Chrome, but doesn't do anything
- // https://github.com/videojs/video.js/issues/3180
- if (IS_ANDROID && IS_CHROME && CHROME_VERSION < 58) {
- return false;
- }
- // IE will error if Windows Media Player not installed #3315
- try {
- var playbackRate = Html5.TEST_VID.playbackRate;
-
- Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1;
- return playbackRate !== Html5.TEST_VID.playbackRate;
- } catch (e) {
- return false;
- }
- };
-
- /**
- * Check to see if native `TextTrack`s are supported by this browser/device.
- *
- * @return {boolean}
- * - True if native `TextTrack`s are supported.
- * - False otherwise
- */
- Html5.supportsNativeTextTracks = function () {
- return IS_ANY_SAFARI;
- };
-
- /**
- * Check to see if native `VideoTrack`s are supported by this browser/device
- *
- * @return {boolean}
- * - True if native `VideoTrack`s are supported.
- * - False otherwise
- */
- Html5.supportsNativeVideoTracks = function () {
- return !!(Html5.TEST_VID && Html5.TEST_VID.videoTracks);
- };
-
- /**
- * Check to see if native `AudioTrack`s are supported by this browser/device
- *
- * @return {boolean}
- * - True if native `AudioTrack`s are supported.
- * - False otherwise
- */
- Html5.supportsNativeAudioTracks = function () {
- return !!(Html5.TEST_VID && Html5.TEST_VID.audioTracks);
- };
-
- /**
- * 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', 'resize', 'volumechange'];
-
- /**
- * Boolean indicating whether the `Tech` supports volume control.
- *
- * @type {boolean}
- * @default {@link Html5.canControlVolume}
- */
- Html5.prototype.featuresVolumeControl = Html5.canControlVolume();
-
- /**
- * Boolean indicating whether the `Tech` supports changing the speed at which the media
- * plays. Examples:
- * - Set player to play 2x (twice) as fast
- * - Set player to play 0.5x (half) as fast
- *
- * @type {boolean}
- * @default {@link Html5.canControlPlaybackRate}
- */
- Html5.prototype.featuresPlaybackRate = Html5.canControlPlaybackRate();
-
- /**
- * Boolean indicating whether the `HTML5` tech currently supports the media element
- * moving in the DOM. iOS breaks if you move the media element, so this is set this to
- * false there. Everywhere else this should be true.
- *
- * @type {boolean}
- * @default
- */
- Html5.prototype.movingMediaElementInDOM = !IS_IOS;
-
-// TODO: Previous comment: No longer appears to be used. Can probably be removed.
-// Is this true?
- /**
- * Boolean indicating whether the `HTML5` tech currently supports automatic media resize
- * when going into fullscreen.
- *
- * @type {boolean}
- * @default
- */
- Html5.prototype.featuresFullscreenResize = true;
-
- /**
- * Boolean indicating whether the `HTML5` tech currently supports the progress event.
- * If this is false, manual `progress` events will be triggred instead.
- *
- * @type {boolean}
- * @default
- */
- Html5.prototype.featuresProgressEvents = true;
-
- /**
- * Boolean indicating whether the `HTML5` tech currently supports the timeupdate event.
- * If this is false, manual `timeupdate` events will be triggred instead.
- *
- * @default
- */
- Html5.prototype.featuresTimeupdateEvents = true;
-
- /**
- * Boolean indicating whether the `HTML5` tech currently supports native `TextTrack`s.
- *
- * @type {boolean}
- * @default {@link Html5.supportsNativeTextTracks}
- */
- Html5.prototype.featuresNativeTextTracks = Html5.supportsNativeTextTracks();
-
- /**
- * Boolean indicating whether the `HTML5` tech currently supports native `VideoTrack`s.
- *
- * @type {boolean}
- * @default {@link Html5.supportsNativeVideoTracks}
- */
- Html5.prototype.featuresNativeVideoTracks = Html5.supportsNativeVideoTracks();
-
- /**
- * Boolean indicating whether the `HTML5` tech currently supports native `AudioTrack`s.
- *
- * @type {boolean}
- * @default {@link Html5.supportsNativeAudioTracks}
- */
- Html5.prototype.featuresNativeAudioTracks = Html5.supportsNativeAudioTracks();
-
-// HTML5 Feature detection and Device Fixes --------------------------------- //
- var canPlayType = Html5.TEST_VID && Html5.TEST_VID.constructor.prototype.canPlayType;
- 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 (ANDROID_VERSION >= 4.0 && !IS_FIREFOX) {
- 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
- } else if (IS_OLD_ANDROID) {
- 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;
- return r;
- };
-
-// by default, patch the media 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) {
- // satisfy linter
- }
- })();
- }
- };
-
- /* Native HTML5 element property wrapping ----------------------------------- */
-// Wrap native boolean attributes with getters that check both property and attribute
-// The list is as followed:
-// muted, defaultMuted, autoplay, controls, loop, playsinline
- [
- /**
- * Get the value of `muted` from the media element. `muted` indicates
- * that the volume for the media should be set to silent. This does not actually change
- * the `volume` attribute.
- *
- * @method Html5#muted
- * @return {boolean}
- * - True if the value of `volume` should be ignored and the audio set to silent.
- * - False if the value of `volume` should be used.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
- */
- 'muted',
-
- /**
- * Get the value of `defaultMuted` from the media element. `defaultMuted` indicates
- * whether the media should start muted or not. Only changes the default state of the
- * media. `muted` and `defaultMuted` can have different values. {@link Html5#muted} indicates the
- * current state.
- *
- * @method Html5#defaultMuted
- * @return {boolean}
- * - The value of `defaultMuted` from the media element.
- * - True indicates that the media should start muted.
- * - False indicates that the media should not start muted
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
- */
- 'defaultMuted',
-
- /**
- * Get the value of `autoplay` from the media element. `autoplay` indicates
- * that the media should start to play as soon as the page is ready.
- *
- * @method Html5#autoplay
- * @return {boolean}
- * - The value of `autoplay` from the media element.
- * - True indicates that the media should start as soon as the page loads.
- * - False indicates that the media should not start as soon as the page loads.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
- */
- 'autoplay',
-
- /**
- * Get the value of `controls` from the media element. `controls` indicates
- * whether the native media controls should be shown or hidden.
- *
- * @method Html5#controls
- * @return {boolean}
- * - The value of `controls` from the media element.
- * - True indicates that native controls should be showing.
- * - False indicates that native controls should be hidden.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-controls}
- */
- 'controls',
-
- /**
- * Get the value of `loop` from the media element. `loop` indicates
- * that the media should return to the start of the media and continue playing once
- * it reaches the end.
- *
- * @method Html5#loop
- * @return {boolean}
- * - The value of `loop` from the media element.
- * - True indicates that playback should seek back to start once
- * the end of a media is reached.
- * - False indicates that playback should not loop back to the start when the
- * end of the media is reached.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
- */
- 'loop',
-
- /**
- * Get the value of `playsinline` from the media element. `playsinline` indicates
- * to the browser that non-fullscreen playback is preferred when fullscreen
- * playback is the native default, such as in iOS Safari.
- *
- * @method Html5#playsinline
- * @return {boolean}
- * - The value of `playsinline` from the media element.
- * - True indicates that the media should play inline.
- * - False indicates that the media should not play inline.
- *
- * @see [Spec]{@link https://html.spec.whatwg.org/#attr-video-playsinline}
- */
- 'playsinline'].forEach(function (prop) {
- Html5.prototype[prop] = function () {
- return this.el_[prop] || this.el_.hasAttribute(prop);
- };
- });
-
-// Wrap native boolean attributes with setters that set both property and attribute
-// The list is as followed:
-// setMuted, setDefaultMuted, setAutoplay, setLoop, setPlaysinline
-// setControls is special-cased above
- [
- /**
- * Set the value of `muted` on the media element. `muted` indicates that the current
- * audio level should be silent.
- *
- * @method Html5#setMuted
- * @param {boolean} muted
- * - True if the audio should be set to silent
- * - False otherwise
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
- */
- 'muted',
-
- /**
- * Set the value of `defaultMuted` on the media element. `defaultMuted` indicates that the current
- * audio level should be silent, but will only effect the muted level on intial playback..
- *
- * @method Html5.prototype.setDefaultMuted
- * @param {boolean} defaultMuted
- * - True if the audio should be set to silent
- * - False otherwise
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
- */
- 'defaultMuted',
-
- /**
- * Set the value of `autoplay` on the media element. `autoplay` indicates
- * that the media should start to play as soon as the page is ready.
- *
- * @method Html5#setAutoplay
- * @param {boolean} autoplay
- * - True indicates that the media should start as soon as the page loads.
- * - False indicates that the media should not start as soon as the page loads.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
- */
- 'autoplay',
-
- /**
- * Set the value of `loop` on the media element. `loop` indicates
- * that the media should return to the start of the media and continue playing once
- * it reaches the end.
- *
- * @method Html5#setLoop
- * @param {boolean} loop
- * - True indicates that playback should seek back to start once
- * the end of a media is reached.
- * - False indicates that playback should not loop back to the start when the
- * end of the media is reached.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
- */
- 'loop',
-
- /**
- * Set the value of `playsinline` from the media element. `playsinline` indicates
- * to the browser that non-fullscreen playback is preferred when fullscreen
- * playback is the native default, such as in iOS Safari.
- *
- * @method Html5#setPlaysinline
- * @param {boolean} playsinline
- * - True indicates that the media should play inline.
- * - False indicates that the media should not play inline.
- *
- * @see [Spec]{@link https://html.spec.whatwg.org/#attr-video-playsinline}
- */
- 'playsinline'].forEach(function (prop) {
- Html5.prototype['set' + toTitleCase(prop)] = function (v) {
- this.el_[prop] = v;
-
- if (v) {
- this.el_.setAttribute(prop, prop);
- } else {
- this.el_.removeAttribute(prop);
- }
- };
- });
-
-// Wrap native properties with a getter
-// The list is as followed
-// paused, currentTime, buffered, volume, poster, preload, error, seeking
-// seekable, ended, playbackRate, defaultPlaybackRate, played, networkState
-// readyState, videoWidth, videoHeight
- [
- /**
- * Get the value of `paused` from the media element. `paused` indicates whether the media element
- * is currently paused or not.
- *
- * @method Html5#paused
- * @return {boolean}
- * The value of `paused` from the media element.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-paused}
- */
- 'paused',
-
- /**
- * Get the value of `currentTime` from the media element. `currentTime` indicates
- * the current second that the media is at in playback.
- *
- * @method Html5#currentTime
- * @return {number}
- * The value of `currentTime` from the media element.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-currenttime}
- */
- 'currentTime',
-
- /**
- * Get the value of `buffered` from the media element. `buffered` is a `TimeRange`
- * object that represents the parts of the media that are already downloaded and
- * available for playback.
- *
- * @method Html5#buffered
- * @return {TimeRange}
- * The value of `buffered` from the media element.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-buffered}
- */
- 'buffered',
-
- /**
- * Get the value of `volume` from the media element. `volume` indicates
- * the current playback volume of audio for a media. `volume` will be a value from 0
- * (silent) to 1 (loudest and default).
- *
- * @method Html5#volume
- * @return {number}
- * The value of `volume` from the media element. Value will be between 0-1.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume}
- */
- 'volume',
-
- /**
- * Get the value of `poster` from the media element. `poster` indicates
- * that the url of an image file that can/will be shown when no media data is available.
- *
- * @method Html5#poster
- * @return {string}
- * The value of `poster` from the media element. Value will be a url to an
- * image.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-video-poster}
- */
- 'poster',
-
- /**
- * Get the value of `preload` from the media element. `preload` indicates
- * what should download before the media is interacted with. It can have the following
- * values:
- * - none: nothing should be downloaded
- * - metadata: poster and the first few frames of the media may be downloaded to get
- * media dimensions and other metadata
- * - auto: allow the media and metadata for the media to be downloaded before
- * interaction
- *
- * @method Html5#preload
- * @return {string}
- * The value of `preload` from the media element. Will be 'none', 'metadata',
- * or 'auto'.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload}
- */
- 'preload',
-
- /**
- * Get the value of the `error` from the media element. `error` indicates any
- * MediaError that may have occured during playback. If error returns null there is no
- * current error.
- *
- * @method Html5#error
- * @return {MediaError|null}
- * The value of `error` from the media element. Will be `MediaError` if there
- * is a current error and null otherwise.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-error}
- */
- 'error',
-
- /**
- * Get the value of `seeking` from the media element. `seeking` indicates whether the
- * media is currently seeking to a new position or not.
- *
- * @method Html5#seeking
- * @return {boolean}
- * - The value of `seeking` from the media element.
- * - True indicates that the media is currently seeking to a new position.
- * - Flase indicates that the media is not seeking to a new position at this time.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seeking}
- */
- 'seeking',
-
- /**
- * Get the value of `seekable` from the media element. `seekable` returns a
- * `TimeRange` object indicating ranges of time that can currently be `seeked` to.
- *
- * @method Html5#seekable
- * @return {TimeRange}
- * The value of `seekable` from the media element. A `TimeRange` object
- * indicating the current ranges of time that can be seeked to.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seekable}
- */
- 'seekable',
-
- /**
- * Get the value of `ended` from the media element. `ended` indicates whether
- * the media has reached the end or not.
- *
- * @method Html5#ended
- * @return {boolean}
- * - The value of `ended` from the media element.
- * - True indicates that the media has ended.
- * - False indicates that the media has not ended.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended}
- */
- 'ended',
-
- /**
- * Get the value of `playbackRate` from the media element. `playbackRate` indicates
- * the rate at which the media is currently playing back. Examples:
- * - if playbackRate is set to 2, media will play twice as fast.
- * - if playbackRate is set to 0.5, media will play half as fast.
- *
- * @method Html5#playbackRate
- * @return {number}
- * The value of `playbackRate` from the media element. A number indicating
- * the current playback speed of the media, where 1 is normal speed.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
- */
- 'playbackRate',
-
- /**
- * Get the value of `defaultPlaybackRate` from the media element. `defaultPlaybackRate` indicates
- * the rate at which the media is currently playing back. This value will not indicate the current
- * `playbackRate` after playback has started, use {@link Html5#playbackRate} for that.
- *
- * Examples:
- * - if defaultPlaybackRate is set to 2, media will play twice as fast.
- * - if defaultPlaybackRate is set to 0.5, media will play half as fast.
- *
- * @method Html5.prototype.defaultPlaybackRate
- * @return {number}
- * The value of `defaultPlaybackRate` from the media element. A number indicating
- * the current playback speed of the media, where 1 is normal speed.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
- */
- 'defaultPlaybackRate',
-
- /**
- * Get the value of `played` from the media element. `played` returns a `TimeRange`
- * object representing points in the media timeline that have been played.
- *
- * @method Html5#played
- * @return {TimeRange}
- * The value of `played` from the media element. A `TimeRange` object indicating
- * the ranges of time that have been played.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-played}
- */
- 'played',
-
- /**
- * Get the value of `networkState` from the media element. `networkState` indicates
- * the current network state. It returns an enumeration from the following list:
- * - 0: NETWORK_EMPTY
- * - 1: NEWORK_IDLE
- * - 2: NETWORK_LOADING
- * - 3: NETWORK_NO_SOURCE
- *
- * @method Html5#networkState
- * @return {number}
- * The value of `networkState` from the media element. This will be a number
- * from the list in the description.
- *
- * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-networkstate}
- */
- 'networkState',
-
- /**
- * Get the value of `readyState` from the media element. `readyState` indicates
- * the current state of the media element. It returns an enumeration from the
- * following list:
- * - 0: HAVE_NOTHING
- * - 1: HAVE_METADATA
- * - 2: HAVE_CURRENT_DATA
- * - 3: HAVE_FUTURE_DATA
- * - 4: HAVE_ENOUGH_DATA
- *
- * @method Html5#readyState
- * @return {number}
- * The value of `readyState` from the media element. This will be a number
- * from the list in the description.
- *
- * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#ready-states}
- */
- 'readyState',
-
- /**
- * Get the value of `videoWidth` from the video element. `videoWidth` indicates
- * the current width of the video in css pixels.
- *
- * @method Html5#videoWidth
- * @return {number}
- * The value of `videoWidth` from the video element. This will be a number
- * in css pixels.
- *
- * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth}
- */
- 'videoWidth',
-
- /**
- * Get the value of `videoHeight` from the video element. `videoHeigth` indicates
- * the current height of the video in css pixels.
- *
- * @method Html5#videoHeight
- * @return {number}
- * The value of `videoHeight` from the video element. This will be a number
- * in css pixels.
- *
- * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth}
- */
- 'videoHeight'].forEach(function (prop) {
- Html5.prototype[prop] = function () {
- return this.el_[prop];
- };
- });
-
-// Wrap native properties with a setter in this format:
-// set + toTitleCase(name)
-// The list is as follows:
-// setVolume, setSrc, setPoster, setPreload, setPlaybackRate, setDefaultPlaybackRate
- [
- /**
- * Set the value of `volume` on the media element. `volume` indicates the current
- * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
- * so on.
- *
- * @method Html5#setVolume
- * @param {number} percentAsDecimal
- * The volume percent as a decimal. Valid range is from 0-1.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume}
- */
- 'volume',
-
- /**
- * Set the value of `src` on the media element. `src` indicates the current
- * {@link Tech~SourceObject} for the media.
- *
- * @method Html5#setSrc
- * @param {Tech~SourceObject} src
- * The source object to set as the current source.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-src}
- */
- 'src',
-
- /**
- * Set the value of `poster` on the media element. `poster` is the url to
- * an image file that can/will be shown when no media data is available.
- *
- * @method Html5#setPoster
- * @param {string} poster
- * The url to an image that should be used as the `poster` for the media
- * element.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-poster}
- */
- 'poster',
-
- /**
- * Set the value of `preload` on the media element. `preload` indicates
- * what should download before the media is interacted with. It can have the following
- * values:
- * - none: nothing should be downloaded
- * - metadata: poster and the first few frames of the media may be downloaded to get
- * media dimensions and other metadata
- * - auto: allow the media and metadata for the media to be downloaded before
- * interaction
- *
- * @method Html5#setPreload
- * @param {string} preload
- * The value of `preload` to set on the media element. Must be 'none', 'metadata',
- * or 'auto'.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload}
- */
- 'preload',
-
- /**
- * Set the value of `playbackRate` on the media element. `playbackRate` indicates
- * the rate at which the media should play back. Examples:
- * - if playbackRate is set to 2, media will play twice as fast.
- * - if playbackRate is set to 0.5, media will play half as fast.
- *
- * @method Html5#setPlaybackRate
- * @return {number}
- * The value of `playbackRate` from the media element. A number indicating
- * the current playback speed of the media, where 1 is normal speed.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
- */
- 'playbackRate',
-
- /**
- * Set the value of `defaultPlaybackRate` on the media element. `defaultPlaybackRate` indicates
- * the rate at which the media should play back upon initial startup. Changing this value
- * after a video has started will do nothing. Instead you should used {@link Html5#setPlaybackRate}.
- *
- * Example Values:
- * - if playbackRate is set to 2, media will play twice as fast.
- * - if playbackRate is set to 0.5, media will play half as fast.
- *
- * @method Html5.prototype.setDefaultPlaybackRate
- * @return {number}
- * The value of `defaultPlaybackRate` from the media element. A number indicating
- * the current playback speed of the media, where 1 is normal speed.
- *
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultplaybackrate}
- */
- 'defaultPlaybackRate'].forEach(function (prop) {
- Html5.prototype['set' + toTitleCase(prop)] = function (v) {
- this.el_[prop] = v;
- };
- });
-
-// wrap native functions with a function
-// The list is as follows:
-// pause, load play
- [
- /**
- * A wrapper around the media elements `pause` function. This will call the `HTML5`
- * media elements `pause` function.
- *
- * @method Html5#pause
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-pause}
- */
- 'pause',
-
- /**
- * A wrapper around the media elements `load` function. This will call the `HTML5`s
- * media element `load` function.
- *
- * @method Html5#load
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-load}
- */
- 'load',
-
- /**
- * A wrapper around the media elements `play` function. This will call the `HTML5`s
- * media element `play` function.
- *
- * @method Html5#play
- * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-play}
- */
- 'play'].forEach(function (prop) {
- Html5.prototype[prop] = function () {
- return this.el_[prop]();
- };
- });
-
- Tech.withSourceHandlers(Html5);
-
- /**
- * Native source handler for Html5, simply passes the source to the media element.
- *
- * @proprety {Tech~SourceObject} source
- * The source object
- *
- * @proprety {Html5} tech
- * The instance of the HTML5 tech.
- */
- Html5.nativeSourceHandler = {};
-
- /**
- * Check if the media element can play the given mime type.
- *
- * @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 media element can handle a source natively.
- *
- * @param {Tech~SourceObject} source
- * The source object
- *
- * @param {Object} [options]
- * Options to be passed to the tech.
- *
- * @return {string}
- * 'probably', 'maybe', or '' (empty string).
- */
- Html5.nativeSourceHandler.canHandleSource = function (source, options) {
-
- // If a type was provided we should rely on that
- if (source.type) {
- return Html5.nativeSourceHandler.canPlayType(source.type);
-
- // If no type, fall back to checking 'video/[EXTENSION]'
- } else if (source.src) {
- var ext = getFileExtension(source.src);
-
- return Html5.nativeSourceHandler.canPlayType('video/' + ext);
- }
-
- return '';
- };
-
- /**
- * Pass the source to the native media element.
- *
- * @param {Tech~SourceObject} source
- * The source object
- *
- * @param {Html5} tech
- * The instance of the Html5 tech
- *
- * @param {Object} [options]
- * The options to pass to the source
- */
- Html5.nativeSourceHandler.handleSource = function (source, tech, options) {
- tech.setSrc(source.src);
- };
-
- /**
- * A noop for the native dispose function, as cleanup is not needed.
- */
- Html5.nativeSourceHandler.dispose = function () {
- };
-
-// Register the native source handler
- Html5.registerSourceHandler(Html5.nativeSourceHandler);
-
- Tech.registerTech('Html5', Html5);
-
- var _templateObject$1 = taggedTemplateLiteralLoose(['\n Using the tech directly can be dangerous. I hope you know what you\'re doing.\n See https://github.com/videojs/video.js/issues/2617 for more info.\n '], ['\n Using the tech directly can be dangerous. I hope you know what you\'re doing.\n See https://github.com/videojs/video.js/issues/2617 for more info.\n ']);
-
- /**
- * @file player.js
- */
-// Subclasses Component
-// The following imports are used only to ensure that the corresponding modules
-// are always included in the video.js package. Importing the modules will
-// execute them and they will register themselves with video.js.
-// Import Html5 tech, at least for disposing the original video tag.
-// The following tech events are simply re-triggered
-// on the player when they happen
- var TECH_EVENTS_RETRIGGER = [
- /**
- * Fired while the user agent is downloading media data.
- *
- * @event Player#progress
- * @type {EventTarget~Event}
- */
- /**
- * Retrigger the `progress` event that was triggered by the {@link Tech}.
- *
- * @private
- * @method Player#handleTechProgress_
- * @fires Player#progress
- * @listens Tech#progress
- */
- 'progress',
-
- /**
- * Fires when the loading of an audio/video is aborted.
- *
- * @event Player#abort
- * @type {EventTarget~Event}
- */
- /**
- * Retrigger the `abort` event that was triggered by the {@link Tech}.
- *
- * @private
- * @method Player#handleTechAbort_
- * @fires Player#abort
- * @listens Tech#abort
- */
- 'abort',
-
- /**
- * Fires when the browser is intentionally not getting media data.
- *
- * @event Player#suspend
- * @type {EventTarget~Event}
- */
- /**
- * Retrigger the `suspend` event that was triggered by the {@link Tech}.
- *
- * @private
- * @method Player#handleTechSuspend_
- * @fires Player#suspend
- * @listens Tech#suspend
- */
- 'suspend',
-
- /**
- * Fires when the current playlist is empty.
- *
- * @event Player#emptied
- * @type {EventTarget~Event}
- */
- /**
- * Retrigger the `emptied` event that was triggered by the {@link Tech}.
- *
- * @private
- * @method Player#handleTechEmptied_
- * @fires Player#emptied
- * @listens Tech#emptied
- */
- 'emptied',
- /**
- * Fires when the browser is trying to get media data, but data is not available.
- *
- * @event Player#stalled
- * @type {EventTarget~Event}
- */
- /**
- * Retrigger the `stalled` event that was triggered by the {@link Tech}.
- *
- * @private
- * @method Player#handleTechStalled_
- * @fires Player#stalled
- * @listens Tech#stalled
- */
- 'stalled',
-
- /**
- * Fires when the browser has loaded meta data for the audio/video.
- *
- * @event Player#loadedmetadata
- * @type {EventTarget~Event}
- */
- /**
- * Retrigger the `stalled` event that was triggered by the {@link Tech}.
- *
- * @private
- * @method Player#handleTechLoadedmetadata_
- * @fires Player#loadedmetadata
- * @listens Tech#loadedmetadata
- */
- 'loadedmetadata',
-
- /**
- * Fires when the browser has loaded the current frame of the audio/video.
- *
- * @event Player#loadeddata
- * @type {event}
- */
- /**
- * Retrigger the `loadeddata` event that was triggered by the {@link Tech}.
- *
- * @private
- * @method Player#handleTechLoaddeddata_
- * @fires Player#loadeddata
- * @listens Tech#loadeddata
- */
- 'loadeddata',
-
- /**
- * Fires when the current playback position has changed.
- *
- * @event Player#timeupdate
- * @type {event}
- */
- /**
- * Retrigger the `timeupdate` event that was triggered by the {@link Tech}.
- *
- * @private
- * @method Player#handleTechTimeUpdate_
- * @fires Player#timeupdate
- * @listens Tech#timeupdate
- */
- 'timeupdate',
-
- /**
- * Fires when the playing speed of the audio/video is changed
- *
- * @event Player#ratechange
- * @type {event}
- */
- /**
- * Retrigger the `ratechange` event that was triggered by the {@link Tech}.
- *
- * @private
- * @method Player#handleTechRatechange_
- * @fires Player#ratechange
- * @listens Tech#ratechange
- */
- 'ratechange',
-
- /**
- * Fires when the video's intrinsic dimensions change
- *
- * @event Player#resize
- * @type {event}
- */
- /**
- * Retrigger the `resize` event that was triggered by the {@link Tech}.
- *
- * @private
- * @method Player#handleTechResize_
- * @fires Player#resize
- * @listens Tech#resize
- */
- 'resize',
-
- /**
- * Fires when the volume has been changed
- *
- * @event Player#volumechange
- * @type {event}
- */
- /**
- * Retrigger the `volumechange` event that was triggered by the {@link Tech}.
- *
- * @private
- * @method Player#handleTechVolumechange_
- * @fires Player#volumechange
- * @listens Tech#volumechange
- */
- 'volumechange',
-
- /**
- * Fires when the text track has been changed
- *
- * @event Player#texttrackchange
- * @type {event}
- */
- /**
- * Retrigger the `texttrackchange` event that was triggered by the {@link Tech}.
- *
- * @private
- * @method Player#handleTechTexttrackchange_
- * @fires Player#texttrackchange
- * @listens Tech#texttrackchange
- */
- 'texttrackchange'];
-
- /**
- * An instance of the `Player` class is created when any of the Video.js setup methods
- * are used to initialize a video.
- *
- * After an instance has been created it can be accessed globally in two ways:
- * 1. By calling `videojs('example_video_1');`
- * 2. By using it directly via `videojs.players.example_video_1;`
- *
- * @extends Component
- */
-
- var Player = function (_Component) {
- inherits(Player, _Component);
-
- /**
- * Create an instance of this class.
- *
- * @param {Element} tag
- * The original video DOM element used for configuring options.
- *
- * @param {Object} [options]
- * Object of option names and values.
- *
- * @param {Component~ReadyCallback} [ready]
- * Ready callback function.
- */
- function Player(tag, options, ready) {
- classCallCheck(this, Player);
-
- // Make sure tag ID exists
- tag.id = tag.id || 'vjs_video_' + 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 = assign(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;
-
- // If language is not set, get the closest lang attribute
- if (!options.language) {
- if (typeof tag.closest === 'function') {
- var closest = tag.closest('[lang]');
-
- if (closest) {
- options.language = closest.getAttribute('lang');
- }
- } else {
- var element = tag;
-
- while (element && element.nodeType === 1) {
- if (getAttributes(element).hasOwnProperty('lang')) {
- options.language = element.getAttribute('lang');
- break;
- }
- element = element.parentNode;
- }
- }
- }
-
- // Run base component initializing with new options
-
- // Turn off API access because we're loading a new tech that might load asynchronously
- var _this = possibleConstructorReturn(this, _Component.call(this, null, options, ready));
-
- _this.isReady_ = false;
-
- // Init state hasStarted_
- _this.hasStarted_ = false;
-
- // 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?');
- }
-
- // Store the original tag used to set options
- _this.tag = tag;
-
- // Store the tag attributes used to restore html5 element
- _this.tagAttributes = tag && getAttributes(tag);
-
- // Update current language
- _this.language(_this.options_.language);
-
- // Update Supported Languages
- if (options.languages) {
- // Normalise player option languages to lowercase
- var languagesToLower = {};
-
- Object.getOwnPropertyNames(options.languages).forEach(function (name$$1) {
- languagesToLower[name$$1.toLowerCase()] = options.languages[name$$1];
- });
- _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;
-
- // Set default values for lastVolume
- _this.cache_.lastVolume = 1;
-
- // 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();
-
- // Make this an evented object and use `el_` as its event bus.
- evented(_this, {eventBusKey: 'el_'});
-
- // 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 = mergeOptions(_this.options_);
-
- // Load plugins
- if (options.plugins) {
- var plugins = options.plugins;
-
- Object.keys(plugins).forEach(function (name$$1) {
- if (typeof this[name$$1] === 'function') {
- this[name$$1](plugins[name$$1]);
- } else {
- throw new Error('plugin "' + name$$1 + '" does not exist');
- }
- }, _this);
- }
-
- _this.options_.playerOptions = playerOptionsCopy;
-
- _this.middleware_ = [];
-
- _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');
- }
-
- // Set ARIA label and region role depending on player type
- _this.el_.setAttribute('role', 'region');
- if (_this.isAudio()) {
- _this.el_.setAttribute('aria-label', _this.localize('Audio Player'));
- } else {
- _this.el_.setAttribute('aria-label', _this.localize('Video Player'));
- }
-
- 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 (!IS_IOS) {
- _this.addClass('vjs-workinghover');
- }
-
- // Make player easily findable by ID
- Player.players[_this.id_] = _this;
-
- // Add a major version class to aid css in plugins
- var majorVersion = version.split('.')[0];
-
- _this.addClass('vjs-v' + majorVersion);
-
- // 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_);
-
- _this.changingSrc_ = false;
- return _this;
- }
-
- /**
- * Destroys the video player and does any necessary cleanup.
- *
- * This is especially helpful if you are dynamically adding and removing videos
- * to/from the DOM.
- *
- * @fires Player#dispose
- */
-
-
- Player.prototype.dispose = function dispose() {
- /**
- * Called when the player is being disposed of.
- *
- * @event Player#dispose
- * @type {EventTarget~Event}
- */
- 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 `Player`'s DOM element.
- *
- * @return {Element}
- * The DOM element that gets created.
- */
-
-
- Player.prototype.createEl = function createEl$$1() {
- var tag = this.tag;
- var el = void 0;
- var playerElIngest = this.playerElIngest_ = tag.parentNode && tag.parentNode.hasAttribute && tag.parentNode.hasAttribute('data-vjs-player');
-
- if (playerElIngest) {
- el = this.el_ = tag.parentNode;
- } else {
- el = this.el_ = _Component.prototype.createEl.call(this, 'div');
- }
-
- // set tabindex to -1 so we could focus on the player element
- tag.setAttribute('tabindex', '-1');
-
- // 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 = getAttributes(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
- if (window_1.VIDEOJS_NO_DYNAMIC_STYLE !== true) {
- this.styleEl_ = createStyleElement('vjs-styles-dimensions');
- var defaultsStyleEl = $('.vjs-styles-defaults');
- var head = $('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);
-
- // Hide any links within the video/audio tag, because IE doesn't hide them completely.
- var links = tag.getElementsByTagName('a');
-
- for (var i = 0; i < links.length; i++) {
- var linkEl = links.item(i);
-
- addClass(linkEl, 'vjs-hidden');
- linkEl.setAttribute('hidden', 'hidden');
- }
-
- // 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 && !playerElIngest) {
- 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
- //
- // Breaks iPhone, fixed in HTML5 setup.
- prependTo(tag, el);
- this.children_.unshift(tag);
-
- // Set lang attr on player to ensure CSS :lang() in consistent with player
- // if it's been set to something different to the doc
- this.el_.setAttribute('lang', this.language_);
-
- this.el_ = el;
-
- return el;
- };
-
- /**
- * A getter/setter for the `Player`'s width. Returns the player's configured value.
- * To get the current width use `currentWidth()`.
- *
- * @param {number} [value]
- * The value to set the `Player`'s width to.
- *
- * @return {number}
- * The current width of the `Player` when getting.
- */
-
-
- Player.prototype.width = function width(value) {
- return this.dimension('width', value);
- };
-
- /**
- * A getter/setter for the `Player`'s height. Returns the player's configured value.
- * To get the current height use `currentheight()`.
- *
- * @param {number} [value]
- * The value to set the `Player`'s heigth to.
- *
- * @return {number}
- * The current height of the `Player` when getting.
- */
-
-
- Player.prototype.height = function height(value) {
- return this.dimension('height', value);
- };
-
- /**
- * A getter/setter for the `Player`'s width & height.
- *
- * @param {string} dimension
- * This string can be:
- * - 'width'
- * - 'height'
- *
- * @param {number} [value]
- * Value for dimension specified in the first argument.
- *
- * @return {number}
- * The dimension arguments value when getting (width/height).
- */
-
-
- 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;
- this.updateStyleEl_();
- return;
- }
-
- var parsedVal = parseFloat(value);
-
- if (isNaN(parsedVal)) {
- log$1.error('Improper value "' + value + '" supplied for for ' + _dimension);
- return;
- }
-
- this[privDimension] = parsedVal;
- this.updateStyleEl_();
- };
-
- /**
- * A getter/setter/toggler for the vjs-fluid `className` on the `Player`.
- *
- * @param {boolean} [bool]
- * - A value of true adds the class.
- * - A value of false removes the class.
- * - No value will toggle the fluid class.
- *
- * @return {boolean|undefined}
- * - The value of fluid when getting.
- * - `undefined` when setting.
- */
-
-
- 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');
- }
-
- this.updateStyleEl_();
- };
-
- /**
- * Get/Set the aspect ratio
- *
- * @param {string} [ratio]
- * Aspect ratio for player
- *
- * @return {string|undefined}
- * returns the current aspect ratio when getting
- */
-
- /**
- * A getter/setter for the `Player`'s aspect ratio.
- *
- * @param {string} [ratio]
- * The value to set the `Player's aspect ratio to.
- *
- * @return {string|undefined}
- * - The current aspect ratio of the `Player` when getting.
- * - undefined when setting
- */
-
-
- 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).
- *
- * @private
- * @listens Tech#loadedmetadata
- */
-
-
- Player.prototype.updateStyleEl_ = function updateStyleEl_() {
- if (window_1.VIDEOJS_NO_DYNAMIC_STYLE === true) {
- var _width = typeof this.width_ === 'number' ? this.width_ : this.options_.width;
- var _height = typeof this.height_ === 'number' ? this.height_ : this.options_.height;
- var techEl = this.tech_ && this.tech_.el();
-
- if (techEl) {
- if (_width >= 0) {
- techEl.width = _width;
- }
- if (_height >= 0) {
- techEl.height = _height;
- }
- }
-
- return;
- }
-
- var width = void 0;
- var height = void 0;
- var aspectRatio = void 0;
- var idClass = void 0;
-
- // 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() > 0) {
- // 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);
-
- 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/Create an instance of playback {@link Tech} including element
- * and API methods. Then append the `Tech` element in `Player` as a child.
- *
- * @param {string} techName
- * name of the playback technology
- *
- * @param {string} source
- * video source
- *
- * @private
- */
-
-
- Player.prototype.loadTech_ = function loadTech_(techName, source) {
- var _this2 = this;
-
- // Pause and remove current playback technology
- if (this.tech_) {
- this.unloadTech_();
- }
-
- var titleTechName = toTitleCase(techName);
- var camelTechName = techName.charAt(0).toLowerCase() + techName.slice(1);
-
- // get rid of the HTML5 video tag as soon as we are using another tech
- if (titleTechName !== 'Html5' && this.tag) {
- Tech.getTech('Html5').disposeMediaElement(this.tag);
- this.tag.player = null;
- this.tag = null;
- }
-
- this.techName_ = titleTechName;
-
- // 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 = {
- source: source,
- 'nativeControlsForTouch': this.options_.nativeControlsForTouch,
- 'playerId': this.id(),
- 'techId': this.id() + '_' + titleTechName + '_api',
- 'autoplay': this.options_.autoplay,
- 'playsinline': this.options_.playsinline,
- 'preload': this.options_.preload,
- 'loop': this.options_.loop,
- 'muted': this.options_.muted,
- 'poster': this.poster(),
- 'language': this.language(),
- 'playerElIngest': this.playerElIngest_ || false,
- 'vtt.js': this.options_['vtt.js']
- };
-
- ALL.names.forEach(function (name$$1) {
- var props = ALL[name$$1];
-
- techOptions[props.getterName] = _this2[props.privateName];
- });
-
- assign(techOptions, this.options_[titleTechName]);
- assign(techOptions, this.options_[camelTechName]);
- assign(techOptions, this.options_[techName.toLowerCase()]);
-
- if (this.tag) {
- techOptions.tag = this.tag;
- }
-
- if (source && source.src === this.cache_.src && this.cache_.currentTime > 0) {
- techOptions.startTime = this.cache_.currentTime;
- }
-
- // Initialize tech instance
- var TechClass = Tech.getTech(techName);
-
- if (!TechClass) {
- throw new Error('No Tech named \'' + titleTechName + '\' exists! \'' + titleTechName + '\' should be registered using videojs.registerTech()\'');
- }
-
- this.tech_ = new TechClass(techOptions);
-
- // player.triggerReady is always async, so don't need this to be async
- this.tech_.ready(bind(this, this.handleTechReady_), true);
-
- textTrackConverter.jsonToTextTracks(this.textTracksJson_ || [], this.tech_);
-
- // Listen to all HTML5-defined events and trigger them on the player
- TECH_EVENTS_RETRIGGER.forEach(function (event) {
- _this2.on(_this2.tech_, event, _this2['handleTech' + toTitleCase(event) + '_']);
- });
- 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_, 'durationchange', this.handleTechDurationChange_);
- this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_);
- this.on(this.tech_, 'error', this.handleTechError_);
- this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_);
- this.on(this.tech_, 'posterchange', this.handleTechPosterChange_);
- this.on(this.tech_, 'textdata', this.handleTechTextData_);
-
- 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() && (titleTechName !== 'Html5' || !this.tag)) {
- prependTo(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 and dispose of the current playback {@link Tech}.
- *
- * @private
- */
-
-
- Player.prototype.unloadTech_ = function unloadTech_() {
- var _this3 = this;
-
- // Save the current text tracks so that we can reuse the same text tracks with the next tech
- ALL.names.forEach(function (name$$1) {
- var props = ALL[name$$1];
-
- _this3[props.privateName] = _this3[props.getterName]();
- });
- this.textTracksJson_ = textTrackConverter.textTracksToJson(this.tech_);
-
- this.isReady_ = false;
-
- this.tech_.dispose();
-
- this.tech_ = false;
- };
-
- /**
- * Return a reference to the current {@link Tech}.
- * It will print a warning by default about the danger of using the tech directly
- * but any argument that is passed in will silence the warning.
- *
- * @param {*} [safety]
- * Anything passed in to silence the warning
- *
- * @return {Tech}
- * The Tech
- */
-
-
- Player.prototype.tech = function tech(safety) {
- if (safety === undefined) {
- log$1.warn(tsml(_templateObject$1));
- }
-
- return this.tech_;
- };
-
- /**
- * Set up click and touch listeners for the playback element
- *
- * - On desktops: a click on the video itself will toggle playback
- * - On mobile devices: a click on the video toggles controls
- * which 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
- */
-
-
- 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.
- *
- * @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
- *
- * @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.currentSrc()) && this.tag && this.options_.autoplay && this.paused()) {
- try {
- // Chrome Fix. Fixed in Chrome v16.
- delete this.tag.poster;
- } catch (e) {
- log$1('deleting tag.poster throws in some browsers', e);
- }
- }
- };
-
- /**
- * Retrigger the `loadstart` event that was triggered by the {@link Tech}. This
- * function will also trigger {@link Player#firstplay} if it is the first loadstart
- * for a video.
- *
- * @fires Player#loadstart
- * @fires Player#firstplay
- * @listens Tech#loadstart
- * @private
- */
-
-
- Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() {
- // TODO: Update to use `emptied` event instead. See #1277.
-
- this.removeClass('vjs-ended');
- this.removeClass('vjs-seeking');
-
- // 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()) {
- /**
- * Fired when the user agent begins looking for media data
- *
- * @event Player#loadstart
- * @type {EventTarget~Event}
- */
- this.trigger('loadstart');
- this.trigger('firstplay');
- } else {
- // reset the hasStarted state
- this.hasStarted(false);
- this.trigger('loadstart');
- }
- };
-
- /**
- * Add/remove the vjs-has-started class
- *
- * @fires Player#firstplay
- *
- * @param {boolean} request
- * - true: adds the class
- * - false: remove the class
- *
- * @return {boolean}
- * the boolean value of hasStarted_
- */
-
-
- Player.prototype.hasStarted = function hasStarted(request) {
- if (request === undefined) {
- // act as getter, if we have no request to change
- return this.hasStarted_;
- }
-
- if (request === this.hasStarted_) {
- return;
- }
-
- this.hasStarted_ = request;
-
- if (this.hasStarted_) {
- this.addClass('vjs-has-started');
- this.trigger('firstplay');
- } else {
- this.removeClass('vjs-has-started');
- }
- };
-
- /**
- * Fired whenever the media begins or resumes playback
- *
- * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play}
- * @fires Player#play
- * @listens Tech#play
- * @private
- */
-
-
- 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
- this.hasStarted(true);
- /**
- * Triggered whenever an {@link Tech#play} event happens. Indicates that
- * playback has started or resumed.
- *
- * @event Player#play
- * @type {EventTarget~Event}
- */
- this.trigger('play');
- };
-
- /**
- * Retrigger the `waiting` event that was triggered by the {@link Tech}.
- *
- * @fires Player#waiting
- * @listens Tech#waiting
- * @private
- */
-
-
- Player.prototype.handleTechWaiting_ = function handleTechWaiting_() {
- var _this4 = this;
-
- this.addClass('vjs-waiting');
- /**
- * A readyState change on the DOM element has caused playback to stop.
- *
- * @event Player#waiting
- * @type {EventTarget~Event}
- */
- this.trigger('waiting');
- this.one('timeupdate', function () {
- return _this4.removeClass('vjs-waiting');
- });
- };
-
- /**
- * Retrigger the `canplay` event that was triggered by the {@link Tech}.
- * > Note: This is not consistent between browsers. See #1351
- *
- * @fires Player#canplay
- * @listens Tech#canplay
- * @private
- */
-
-
- Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() {
- this.removeClass('vjs-waiting');
- /**
- * The media has a readyState of HAVE_FUTURE_DATA or greater.
- *
- * @event Player#canplay
- * @type {EventTarget~Event}
- */
- this.trigger('canplay');
- };
-
- /**
- * Retrigger the `canplaythrough` event that was triggered by the {@link Tech}.
- *
- * @fires Player#canplaythrough
- * @listens Tech#canplaythrough
- * @private
- */
-
-
- Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() {
- this.removeClass('vjs-waiting');
- /**
- * The media has a readyState of HAVE_ENOUGH_DATA or greater. This means that the
- * entire media file can be played without buffering.
- *
- * @event Player#canplaythrough
- * @type {EventTarget~Event}
- */
- this.trigger('canplaythrough');
- };
-
- /**
- * Retrigger the `playing` event that was triggered by the {@link Tech}.
- *
- * @fires Player#playing
- * @listens Tech#playing
- * @private
- */
-
-
- Player.prototype.handleTechPlaying_ = function handleTechPlaying_() {
- this.removeClass('vjs-waiting');
- /**
- * The media is no longer blocked from playback, and has started playing.
- *
- * @event Player#playing
- * @type {EventTarget~Event}
- */
- this.trigger('playing');
- };
-
- /**
- * Retrigger the `seeking` event that was triggered by the {@link Tech}.
- *
- * @fires Player#seeking
- * @listens Tech#seeking
- * @private
- */
-
-
- Player.prototype.handleTechSeeking_ = function handleTechSeeking_() {
- this.addClass('vjs-seeking');
- /**
- * Fired whenever the player is jumping to a new time
- *
- * @event Player#seeking
- * @type {EventTarget~Event}
- */
- this.trigger('seeking');
- };
-
- /**
- * Retrigger the `seeked` event that was triggered by the {@link Tech}.
- *
- * @fires Player#seeked
- * @listens Tech#seeked
- * @private
- */
-
-
- Player.prototype.handleTechSeeked_ = function handleTechSeeked_() {
- this.removeClass('vjs-seeking');
- /**
- * Fired when the player has finished jumping to a new time
- *
- * @event Player#seeked
- * @type {EventTarget~Event}
- */
- this.trigger('seeked');
- };
-
- /**
- * Retrigger the `firstplay` event that was triggered by the {@link Tech}.
- *
- * @fires Player#firstplay
- * @listens Tech#firstplay
- * @deprecated As of 6.0 firstplay event is deprecated.
- * @deprecated As of 6.0 passing the `starttime` option to the player and the firstplay event are deprecated.
- * @private
- */
-
-
- 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) {
- log$1.warn('Passing the `starttime` option to the player will be deprecated in 6.0');
- this.currentTime(this.options_.starttime);
- }
-
- this.addClass('vjs-has-started');
- /**
- * Fired the first time a video is played. Not part of the HLS spec, and this is
- * probably not the best implementation yet, so use sparingly. If you don't have a
- * reason to prevent playback, use `myPlayer.one('play');` instead.
- *
- * @event Player#firstplay
- * @deprecated As of 6.0 firstplay event is deprecated.
- * @type {EventTarget~Event}
- */
- this.trigger('firstplay');
- };
-
- /**
- * Retrigger the `pause` event that was triggered by the {@link Tech}.
- *
- * @fires Player#pause
- * @listens Tech#pause
- * @private
- */
-
-
- Player.prototype.handleTechPause_ = function handleTechPause_() {
- this.removeClass('vjs-playing');
- this.addClass('vjs-paused');
- /**
- * Fired whenever the media has been paused
- *
- * @event Player#pause
- * @type {EventTarget~Event}
- */
- this.trigger('pause');
- };
-
- /**
- * Retrigger the `ended` event that was triggered by the {@link Tech}.
- *
- * @fires Player#ended
- * @listens Tech#ended
- * @private
- */
-
-
- Player.prototype.handleTechEnded_ = function handleTechEnded_() {
- this.addClass('vjs-ended');
- if (this.options_.loop) {
- this.currentTime(0);
- this.play();
- } else if (!this.paused()) {
- this.pause();
- }
-
- /**
- * Fired when the end of the media resource is reached (currentTime == duration)
- *
- * @event Player#ended
- * @type {EventTarget~Event}
- */
- this.trigger('ended');
- };
-
- /**
- * Fired when the duration of the media resource is first known or changed
- *
- * @listens Tech#durationchange
- * @private
- */
-
-
- Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() {
- this.duration(this.techGet_('duration'));
- };
-
- /**
- * Handle a click on the media element to play/pause
- *
- * @param {EventTarget~Event} event
- * the event that caused this function to trigger
- *
- * @listens Tech#mousedown
- * @private
- */
-
-
- 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.
- *
- * @listens Tech#tap
- * @private
- */
-
-
- Player.prototype.handleTechTap_ = function handleTechTap_() {
- this.userActive(!this.userActive());
- };
-
- /**
- * Handle touch to start
- *
- * @listens Tech#touchstart
- * @private
- */
-
-
- Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() {
- this.userWasActive = this.userActive();
- };
-
- /**
- * Handle touch to move
- *
- * @listens Tech#touchmove
- * @private
- */
-
-
- Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() {
- if (this.userWasActive) {
- this.reportUserActivity();
- }
- };
-
- /**
- * Handle touch to end
- *
- * @param {EventTarget~Event} event
- * the touchend event that triggered
- * this function
- *
- * @listens Tech#touchend
- * @private
- */
-
-
- 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
- * @listens Player#fullscreenchange
- */
-
-
- 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
- * @listens stageclick
- */
-
-
- Player.prototype.handleStageClick_ = function handleStageClick_() {
- this.reportUserActivity();
- };
-
- /**
- * Handle Tech Fullscreen Change
- *
- * @param {EventTarget~Event} event
- * the fullscreenchange event that triggered this function
- *
- * @param {Object} data
- * the data that was sent with the event
- *
- * @private
- * @listens Tech#fullscreenchange
- * @fires Player#fullscreenchange
- */
-
-
- Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) {
- if (data) {
- this.isFullscreen(data.isFullscreen);
- }
- /**
- * Fired when going in and out of fullscreen.
- *
- * @event Player#fullscreenchange
- * @type {EventTarget~Event}
- */
- this.trigger('fullscreenchange');
- };
-
- /**
- * Fires when an error occurred during the loading of an audio/video.
- *
- * @private
- * @listens Tech#error
- */
-
-
- Player.prototype.handleTechError_ = function handleTechError_() {
- var error = this.tech_.error();
-
- this.error(error);
- };
-
- /**
- * Retrigger the `textdata` event that was triggered by the {@link Tech}.
- *
- * @fires Player#textdata
- * @listens Tech#textdata
- * @private
- */
-
-
- Player.prototype.handleTechTextData_ = function handleTechTextData_() {
- var data = null;
-
- if (arguments.length > 1) {
- data = arguments[1];
- }
-
- /**
- * Fires when we get a textdata event from tech
- *
- * @event Player#textdata
- * @type {EventTarget~Event}
- */
- this.trigger('textdata', data);
- };
-
- /**
- * Get object for cached values.
- *
- * @return {Object}
- * get the current object cache
- */
-
-
- Player.prototype.getCache = function getCache() {
- return this.cache_;
- };
-
- /**
- * Pass values to the playback tech
- *
- * @param {string} [method]
- * the method to call
- *
- * @param {Object} arg
- * the argument to pass
- *
- * @private
- */
-
-
- Player.prototype.techCall_ = function techCall_(method, arg) {
- // If it's not ready yet, call method when it is
-
- this.ready(function () {
- if (method in allowedSetters) {
- return set$1(this.middleware_, this.tech_, method, arg);
- }
-
- try {
- if (this.tech_) {
- this.tech_[method](arg);
- }
- } catch (e) {
- log$1(e);
- throw e;
- }
- }, true);
- };
-
- /**
- * Get calls can't wait for the tech, and sometimes don't need to.
- *
- * @param {string} method
- * Tech method
- *
- * @return {Function|undefined}
- * the method or undefined
- *
- * @private
- */
-
-
- Player.prototype.techGet_ = function techGet_(method) {
- if (!this.tech_ || !this.tech_.isReady_) {
- return;
- }
-
- if (method in allowedGetters) {
- return get$1(this.middleware_, this.tech_, method);
- }
-
- // 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) {
- log$1('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e);
- throw e;
- }
-
- // When a method isn't available on the object it throws a TypeError
- if (e.name === 'TypeError') {
- log$1('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e);
- this.tech_.isReady_ = false;
- throw e;
- }
-
- // If error unknown, just log and throw
- log$1(e);
- throw e;
- }
- };
-
- /**
- * start media playback
- *
- * @return {Promise|undefined}
- * Returns a `Promise` if the browser returns one, for most browsers this will
- * return undefined.
- */
-
-
- Player.prototype.play = function play() {
- if (this.changingSrc_) {
- this.ready(function () {
- var retval = this.techGet_('play');
-
- // silence errors (unhandled promise from play)
- if (retval !== undefined && typeof retval.then === 'function') {
- retval.then(null, function (e) {
- });
- }
- });
-
- // Only calls the tech's play if we already have a src loaded
- } else if (this.isReady_ && (this.src() || this.currentSrc())) {
- return this.techGet_('play');
- } else {
- this.ready(function () {
- this.tech_.one('loadstart', function () {
- var retval = this.play();
-
- // silence errors (unhandled promise from play)
- if (retval !== undefined && typeof retval.then === 'function') {
- retval.then(null, function (e) {
- });
- }
- });
- });
- }
- };
-
- /**
- * Pause the video playback
- *
- * @return {Player}
- * A reference to the player object this function was called on
- */
-
-
- Player.prototype.pause = function pause() {
- this.techCall_('pause');
- };
-
- /**
- * Check if the player is paused or has yet to play
- *
- * @return {boolean}
- * - false: if the media is currently playing
- * - true: if media is not currently playing
- */
-
-
- 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;
- };
-
- /**
- * Get a TimeRange object representing the current ranges of time that the user
- * has played.
- *
- * @return {TimeRange}
- * A time range object that represents all the increments of time that have
- * been played.
- */
-
-
- Player.prototype.played = function played() {
- return this.techGet_('played') || createTimeRanges(0, 0);
- };
-
- /**
- * 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]
- * wether the user is or is not scrubbing
- *
- * @return {boolean}
- * The value of scrubbing when getting
- */
-
-
- Player.prototype.scrubbing = function scrubbing(isScrubbing) {
- if (typeof isScrubbing === 'undefined') {
- return this.scrubbing_;
- }
- this.scrubbing_ = !!isScrubbing;
-
- if (isScrubbing) {
- this.addClass('vjs-scrubbing');
- } else {
- this.removeClass('vjs-scrubbing');
- }
- };
-
- /**
- * Get or set the current time (in seconds)
- *
- * @param {number|string} [seconds]
- * The time to seek to in seconds
- *
- * @return {number}
- * - the current time in seconds when getting
- */
-
-
- Player.prototype.currentTime = function currentTime(seconds) {
- if (typeof seconds !== 'undefined') {
- this.techCall_('setCurrentTime', seconds);
- return;
- }
-
- // 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.
- this.cache_.currentTime = this.techGet_('currentTime') || 0;
- return this.cache_.currentTime;
- };
-
- /**
- * Normally gets the length in time of the video in seconds;
- * in all but the rarest use cases an argument will NOT be passed to the method
- *
- * > **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.
- *
- * @fires Player#durationchange
- *
- * @param {number} [seconds]
- * The duration of the video to set in seconds
- *
- * @return {number}
- * - The duration of the video in seconds when getting
- */
-
-
- Player.prototype.duration = function duration(seconds) {
- if (seconds === undefined) {
- // return NaN if the duration is not known
- return this.cache_.duration !== undefined ? this.cache_.duration : NaN;
- }
-
- seconds = parseFloat(seconds);
-
- // 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');
- }
- /**
- * @event Player#durationchange
- * @type {EventTarget~Event}
- */
- this.trigger('durationchange');
- }
- };
-
- /**
- * Calculates how much time is left in the video. Not part
- * of the native video API.
- *
- * @return {number}
- * The time remaining in seconds
- */
-
-
- Player.prototype.remainingTime = function remainingTime() {
- return this.duration() - this.currentTime();
- };
-
- /**
- * A remaining time function that is intented to be used when
- * the time is to be displayed directly to the user.
- *
- * @return {number}
- * The rounded time remaining in seconds
- */
-
-
- Player.prototype.remainingTimeDisplay = function remainingTimeDisplay() {
- return Math.floor(this.duration()) - Math.floor(this.currentTime());
- };
-
- //
- // Kind of like an array of portions of the video that have been downloaded.
-
- /**
- * Get a TimeRange object with an array of the times of the video
- * that have been downloaded. If you just want the percent of the
- * video that's been downloaded, use bufferedPercent.
- *
- * @see [Buffered Spec]{@link http://dev.w3.org/html5/spec/video.html#dom-media-buffered}
- *
- * @return {TimeRange}
- * A mock TimeRange object (following HTML spec)
- */
-
-
- Player.prototype.buffered = function buffered() {
- var buffered = this.techGet_('buffered');
-
- if (!buffered || !buffered.length) {
- buffered = createTimeRanges(0, 0);
- }
-
- return buffered;
- };
-
- /**
- * Get the percent (as a decimal) of the video that's been downloaded.
- * This method is not a part of the native HTML video API.
- *
- * @return {number}
- * A decimal between 0 and 1 representing the percent
- * that is bufferred 0 being 0% and 1 being 100%
- */
-
-
- Player.prototype.bufferedPercent = function bufferedPercent$$1() {
- return 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
- */
-
-
- Player.prototype.bufferedEnd = function bufferedEnd() {
- var buffered = this.buffered();
- var duration = this.duration();
- var end = buffered.end(buffered.length - 1);
-
- if (end > duration) {
- end = duration;
- }
-
- return end;
- };
-
- /**
- * Get or set the current volume of the media
- *
- * @param {number} [percentAsDecimal]
- * The new volume as a decimal percent:
- * - 0 is muted/0%/off
- * - 1.0 is 100%/full
- * - 0.5 is half volume or 50%
- *
- * @return {number}
- * The current volume as a percent when getting
- */
-
-
- Player.prototype.volume = function volume(percentAsDecimal) {
- var vol = void 0;
-
- if (percentAsDecimal !== undefined) {
- // Force value to between 0 and 1
- vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal)));
- this.cache_.volume = vol;
- this.techCall_('setVolume', vol);
-
- if (vol > 0) {
- this.lastVolume_(vol);
- }
-
- return;
- }
-
- // 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
- *
- * @param {boolean} [muted]
- * - true to mute
- * - false to unmute
- *
- * @return {boolean}
- * - true if mute is on and getting
- * - false if mute is off and getting
- */
-
-
- Player.prototype.muted = function muted(_muted) {
- if (_muted !== undefined) {
- this.techCall_('setMuted', _muted);
- return;
- }
- return this.techGet_('muted') || false;
- };
-
- /**
- * Get the current defaultMuted state, or turn defaultMuted on or off. defaultMuted
- * indicates the state of muted on intial playback.
- *
- * ```js
- * var myPlayer = videojs('some-player-id');
- *
- * myPlayer.src("http://www.example.com/path/to/video.mp4");
- *
- * // get, should be false
- * console.log(myPlayer.defaultMuted());
- * // set to true
- * myPlayer.defaultMuted(true);
- * // get should be true
- * console.log(myPlayer.defaultMuted());
- * ```
- *
- * @param {boolean} [defaultMuted]
- * - true to mute
- * - false to unmute
- *
- * @return {boolean|Player}
- * - true if defaultMuted is on and getting
- * - false if defaultMuted is off and getting
- * - A reference to the current player when setting
- */
-
-
- Player.prototype.defaultMuted = function defaultMuted(_defaultMuted) {
- if (_defaultMuted !== undefined) {
- return this.techCall_('setDefaultMuted', _defaultMuted);
- }
- return this.techGet_('defaultMuted') || false;
- };
-
- /**
- * Get the last volume, or set it
- *
- * @param {number} [percentAsDecimal]
- * The new last volume as a decimal percent:
- * - 0 is muted/0%/off
- * - 1.0 is 100%/full
- * - 0.5 is half volume or 50%
- *
- * @return {number}
- * the current value of lastVolume as a percent when getting
- *
- * @private
- */
-
-
- Player.prototype.lastVolume_ = function lastVolume_(percentAsDecimal) {
- if (percentAsDecimal !== undefined && percentAsDecimal !== 0) {
- this.cache_.lastVolume = percentAsDecimal;
- return;
- }
- return this.cache_.lastVolume;
- };
-
- /**
- * Check if current tech can support native fullscreen
- * (e.g. with built in controls like iOS, so not our flash swf)
- *
- * @return {boolean}
- * if native fullscreen is supported
- */
-
-
- Player.prototype.supportsFullScreen = function supportsFullScreen() {
- return this.techGet_('supportsFullScreen') || false;
- };
-
- /**
- * Check if the player is in fullscreen mode or tell the player that it
- * is or is not in fullscreen mode.
- *
- * > 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]
- * Set the players current fullscreen state
- *
- * @return {boolean}
- * - true if fullscreen is on and getting
- * - false if fullscreen is off and getting
- */
-
-
- Player.prototype.isFullscreen = function isFullscreen(isFS) {
- if (isFS !== undefined) {
- this.isFullscreen_ = !!isFS;
- return;
- }
- return !!this.isFullscreen_;
- };
-
- /**
- * Increase the size of the video to full screen
- * 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.
- *
- * @fires Player#fullscreenchange
- */
-
-
- Player.prototype.requestFullscreen = function requestFullscreen() {
- var fsApi = FullscreenApi;
-
- 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
- on(document_1, fsApi.fullscreenchange, bind(this, function documentFullscreenChange(e) {
- this.isFullscreen(document_1[fsApi.fullscreenElement]);
-
- // If cancelling fullscreen, remove event listener.
- if (this.isFullscreen() === false) {
- off(document_1, fsApi.fullscreenchange, documentFullscreenChange);
- }
- /**
- * @event Player#fullscreenchange
- * @type {EventTarget~Event}
- */
- 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();
- /**
- * @event Player#fullscreenchange
- * @type {EventTarget~Event}
- */
- this.trigger('fullscreenchange');
- }
- };
-
- /**
- * Return the video to its normal size after having been in full screen mode
- *
- * @fires Player#fullscreenchange
- */
-
-
- Player.prototype.exitFullscreen = function exitFullscreen() {
- var fsApi = FullscreenApi;
-
- this.isFullscreen(false);
-
- // Check for browser element fullscreen support
- if (fsApi.requestFullscreen) {
- document_1[fsApi.exitFullscreen]();
- } else if (this.tech_.supportsFullScreen()) {
- this.techCall_('exitFullScreen');
- } else {
- this.exitFullWindow();
- /**
- * @event Player#fullscreenchange
- * @type {EventTarget~Event}
- */
- this.trigger('fullscreenchange');
- }
- };
-
- /**
- * When fullscreen isn't supported we can stretch the
- * video container to as wide as the browser will let us.
- *
- * @fires Player#enterFullWindow
- */
-
-
- Player.prototype.enterFullWindow = function enterFullWindow() {
- this.isFullWindow = true;
-
- // Storing original doc overflow value to return to when fullscreen is off
- this.docOrigOverflow = document_1.documentElement.style.overflow;
-
- // Add listener for esc key to exit fullscreen
- on(document_1, 'keydown', bind(this, this.fullWindowOnEscKey));
-
- // Hide any scroll bars
- document_1.documentElement.style.overflow = 'hidden';
-
- // Apply fullscreen styles
- addClass(document_1.body, 'vjs-full-window');
-
- /**
- * @event Player#enterFullWindow
- * @type {EventTarget~Event}
- */
- 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
- */
-
-
- Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) {
- if (event.keyCode === 27) {
- if (this.isFullscreen() === true) {
- this.exitFullscreen();
- } else {
- this.exitFullWindow();
- }
- }
- };
-
- /**
- * Exit full window
- *
- * @fires Player#exitFullWindow
- */
-
-
- Player.prototype.exitFullWindow = function exitFullWindow() {
- this.isFullWindow = false;
- off(document_1, 'keydown', this.fullWindowOnEscKey);
-
- // Unhide scroll bars.
- document_1.documentElement.style.overflow = this.docOrigOverflow;
-
- // Remove fullscreen styles
- removeClass(document_1.body, 'vjs-full-window');
-
- // Resize the box, controller, and poster to original sizes
- // this.positionAll();
- /**
- * @event Player#exitFullWindow
- * @type {EventTarget~Event}
- */
- this.trigger('exitFullWindow');
- };
-
- /**
- * Check whether the player can play a given mimetype
- *
- * @see https://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-navigator-canplaytype
- *
- * @param {string} type
- * The mimetype to check
- *
- * @return {string}
- * 'probably', 'maybe', or '' (empty string)
- */
-
-
- Player.prototype.canPlayType = function canPlayType(type) {
- var can = void 0;
-
- // Loop through each playback technology in the options order
- for (var i = 0, j = this.options_.techOrder; i < j.length; i++) {
- var techName = j[i];
- var tech = Tech.getTech(techName);
-
- // Support old behavior of techs being registered as components.
- // Remove once that deprecated behavior is removed.
- if (!tech) {
- tech = Component.getComponent(techName);
- }
-
- // Check if the current tech is defined before continuing
- if (!tech) {
- log$1.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 or false
- */
-
-
- Player.prototype.selectSource = function selectSource(sources) {
- var _this5 = this;
-
- // Get only the techs specified in `techOrder` that exist and are supported by the
- // current platform
- var techs = this.options_.techOrder.map(function (techName) {
- return [techName, Tech.getTech(techName)];
- }).filter(function (_ref) {
- var techName = _ref[0],
- tech = _ref[1];
-
- // Check if the current tech is defined before continuing
- if (tech) {
- // Check if the browser supports this technology
- return tech.isSupported();
- }
-
- log$1.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 = void 0;
-
- outerArray.some(function (outerChoice) {
- return innerArray.some(function (innerChoice) {
- found = tester(outerChoice, innerChoice);
-
- if (found) {
- return true;
- }
- });
- });
-
- return found;
- };
-
- var foundSourceAndTech = void 0;
- var flip = function flip(fn) {
- return function (a, b) {
- return fn(b, a);
- };
- };
- var finder = function finder(_ref2, source) {
- var techName = _ref2[0],
- tech = _ref2[1];
-
- if (tech.canPlaySource(source, _this5.options_[techName.toLowerCase()])) {
- 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;
- };
-
- /**
- * Get or set the video source.
- *
- * @param {Tech~SourceObject|Tech~SourceObject[]|string} [source]
- * A SourceObject, an array of SourceObjects, or a string referencing
- * a URL to a media source. It is _highly recommended_ that an object
- * or array of objects is used here, so that source selection
- * algorithms can take the `type` into account.
- *
- * If not provided, this method acts as a getter.
- *
- * @return {string|undefined}
- * If the `source` argument is missing, returns the current source
- * URL. Otherwise, returns nothing/undefined.
- */
-
-
- Player.prototype.src = function src(source) {
- var _this6 = this;
-
- // getter usage
- if (typeof source === 'undefined') {
- return this.cache_.src || '';
- }
- // filter out invalid sources and turn our source into
- // an array of source objects
- var sources = filterSource(source);
-
- // if a source was passed in then it is invalid because
- // it was filtered to a zero length Array. So we have to
- // show an error
- if (!sources.length) {
- this.setTimeout(function () {
- this.error({code: 4, message: this.localize(this.options_.notSupportedMessage)});
- }, 0);
- return;
- }
-
- // intial sources
- this.cache_.sources = sources;
- this.changingSrc_ = true;
-
- // intial source
- this.cache_.source = sources[0];
-
- // middlewareSource is the source after it has been changed by middleware
- setSource(this, sources[0], function (middlewareSource, mws) {
- _this6.middleware_ = mws;
-
- var err = _this6.src_(middlewareSource);
-
- if (err) {
- if (sources.length > 1) {
- return _this6.src(sources.slice(1));
- }
-
- // We need to wrap this in a timeout to give folks a chance to add error event handlers
- _this6.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
- _this6.triggerReady();
-
- return;
- }
-
- _this6.changingSrc_ = false;
- // video element listed source
- _this6.cache_.src = middlewareSource.src;
-
- setTech(mws, _this6.tech_);
- });
- };
-
- /**
- * Set the source object on the tech, returns a boolean that indicates wether
- * there is a tech that can play the source or not
- *
- * @param {Tech~SourceObject} source
- * The source object to set on the Tech
- *
- * @return {Boolean}
- * - True if there is no Tech to playback this source
- * - False otherwise
- *
- * @private
- */
-
-
- Player.prototype.src_ = function src_(source) {
- var sourceTech = this.selectSource([source]);
-
- if (!sourceTech) {
- return true;
- }
-
- if (!titleCaseEquals(sourceTech.tech, this.techName_)) {
- this.changingSrc_ = true;
-
- // load this technology with the chosen source
- this.loadTech_(sourceTech.tech, sourceTech.source);
- return false;
- }
-
- // 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 (this.tech_.constructor.prototype.hasOwnProperty('setSource')) {
- this.techCall_('setSource', source);
- } else {
- this.techCall_('src', source.src);
- }
-
- if (this.options_.preload === 'auto') {
- this.load();
- }
-
- // Set the source synchronously if possible (#2326)
- }, true);
-
- return false;
- };
-
- /**
- * Begin loading the src data.
- */
-
-
- Player.prototype.load = function load() {
- this.techCall_('load');
- };
-
- /**
- * Reset the player. Loads the first tech in the techOrder,
- * and calls `reset` on the tech`.
- */
-
-
- Player.prototype.reset = function reset() {
- this.loadTech_(this.options_.techOrder[0], null);
- this.techCall_('reset');
- };
-
- /**
- * Returns all of the current source objects.
- *
- * @return {Tech~SourceObject[]}
- * The current source objects
- */
-
-
- Player.prototype.currentSources = function currentSources() {
- var source = this.currentSource();
- var sources = [];
-
- // assume `{}` or `{ src }`
- if (Object.keys(source).length !== 0) {
- sources.push(source);
- }
-
- return this.cache_.sources || sources;
- };
-
- /**
- * Returns the current source object.
- *
- * @return {Tech~SourceObject}
- * The current source object
- */
-
-
- Player.prototype.currentSource = function currentSource() {
- return this.cache_.source || {};
- };
-
- /**
- * 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
- */
-
-
- Player.prototype.currentSrc = function currentSrc() {
- return this.currentSource() && this.currentSource().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
- */
-
-
- Player.prototype.currentType = function currentType() {
- return this.currentSource() && this.currentSource().type || '';
- };
-
- /**
- * Get or set the preload attribute
- *
- * @param {boolean} [value]
- * - true means that we should preload
- * - false maens that we should not preload
- *
- * @return {string}
- * The preload attribute value when getting
- */
-
-
- Player.prototype.preload = function preload(value) {
- if (value !== undefined) {
- this.techCall_('setPreload', value);
- this.options_.preload = value;
- return;
- }
- return this.techGet_('preload');
- };
-
- /**
- * Get or set the autoplay attribute.
- *
- * @param {boolean} [value]
- * - true means that we should autoplay
- * - false means that we should not autoplay
- *
- * @return {string}
- * The current value of autoplay when getting
- */
-
-
- Player.prototype.autoplay = function autoplay(value) {
- if (value !== undefined) {
- this.techCall_('setAutoplay', value);
- this.options_.autoplay = value;
- return;
- }
- return this.techGet_('autoplay', value);
- };
-
- /**
- * Set or unset the playsinline attribute.
- * Playsinline tells the browser that non-fullscreen playback is preferred.
- *
- * @param {boolean} [value]
- * - true means that we should try to play inline by default
- * - false means that we should use the browser's default playback mode,
- * which in most cases is inline. iOS Safari is a notable exception
- * and plays fullscreen by default.
- *
- * @return {string|Player}
- * - the current value of playsinline
- * - the player when setting
- *
- * @see [Spec]{@link https://html.spec.whatwg.org/#attr-video-playsinline}
- */
-
-
- Player.prototype.playsinline = function playsinline(value) {
- if (value !== undefined) {
- this.techCall_('setPlaysinline', value);
- this.options_.playsinline = value;
- return this;
- }
- return this.techGet_('playsinline');
- };
-
- /**
- * Get or set the loop attribute on the video element.
- *
- * @param {boolean} [value]
- * - true means that we should loop the video
- * - false means that we should not loop the video
- *
- * @return {string}
- * The current value of loop when getting
- */
-
-
- Player.prototype.loop = function loop(value) {
- if (value !== undefined) {
- this.techCall_('setLoop', value);
- this.options_.loop = value;
- return;
- }
- return this.techGet_('loop');
- };
-
- /**
- * Get or set the poster image source url
- *
- * @fires Player#posterchange
- *
- * @param {string} [src]
- * Poster image source URL
- *
- * @return {string}
- * The current value of poster when getting
- */
-
-
- 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 event fires when the poster image is changed on the player.
- *
- * @event Player#posterchange
- * @type {EventTarget~Event}
- */
- this.trigger('posterchange');
- };
-
- /**
- * 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
- * source if the player user hasn't set a poster through
- * the normal APIs.
- *
- * @fires Player#posterchange
- * @listens Tech#posterchange
- * @private
- */
-
-
- 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.
- *
- * @fires Player#controlsenabled
- *
- * @param {boolean} [bool]
- * - true to turn controls on
- * - false to turn controls off
- *
- * @return {boolean}
- * The current value of controls when getting
- */
-
-
- Player.prototype.controls = function controls(bool) {
- if (bool !== undefined) {
- bool = !!bool;
-
- // 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');
- /**
- * @event Player#controlsenabled
- * @type {EventTarget~Event}
- */
- this.trigger('controlsenabled');
-
- if (!this.usingNativeControls()) {
- this.addTechControlsListeners_();
- }
- } else {
- this.removeClass('vjs-controls-enabled');
- this.addClass('vjs-controls-disabled');
- /**
- * @event Player#controlsdisabled
- * @type {EventTarget~Event}
- */
- this.trigger('controlsdisabled');
-
- if (!this.usingNativeControls()) {
- this.removeTechControlsListeners_();
- }
- }
- }
- return;
- }
- 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**
- *
- * @fires Player#usingnativecontrols
- * @fires Player#usingcustomcontrols
- *
- * @param {boolean} [bool]
- * - true to turn native controls on
- * - false to turn native controls off
- *
- * @return {boolean}
- * The current value of native controls when getting
- */
-
-
- Player.prototype.usingNativeControls = function usingNativeControls(bool) {
- if (bool !== undefined) {
- bool = !!bool;
-
- // 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 Player#usingnativecontrols
- * @type {EventTarget~Event}
- */
- this.trigger('usingnativecontrols');
- } else {
- this.removeClass('vjs-using-native-controls');
-
- /**
- * player is using the custom HTML controls
- *
- * @event Player#usingcustomcontrols
- * @type {EventTarget~Event}
- */
- this.trigger('usingcustomcontrols');
- }
- }
- return;
- }
- return !!this.usingNativeControls_;
- };
-
- /**
- * Set or get the current MediaError
- *
- * @fires Player#error
- *
- * @param {MediaError|string|number} [err]
- * A MediaError or a string/number to be turned
- * into a MediaError
- *
- * @return {MediaError|null}
- * The current MediaError when getting (or null)
- */
-
-
- 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');
- if (this.errorDisplay) {
- this.errorDisplay.close();
- }
- return;
- }
-
- this.error_ = new MediaError(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
- log$1.error('(CODE:' + this.error_.code + ' ' + MediaError.errorTypes[this.error_.code] + ')', this.error_.message, this.error_);
-
- /**
- * @event Player#error
- * @type {EventTarget~Event}
- */
- this.trigger('error');
-
- return;
- };
-
- /**
- * Report user activity
- *
- * @param {Object} event
- * Event object
- */
-
-
- Player.prototype.reportUserActivity = function reportUserActivity(event) {
- this.userActivity_ = true;
- };
-
- /**
- * Get/set if user is active
- *
- * @fires Player#useractive
- * @fires Player#userinactive
- *
- * @param {boolean} [bool]
- * - true if the user is active
- * - false if the user is inactive
- *
- * @return {boolean}
- * The current value of userActive when getting
- */
-
-
- 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');
- /**
- * @event Player#useractive
- * @type {EventTarget~Event}
- */
- 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');
- /**
- * @event Player#userinactive
- * @type {EventTarget~Event}
- */
- this.trigger('userinactive');
- }
- }
- return;
- }
- return this.userActive_;
- };
-
- /**
- * Listen for user activity based on timeout value
- *
- * @private
- */
-
-
- Player.prototype.listenForUserActivity_ = function listenForUserActivity_() {
- var mouseInProgress = void 0;
- var lastMoveX = void 0;
- var lastMoveY = void 0;
- var handleActivity = 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 = void 0;
-
- 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 activity check 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}
- * The current playback rate when getting or 1.0
- */
-
-
- Player.prototype.playbackRate = function playbackRate(rate) {
- if (rate !== undefined) {
- this.techCall_('setPlaybackRate', rate);
- return;
- }
-
- if (this.tech_ && this.tech_.featuresPlaybackRate) {
- return this.techGet_('playbackRate');
- }
- return 1.0;
- };
-
- /**
- * Gets or sets the current default playback rate. A default playback rate of
- * 1.0 represents normal speed and 0.5 would indicate half-speed playback, for instance.
- * defaultPlaybackRate will only represent what the intial playbackRate of a video was, not
- * not the current playbackRate.
- *
- * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-defaultplaybackrate
- *
- * @param {number} [rate]
- * New default playback rate to set.
- *
- * @return {number|Player}
- * - The default playback rate when getting or 1.0
- * - the player when setting
- */
-
-
- Player.prototype.defaultPlaybackRate = function defaultPlaybackRate(rate) {
- if (rate !== undefined) {
- return this.techCall_('setDefaultPlaybackRate', rate);
- }
-
- if (this.tech_ && this.tech_.featuresPlaybackRate) {
- return this.techGet_('defaultPlaybackRate');
- }
- return 1.0;
- };
-
- /**
- * Gets or sets the audio flag
- *
- * @param {boolean} bool
- * - true signals that this is an audio player
- * - false signals that this is not an audio player
- *
- * @return {boolean}
- * The current value of isAudio when getting
- */
-
-
- Player.prototype.isAudio = function isAudio(bool) {
- if (bool !== undefined) {
- this.isAudio_ = !!bool;
- return;
- }
-
- return !!this.isAudio_;
- };
-
- /**
- * A helper method for adding a {@link TextTrack} to our
- * {@link TextTrackList}.
- *
- * In addition to the W3C settings we allow adding additional info through options.
- *
- * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack
- *
- * @param {string} [kind]
- * the kind of TextTrack you are adding
- *
- * @param {string} [label]
- * the label to give the TextTrack label
- *
- * @param {string} [language]
- * the language to set on the TextTrack
- *
- * @return {TextTrack|undefined}
- * the TextTrack that was added or undefined
- * if there is no tech
- */
-
-
- Player.prototype.addTextTrack = function addTextTrack(kind, label, language) {
- if (this.tech_) {
- return this.tech_.addTextTrack(kind, label, language);
- }
- };
-
- /**
- * Create a remote {@link TextTrack} and an {@link HTMLTrackElement}. It will
- * automatically removed from the video element whenever the source changes, unless
- * manualCleanup is set to false.
- *
- * @param {Object} options
- * Options to pass to {@link HTMLTrackElement} during creation. See
- * {@link HTMLTrackElement} for object properties that you should use.
- *
- * @param {boolean} [manualCleanup=true] if set to false, the TextTrack will be
- *
- * @return {HtmlTrackElement}
- * the HTMLTrackElement that was created and added
- * to the HtmlTrackElementList and the remote
- * TextTrackList
- *
- * @deprecated The default value of the "manualCleanup" parameter will default
- * to "false" in upcoming versions of Video.js
- */
-
-
- Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) {
- if (this.tech_) {
- return this.tech_.addRemoteTextTrack(options, manualCleanup);
- }
- };
-
- /**
- * Remove a remote {@link TextTrack} from the respective
- * {@link TextTrackList} and {@link HtmlTrackElementList}.
- *
- * @param {Object} track
- * Remote {@link TextTrack} to remove
- *
- * @return {undefined}
- * does not return anything
- */
-
-
- Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack() {
- var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref3$track = _ref3.track,
- track = _ref3$track === undefined ? arguments[0] : _ref3$track;
-
- // destructure the input into an object with a track argument, defaulting to arguments[0]
- // default the whole argument to an empty object if nothing was passed in
-
- if (this.tech_) {
- return this.tech_.removeRemoteTextTrack(track);
- }
- };
-
- /**
- * Gets available media playback quality metrics as specified by the W3C's Media
- * Playback Quality API.
- *
- * @see [Spec]{@link https://wicg.github.io/media-playback-quality}
- *
- * @return {Object|undefined}
- * An object with supported media playback quality metrics or undefined if there
- * is no tech or the tech does not support it.
- */
-
-
- Player.prototype.getVideoPlaybackQuality = function getVideoPlaybackQuality() {
- return this.techGet_('getVideoPlaybackQuality');
- };
-
- /**
- * Get video width
- *
- * @return {number}
- * current video width
- */
-
-
- Player.prototype.videoWidth = function videoWidth() {
- return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0;
- };
-
- /**
- * Get video height
- *
- * @return {number}
- * current video height
- */
-
-
- Player.prototype.videoHeight = function videoHeight() {
- return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0;
- };
-
- /**
- * 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 language code to set the player to
- *
- * @return {string}
- * The current language code when getting
- */
-
-
- Player.prototype.language = function language(code) {
- if (code === undefined) {
- return this.language_;
- }
-
- this.language_ = String(code).toLowerCase();
- };
-
- /**
- * 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}
- * An array of of supported languages
- */
-
-
- Player.prototype.languages = function languages() {
- return mergeOptions(Player.prototype.options_.languages, this.languages_);
- };
-
- /**
- * returns a JavaScript object reperesenting the current track
- * information. **DOES not return it as JSON**
- *
- * @return {Object}
- * Object representing the current of track info
- */
-
-
- Player.prototype.toJSON = function toJSON() {
- var options = mergeOptions(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 = mergeOptions(track);
- track.player = undefined;
- options.tracks[i] = track;
- }
-
- return options;
- };
-
- /**
- * Creates a simple modal dialog (an instance of the {@link ModalDialog}
- * component) that immediately overlays the player with arbitrary
- * content and removes itself when closed.
- *
- * @param {string|Function|Element|Array|null} content
- * Same as {@link 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 {@link ModalDialog}.
- *
- * @return {ModalDialog}
- * the {@link ModalDialog} that was created
- */
-
-
- Player.prototype.createModal = function createModal(content, options) {
- var _this7 = this;
-
- options = options || {};
- options.content = content || '';
-
- var modal = new ModalDialog(this, options);
-
- this.addChild(modal);
- modal.on('dispose', function () {
- _this7.removeChild(modal);
- });
-
- modal.open();
- return modal;
- };
-
- /**
- * Gets tag settings
- *
- * @param {Element} tag
- * The player tag
- *
- * @return {Object}
- * An object containing all of the settings
- * for a player tag
- */
-
-
- Player.getTagSettings = function getTagSettings(tag) {
- var baseOptions = {
- sources: [],
- tracks: []
- };
-
- var tagOptions = getAttributes(tag);
- var dataSetup = tagOptions['data-setup'];
-
- if (hasClass(tag, 'vjs-fluid')) {
- tagOptions.fluid = true;
- }
-
- // Check if data-setup attr exists.
- if (dataSetup !== null) {
- // Parse options JSON
- // If empty string, make it a parsable json object.
- var _safeParseTuple = tuple(dataSetup || '{}'),
- err = _safeParseTuple[0],
- data = _safeParseTuple[1];
-
- if (err) {
- log$1.error(err);
- }
- assign(tagOptions, data);
- }
-
- assign(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(getAttributes(child));
- } else if (childName === 'track') {
- baseOptions.tracks.push(getAttributes(child));
- }
- }
- }
-
- return baseOptions;
- };
-
- /**
- * Determine wether or not flexbox is supported
- *
- * @return {boolean}
- * - true if flexbox is supported
- * - false if flexbox is not supported
- */
-
-
- Player.prototype.flexNotSupported_ = function flexNotSupported_() {
- var elem = document_1.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 ||
- // IE10-specific (2012 flex spec)
- 'msFlexOrder' in elem.style);
- };
-
- return Player;
- }(Component);
-
- /**
- * Get the {@link VideoTrackList}
- * @link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist
- *
- * @return {VideoTrackList}
- * the current video track list
- *
- * @method Player.prototype.videoTracks
- */
-
- /**
- * Get the {@link AudioTrackList}
- * @link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist
- *
- * @return {AudioTrackList}
- * the current audio track list
- *
- * @method Player.prototype.audioTracks
- */
-
- /**
- * Get the {@link TextTrackList}
- *
- * @link http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks
- *
- * @return {TextTrackList}
- * the current text track list
- *
- * @method Player.prototype.textTracks
- */
-
- /**
- * Get the remote {@link TextTrackList}
- *
- * @return {TextTrackList}
- * The current remote text track list
- *
- * @method Player.prototype.remoteTextTracks
- */
-
- /**
- * Get the remote {@link HtmlTrackElementList} tracks.
- *
- * @return {HtmlTrackElementList}
- * The current remote text track element list
- *
- * @method Player.prototype.remoteTextTrackEls
- */
-
- ALL.names.forEach(function (name$$1) {
- var props = ALL[name$$1];
-
- Player.prototype[props.getterName] = function () {
- if (this.tech_) {
- return this.tech_[props.getterName]();
- }
-
- // if we have not yet loadTech_, we create {video,audio,text}Tracks_
- // these will be passed to the tech during loading
- this[props.privateName] = this[props.privateName] || new props.ListClass();
- return this[props.privateName];
- };
- });
-
- /**
- * Global player list
- *
- * @type {Object}
- */
- Player.players = {};
-
- var navigator$1 = window_1.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: Tech.defaultTechOrder_,
-
- html5: {},
- flash: {},
-
- // 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: navigator$1 && (navigator$1.languages && navigator$1.languages[0] || navigator$1.userLanguage || navigator$1.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.'
- };
-
- [
- /**
- * 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 Player#ended
- */
- '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 Player#seeking
- */
- 'seeking',
- /**
- * Returns the TimeRanges of the media that are currently available
- * for seeking to.
- *
- * @return {TimeRanges} the seekable intervals of the media timeline
- * @method Player#seekable
- */
- 'seekable',
- /**
- * 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 Player#networkState
- */
- '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 Player#readyState
- */
- 'readyState'].forEach(function (fn) {
- Player.prototype[fn] = function () {
- return this.techGet_(fn);
- };
- });
-
- TECH_EVENTS_RETRIGGER.forEach(function (event) {
- Player.prototype['handleTech' + toTitleCase(event) + '_'] = function () {
- return this.trigger(event);
- };
- });
-
- /**
- * Fired when the player has initial duration and dimension information
- *
- * @event Player#loadedmetadata
- * @type {EventTarget~Event}
- */
-
- /**
- * Fired when the player has downloaded data at the current playback position
- *
- * @event Player#loadeddata
- * @type {EventTarget~Event}
- */
-
- /**
- * 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 Player#timeupdate
- * @type {EventTarget~Event}
- */
-
- /**
- * Fired when the volume changes
- *
- * @event Player#volumechange
- * @type {EventTarget~Event}
- */
-
- /**
- * Reports whether or not a player has a plugin available.
- *
- * This does not report whether or not the plugin has ever been initialized
- * on this player. For that, [usingPlugin]{@link Player#usingPlugin}.
- *
- * @method Player#hasPlugin
- * @param {string} name
- * The name of a plugin.
- *
- * @return {boolean}
- * Whether or not this player has the requested plugin available.
- */
-
- /**
- * Reports whether or not a player is using a plugin by name.
- *
- * For basic plugins, this only reports whether the plugin has _ever_ been
- * initialized on this player.
- *
- * @method Player#usingPlugin
- * @param {string} name
- * The name of a plugin.
- *
- * @return {boolean}
- * Whether or not this player is using the requested plugin.
- */
-
- Component.registerComponent('Player', Player);
-
- /**
- * @file plugin.js
- */
- /**
- * The base plugin name.
- *
- * @private
- * @constant
- * @type {string}
- */
- var BASE_PLUGIN_NAME = 'plugin';
-
- /**
- * The key on which a player's active plugins cache is stored.
- *
- * @private
- * @constant
- * @type {string}
- */
- var PLUGIN_CACHE_KEY = 'activePlugins_';
-
- /**
- * Stores registered plugins in a private space.
- *
- * @private
- * @type {Object}
- */
- var pluginStorage = {};
-
- /**
- * Reports whether or not a plugin has been registered.
- *
- * @private
- * @param {string} name
- * The name of a plugin.
- *
- * @returns {boolean}
- * Whether or not the plugin has been registered.
- */
- var pluginExists = function pluginExists(name) {
- return pluginStorage.hasOwnProperty(name);
- };
-
- /**
- * Get a single registered plugin by name.
- *
- * @private
- * @param {string} name
- * The name of a plugin.
- *
- * @returns {Function|undefined}
- * The plugin (or undefined).
- */
- var getPlugin = function getPlugin(name) {
- return pluginExists(name) ? pluginStorage[name] : undefined;
- };
-
- /**
- * Marks a plugin as "active" on a player.
- *
- * Also, ensures that the player has an object for tracking active plugins.
- *
- * @private
- * @param {Player} player
- * A Video.js player instance.
- *
- * @param {string} name
- * The name of a plugin.
- */
- var markPluginAsActive = function markPluginAsActive(player, name) {
- player[PLUGIN_CACHE_KEY] = player[PLUGIN_CACHE_KEY] || {};
- player[PLUGIN_CACHE_KEY][name] = true;
- };
-
- /**
- * Triggers a pair of plugin setup events.
- *
- * @private
- * @param {Player} player
- * A Video.js player instance.
- *
- * @param {Plugin~PluginEventHash} hash
- * A plugin event hash.
- *
- * @param {Boolean} [before]
- * If true, prefixes the event name with "before". In other words,
- * use this to trigger "beforepluginsetup" instead of "pluginsetup".
- */
- var triggerSetupEvent = function triggerSetupEvent(player, hash, before) {
- var eventName = (before ? 'before' : '') + 'pluginsetup';
-
- player.trigger(eventName, hash);
- player.trigger(eventName + ':' + hash.name, hash);
- };
-
- /**
- * Takes a basic plugin function and returns a wrapper function which marks
- * on the player that the plugin has been activated.
- *
- * @private
- * @param {string} name
- * The name of the plugin.
- *
- * @param {Function} plugin
- * The basic plugin.
- *
- * @returns {Function}
- * A wrapper function for the given plugin.
- */
- var createBasicPlugin = function createBasicPlugin(name, plugin) {
- var basicPluginWrapper = function basicPluginWrapper() {
-
- // We trigger the "beforepluginsetup" and "pluginsetup" events on the player
- // regardless, but we want the hash to be consistent with the hash provided
- // for advanced plugins.
- //
- // The only potentially counter-intuitive thing here is the `instance` in
- // the "pluginsetup" event is the value returned by the `plugin` function.
- triggerSetupEvent(this, {name: name, plugin: plugin, instance: null}, true);
-
- var instance = plugin.apply(this, arguments);
-
- markPluginAsActive(this, name);
- triggerSetupEvent(this, {name: name, plugin: plugin, instance: instance});
-
- return instance;
- };
-
- Object.keys(plugin).forEach(function (prop) {
- basicPluginWrapper[prop] = plugin[prop];
- });
-
- return basicPluginWrapper;
- };
-
- /**
- * Takes a plugin sub-class and returns a factory function for generating
- * instances of it.
- *
- * This factory function will replace itself with an instance of the requested
- * sub-class of Plugin.
- *
- * @private
- * @param {string} name
- * The name of the plugin.
- *
- * @param {Plugin} PluginSubClass
- * The advanced plugin.
- *
- * @returns {Function}
- */
- var createPluginFactory = function createPluginFactory(name, PluginSubClass) {
-
- // Add a `name` property to the plugin prototype so that each plugin can
- // refer to itself by name.
- PluginSubClass.prototype.name = name;
-
- return function () {
- triggerSetupEvent(this, {name: name, plugin: PluginSubClass, instance: null}, true);
-
- for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
- args[_key] = arguments[_key];
- }
-
- var instance = new (Function.prototype.bind.apply(PluginSubClass, [null].concat([this].concat(args))))();
-
- // The plugin is replaced by a function that returns the current instance.
- this[name] = function () {
- return instance;
- };
-
- triggerSetupEvent(this, instance.getEventHash());
-
- return instance;
- };
- };
-
- /**
- * Parent class for all advanced plugins.
- *
- * @mixes module:evented~EventedMixin
- * @mixes module:stateful~StatefulMixin
- * @fires Player#beforepluginsetup
- * @fires Player#beforepluginsetup:$name
- * @fires Player#pluginsetup
- * @fires Player#pluginsetup:$name
- * @listens Player#dispose
- * @throws {Error}
- * If attempting to instantiate the base {@link Plugin} class
- * directly instead of via a sub-class.
- */
-
- var Plugin = function () {
-
- /**
- * Creates an instance of this class.
- *
- * Sub-classes should call `super` to ensure plugins are properly initialized.
- *
- * @param {Player} player
- * A Video.js player instance.
- */
- function Plugin(player) {
- classCallCheck(this, Plugin);
-
- if (this.constructor === Plugin) {
- throw new Error('Plugin must be sub-classed; not directly instantiated.');
- }
-
- this.player = player;
-
- // Make this object evented, but remove the added `trigger` method so we
- // use the prototype version instead.
- evented(this);
- delete this.trigger;
-
- stateful(this, this.constructor.defaultState);
- markPluginAsActive(player, this.name);
-
- // Auto-bind the dispose method so we can use it as a listener and unbind
- // it later easily.
- this.dispose = bind(this, this.dispose);
-
- // If the player is disposed, dispose the plugin.
- player.on('dispose', this.dispose);
- }
-
- /**
- * Each event triggered by plugins includes a hash of additional data with
- * conventional properties.
- *
- * This returns that object or mutates an existing hash.
- *
- * @param {Object} [hash={}]
- * An object to be used as event an event hash.
- *
- * @returns {Plugin~PluginEventHash}
- * An event hash object with provided properties mixed-in.
- */
-
-
- Plugin.prototype.getEventHash = function getEventHash() {
- var hash = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-
- hash.name = this.name;
- hash.plugin = this.constructor;
- hash.instance = this;
- return hash;
- };
-
- /**
- * Triggers an event on the plugin object and overrides
- * {@link module:evented~EventedMixin.trigger|EventedMixin.trigger}.
- *
- * @param {string|Object} event
- * An event type or an object with a type property.
- *
- * @param {Object} [hash={}]
- * Additional data hash to merge with a
- * {@link Plugin~PluginEventHash|PluginEventHash}.
- *
- * @returns {boolean}
- * Whether or not default was prevented.
- */
-
-
- Plugin.prototype.trigger = function trigger$$1(event) {
- var hash = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- return trigger(this.eventBusEl_, event, this.getEventHash(hash));
- };
-
- /**
- * Handles "statechanged" events on the plugin. No-op by default, override by
- * subclassing.
- *
- * @abstract
- * @param {Event} e
- * An event object provided by a "statechanged" event.
- *
- * @param {Object} e.changes
- * An object describing changes that occurred with the "statechanged"
- * event.
- */
-
-
- Plugin.prototype.handleStateChanged = function handleStateChanged(e) {
- };
-
- /**
- * Disposes a plugin.
- *
- * Subclasses can override this if they want, but for the sake of safety,
- * it's probably best to subscribe the "dispose" event.
- *
- * @fires Plugin#dispose
- */
-
-
- Plugin.prototype.dispose = function dispose() {
- var name = this.name,
- player = this.player;
-
- /**
- * Signals that a advanced plugin is about to be disposed.
- *
- * @event Plugin#dispose
- * @type {EventTarget~Event}
- */
-
- this.trigger('dispose');
- this.off();
- player.off('dispose', this.dispose);
-
- // Eliminate any possible sources of leaking memory by clearing up
- // references between the player and the plugin instance and nulling out
- // the plugin's state and replacing methods with a function that throws.
- player[PLUGIN_CACHE_KEY][name] = false;
- this.player = this.state = null;
-
- // Finally, replace the plugin name on the player with a new factory
- // function, so that the plugin is ready to be set up again.
- player[name] = createPluginFactory(name, pluginStorage[name]);
- };
-
- /**
- * Determines if a plugin is a basic plugin (i.e. not a sub-class of `Plugin`).
- *
- * @param {string|Function} plugin
- * If a string, matches the name of a plugin. If a function, will be
- * tested directly.
- *
- * @returns {boolean}
- * Whether or not a plugin is a basic plugin.
- */
-
-
- Plugin.isBasic = function isBasic(plugin) {
- var p = typeof plugin === 'string' ? getPlugin(plugin) : plugin;
-
- return typeof p === 'function' && !Plugin.prototype.isPrototypeOf(p.prototype);
- };
-
- /**
- * Register a Video.js plugin.
- *
- * @param {string} name
- * The name of the plugin to be registered. Must be a string and
- * must not match an existing plugin or a method on the `Player`
- * prototype.
- *
- * @param {Function} plugin
- * A sub-class of `Plugin` or a function for basic plugins.
- *
- * @returns {Function}
- * For advanced plugins, a factory function for that plugin. For
- * basic plugins, a wrapper function that initializes the plugin.
- */
-
-
- Plugin.registerPlugin = function registerPlugin(name, plugin) {
- if (typeof name !== 'string') {
- throw new Error('Illegal plugin name, "' + name + '", must be a string, was ' + (typeof name === 'undefined' ? 'undefined' : _typeof(name)) + '.');
- }
-
- if (pluginExists(name)) {
- log$1.warn('A plugin named "' + name + '" already exists. You may want to avoid re-registering plugins!');
- } else if (Player.prototype.hasOwnProperty(name)) {
- throw new Error('Illegal plugin name, "' + name + '", cannot share a name with an existing player method!');
- }
-
- if (typeof plugin !== 'function') {
- throw new Error('Illegal plugin for "' + name + '", must be a function, was ' + (typeof plugin === 'undefined' ? 'undefined' : _typeof(plugin)) + '.');
- }
-
- pluginStorage[name] = plugin;
-
- // Add a player prototype method for all sub-classed plugins (but not for
- // the base Plugin class).
- if (name !== BASE_PLUGIN_NAME) {
- if (Plugin.isBasic(plugin)) {
- Player.prototype[name] = createBasicPlugin(name, plugin);
- } else {
- Player.prototype[name] = createPluginFactory(name, plugin);
- }
- }
-
- return plugin;
- };
-
- /**
- * De-register a Video.js plugin.
- *
- * @param {string} name
- * The name of the plugin to be deregistered.
- */
-
-
- Plugin.deregisterPlugin = function deregisterPlugin(name) {
- if (name === BASE_PLUGIN_NAME) {
- throw new Error('Cannot de-register base plugin.');
- }
- if (pluginExists(name)) {
- delete pluginStorage[name];
- delete Player.prototype[name];
- }
- };
-
- /**
- * Gets an object containing multiple Video.js plugins.
- *
- * @param {Array} [names]
- * If provided, should be an array of plugin names. Defaults to _all_
- * plugin names.
- *
- * @returns {Object|undefined}
- * An object containing plugin(s) associated with their name(s) or
- * `undefined` if no matching plugins exist).
- */
-
-
- Plugin.getPlugins = function getPlugins() {
- var names = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Object.keys(pluginStorage);
-
- var result = void 0;
-
- names.forEach(function (name) {
- var plugin = getPlugin(name);
-
- if (plugin) {
- result = result || {};
- result[name] = plugin;
- }
- });
-
- return result;
- };
-
- /**
- * Gets a plugin's version, if available
- *
- * @param {string} name
- * The name of a plugin.
- *
- * @returns {string}
- * The plugin's version or an empty string.
- */
-
-
- Plugin.getPluginVersion = function getPluginVersion(name) {
- var plugin = getPlugin(name);
-
- return plugin && plugin.VERSION || '';
- };
-
- return Plugin;
- }();
-
- /**
- * Gets a plugin by name if it exists.
- *
- * @static
- * @method getPlugin
- * @memberOf Plugin
- * @param {string} name
- * The name of a plugin.
- *
- * @returns {Function|undefined}
- * The plugin (or `undefined`).
- */
-
-
- Plugin.getPlugin = getPlugin;
-
- /**
- * The name of the base plugin class as it is registered.
- *
- * @type {string}
- */
- Plugin.BASE_PLUGIN_NAME = BASE_PLUGIN_NAME;
-
- Plugin.registerPlugin(BASE_PLUGIN_NAME, Plugin);
-
- /**
- * Documented in player.js
- *
- * @ignore
- */
- Player.prototype.usingPlugin = function (name) {
- return !!this[PLUGIN_CACHE_KEY] && this[PLUGIN_CACHE_KEY][name] === true;
- };
-
- /**
- * Documented in player.js
- *
- * @ignore
- */
- Player.prototype.hasPlugin = function (name) {
- return !!pluginExists(name);
- };
-
- /**
- * Signals that a plugin is about to be set up on a player.
- *
- * @event Player#beforepluginsetup
- * @type {Plugin~PluginEventHash}
- */
-
- /**
- * Signals that a plugin is about to be set up on a player - by name. The name
- * is the name of the plugin.
- *
- * @event Player#beforepluginsetup:$name
- * @type {Plugin~PluginEventHash}
- */
-
- /**
- * Signals that a plugin has just been set up on a player.
- *
- * @event Player#pluginsetup
- * @type {Plugin~PluginEventHash}
- */
-
- /**
- * Signals that a plugin has just been set up on a player - by name. The name
- * is the name of the plugin.
- *
- * @event Player#pluginsetup:$name
- * @type {Plugin~PluginEventHash}
- */
-
- /**
- * @typedef {Object} Plugin~PluginEventHash
- *
- * @property {string} instance
- * For basic plugins, the return value of the plugin function. For
- * advanced plugins, the plugin instance on which the event is fired.
- *
- * @property {string} name
- * The name of the plugin.
- *
- * @property {string} plugin
- * For basic plugins, the plugin function. For advanced plugins, the
- * plugin class/constructor.
- */
-
- /**
- * @file extend.js
- * @module extend
- */
-
- /**
- * 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.
- *
- * @param {Object} subClass
- * The class to inherit to
- *
- * @param {Object} superClass
- * The class to inherit from
- *
- * @private
- */
- 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 === 'undefined' ? 'undefined' : _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
- *
- * @static
- * @const
- *
- * @param {Object} superClass
- * The class to inherit from
- *
- * @param {Object} [subClassMethods={}]
- * The class to inherit to
- *
- * @return {Object}
- * The new object with subClassMethods that inherited superClass.
- */
- 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 === 'undefined' ? 'undefined' : _typeof(subClassMethods)) === 'object') {
- 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;
- };
-
- /**
- * @file video.js
- * @module videojs
- */
-// Include the built-in techs
-// HTML5 Element Shim for IE8
- if (typeof HTMLVideoElement === 'undefined' && isReal()) {
- document_1.createElement('video');
- document_1.createElement('audio');
- document_1.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.
- *
- * @param {string|Element} id
- * Video element or video element ID
- *
- * @param {Object} [options]
- * Optional options object for config/settings
- *
- * @param {Component~ReadyCallback} [ready]
- * Optional ready callback
- *
- * @return {Player}
- * A player instance
- */
- function videojs(id, options, ready) {
- var tag = void 0;
-
- // Allow for element or ID to be passed in
- // String ID
- if (typeof id === 'string') {
- var players = videojs.getPlayers();
-
- // 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 (players[id]) {
-
- // If options or ready function are passed, warn
- if (options) {
- log$1.warn('Player "' + id + '" is already initialised. Options will not be applied.');
- }
-
- if (ready) {
- players[id].ready(ready);
- }
-
- return players[id];
- }
-
- // Otherwise get element for ID
- tag = $('#' + id);
-
- // ID is a media element
- } else {
- tag = id;
- }
-
- // Check for a useable element
- // re: nodeName, could be a box div also
- if (!tag || !tag.nodeName) {
- throw new TypeError('The element or ID supplied is not valid. (videojs)');
- }
-
- // Check if element is included in the DOM
- if (isEl(tag) && !document_1.body.contains(tag)) {
- log$1.warn('The element supplied is not included in the DOM');
- }
-
- // Element may have a player attr referring to an already created player instance.
- // If so return that otherwise set up a new player below
- if (tag.player || Player.players[tag.playerId]) {
- return tag.player || Player.players[tag.playerId];
- }
-
- options = options || {};
-
- videojs.hooks('beforesetup').forEach(function (hookFunction) {
- var opts = hookFunction(tag, mergeOptions(options));
-
- if (!isObject(opts) || Array.isArray(opts)) {
- log$1.error('please return an object in beforesetup hooks');
- return;
- }
-
- options = mergeOptions(options, opts);
- });
-
- var PlayerComponent = Component.getComponent('Player');
- // If not, set up a new player
- var player = new PlayerComponent(tag, options, ready);
-
- videojs.hooks('setup').forEach(function (hookFunction) {
- return hookFunction(player);
- });
-
- return player;
- }
-
- /**
- * An Object that contains lifecycle hooks as keys which point to an array
- * of functions that are run when a lifecycle is triggered
- */
- videojs.hooks_ = {};
-
- /**
- * Get a list of hooks for a specific lifecycle
- * @function videojs.hooks
- *
- * @param {string} type
- * the lifecyle to get hooks from
- *
- * @param {Function|Function[]} [fn]
- * Optionally add a hook (or hooks) to the lifecycle that your are getting.
- *
- * @return {Array}
- * an array of hooks, or an empty array if there are none.
- */
- videojs.hooks = function (type, fn) {
- videojs.hooks_[type] = videojs.hooks_[type] || [];
- if (fn) {
- videojs.hooks_[type] = videojs.hooks_[type].concat(fn);
- }
- return videojs.hooks_[type];
- };
-
- /**
- * Add a function hook to a specific videojs lifecycle.
- *
- * @param {string} type
- * the lifecycle to hook the function to.
- *
- * @param {Function|Function[]}
- * The function or array of functions to attach.
- */
- videojs.hook = function (type, fn) {
- videojs.hooks(type, fn);
- };
-
- /**
- * Add a function hook that will only run once to a specific videojs lifecycle.
- *
- * @param {string} type
- * the lifecycle to hook the function to.
- *
- * @param {Function|Function[]}
- * The function or array of functions to attach.
- */
- videojs.hookOnce = function (type, fn) {
- videojs.hooks(type, [].concat(fn).map(function (original) {
- var wrapper = function wrapper() {
- videojs.removeHook(type, wrapper);
- original.apply(undefined, arguments);
- };
-
- return wrapper;
- }));
- };
-
- /**
- * Remove a hook from a specific videojs lifecycle.
- *
- * @param {string} type
- * the lifecycle that the function hooked to
- *
- * @param {Function} fn
- * The hooked function to remove
- *
- * @return {boolean}
- * The function that was removed or undef
- */
- videojs.removeHook = function (type, fn) {
- var index$$1 = videojs.hooks(type).indexOf(fn);
-
- if (index$$1 <= -1) {
- return false;
- }
-
- videojs.hooks_[type] = videojs.hooks_[type].slice();
- videojs.hooks_[type].splice(index$$1, 1);
-
- return true;
- };
-
-// Add default styles
- if (window_1.VIDEOJS_NO_DYNAMIC_STYLE !== true && isReal()) {
- var style = $('.vjs-styles-defaults');
-
- if (!style) {
- style = createStyleElement('vjs-styles-defaults');
- var head = $('head');
-
- if (head) {
- head.insertBefore(style, head.firstChild);
- }
- 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)
- autoSetupTimeout(1, videojs);
-
- /**
- * Current software version. Follows semver.
- *
- * @type {string}
- */
- videojs.VERSION = version;
-
- /**
- * The global options object. These are the settings that take effect
- * if no overrides are specified when the player is created.
- *
- * @type {Object}
- */
- videojs.options = Player.prototype.options_;
-
- /**
- * Get an object with the currently created players, keyed by player ID
- *
- * @return {Object}
- * The created players
- */
- videojs.getPlayers = function () {
- return Player.players;
- };
-
- /**
- * Expose players object.
- *
- * @memberOf videojs
- * @property {Object} players
- */
- videojs.players = Player.players;
-
- /**
- * Get a component class object by name
- *
- * @borrows Component.getComponent as videojs.getComponent
- */
- videojs.getComponent = Component.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'] }`.
- *
- * > NOTE: You could also just initialize the component before adding.
- * `component.addChild(new MyComponent());`
- *
- * @param {string} name
- * The class name of the component
- *
- * @param {Component} comp
- * The component class
- *
- * @return {Component}
- * The newly registered component
- */
- videojs.registerComponent = function (name$$1, comp) {
- if (Tech.isTech(comp)) {
- log$1.warn('The ' + name$$1 + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)');
- }
-
- Component.registerComponent.call(Component, name$$1, comp);
- };
-
- /**
- * Get a Tech class object by name
- *
- * @borrows Tech.getTech as videojs.getTech
- */
- videojs.getTech = Tech.getTech;
-
- /**
- * Register a Tech so it can referred to by name.
- * This is used in the tech order for the player.
- *
- * @borrows Tech.registerTech as videojs.registerTech
- */
- videojs.registerTech = Tech.registerTech;
-
- videojs.use = use;
-
- /**
- * A suite of browser and device tests from {@link browser}.
- *
- * @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 since version 5.0
- * @type {boolean}
- */
- videojs.TOUCH_ENABLED = TOUCH_ENABLED;
-
- /**
- * Subclass an existing class
- * Mimics ES6 subclassing with the `extend` keyword
- *
- * @borrows extend:extendFn as videojs.extend
- */
- videojs.extend = extendFn;
-
- /**
- * 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.
- *
- * @borrows merge-options:mergeOptions as videojs.mergeOptions
- */
- videojs.mergeOptions = mergeOptions;
-
- /**
- * Change the context (this) of a function
- *
- * > NOTE: as of v5.0 we require an ES5 shim, so you should use the native
- * `function() {}.bind(newContext);` instead of this.
- *
- * @borrows fn:bind as videojs.bind
- */
- videojs.bind = bind;
-
- /**
- * Register a Video.js plugin.
- *
- * @borrows plugin:registerPlugin as videojs.registerPlugin
- * @method registerPlugin
- *
- * @param {string} name
- * The name of the plugin to be registered. Must be a string and
- * must not match an existing plugin or a method on the `Player`
- * prototype.
- *
- * @param {Function} plugin
- * A sub-class of `Plugin` or a function for basic plugins.
- *
- * @return {Function}
- * For advanced plugins, a factory function for that plugin. For
- * basic plugins, a wrapper function that initializes the plugin.
- */
- videojs.registerPlugin = Plugin.registerPlugin;
-
- /**
- * Deprecated method to register a plugin with Video.js
- *
- * @deprecated
- * videojs.plugin() is deprecated; use videojs.registerPlugin() instead
- *
- * @param {string} name
- * The plugin name
- *
- * @param {Plugin|Function} plugin
- * The plugin sub-class or function
- */
- videojs.plugin = function (name$$1, plugin) {
- log$1.warn('videojs.plugin() is deprecated; use videojs.registerPlugin() instead');
- return Plugin.registerPlugin(name$$1, plugin);
- };
-
- /**
- * Gets an object containing multiple Video.js plugins.
- *
- * @param {Array} [names]
- * If provided, should be an array of plugin names. Defaults to _all_
- * plugin names.
- *
- * @return {Object|undefined}
- * An object containing plugin(s) associated with their name(s) or
- * `undefined` if no matching plugins exist).
- */
- videojs.getPlugins = Plugin.getPlugins;
-
- /**
- * Gets a plugin by name if it exists.
- *
- * @param {string} name
- * The name of a plugin.
- *
- * @return {Function|undefined}
- * The plugin (or `undefined`).
- */
- videojs.getPlugin = Plugin.getPlugin;
-
- /**
- * Gets a plugin's version, if available
- *
- * @param {string} name
- * The name of a plugin.
- *
- * @return {string}
- * The plugin's version or an empty string.
- */
- videojs.getPluginVersion = Plugin.getPluginVersion;
-
- /**
- * Adding languages so that they're available to all players.
- * Example: `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
- */
- videojs.addLanguage = function (code, data) {
- var _mergeOptions;
-
- code = ('' + code).toLowerCase();
-
- videojs.options.languages = mergeOptions(videojs.options.languages, (_mergeOptions = {}, _mergeOptions[code] = data, _mergeOptions));
-
- return videojs.options.languages[code];
- };
-
- /**
- * Log messages
- *
- * @borrows log:log as videojs.log
- */
- videojs.log = log$1;
-
- /**
- * Creates an emulated TimeRange object.
- *
- * @borrows time-ranges:createTimeRanges as videojs.createTimeRange
- */
- /**
- * @borrows time-ranges:createTimeRanges as videojs.createTimeRanges
- */
- videojs.createTimeRange = videojs.createTimeRanges = 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
- *
- * @borrows format-time:formatTime as videojs.formatTime
- */
- videojs.formatTime = formatTime;
-
- /**
- * Resolve and parse the elements of a URL
- *
- * @borrows url:parseUrl as videojs.parseUrl
- */
- videojs.parseUrl = parseUrl;
-
- /**
- * Returns whether the url passed is a cross domain request or not.
- *
- * @borrows url:isCrossOrigin as videojs.isCrossOrigin
- */
- videojs.isCrossOrigin = isCrossOrigin;
-
- /**
- * Event target class.
- *
- * @borrows EventTarget as videojs.EventTarget
- */
- videojs.EventTarget = EventTarget;
-
- /**
- * 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.
- *
- * @borrows events:on as videojs.on
- */
- videojs.on = on;
-
- /**
- * Trigger a listener only once for an event
- *
- * @borrows events:one as videojs.one
- */
- videojs.one = one;
-
- /**
- * Removes event listeners from an element
- *
- * @borrows events:off as videojs.off
- */
- videojs.off = off;
-
- /**
- * Trigger an event for an element
- *
- * @borrows events:trigger as videojs.trigger
- */
- videojs.trigger = trigger;
-
- /**
- * A cross-browser XMLHttpRequest wrapper. Here's a simple example:
- *
- * @param {Object} options
- * settings for the request.
- *
- * @return {XMLHttpRequest|XDomainRequest}
- * The request object.
- *
- * @see https://github.com/Raynos/xhr
- */
- videojs.xhr = index;
-
- /**
- * TextTrack class
- *
- * @borrows TextTrack as videojs.TextTrack
- */
- videojs.TextTrack = TextTrack;
-
- /**
- * export the AudioTrack class so that source handlers can create
- * AudioTracks and then add them to the players AudioTrackList
- *
- * @borrows AudioTrack as videojs.AudioTrack
- */
- videojs.AudioTrack = AudioTrack;
-
- /**
- * export the VideoTrack class so that source handlers can create
- * VideoTracks and then add them to the players VideoTrackList
- *
- * @borrows VideoTrack as videojs.VideoTrack
- */
- videojs.VideoTrack = VideoTrack;
-
- /**
- * Determines, via duck typing, whether or not a value is a DOM element.
- *
- * @borrows dom:isEl as videojs.isEl
- * @deprecated Use videojs.dom.isEl() instead
- */
-
- /**
- * Determines, via duck typing, whether or not a value is a text node.
- *
- * @borrows dom:isTextNode as videojs.isTextNode
- * @deprecated Use videojs.dom.isTextNode() instead
- */
-
- /**
- * Creates an element and applies properties.
- *
- * @borrows dom:createEl as videojs.createEl
- * @deprecated Use videojs.dom.createEl() instead
- */
-
- /**
- * Check if an element has a CSS class
- *
- * @borrows dom:hasElClass as videojs.hasClass
- * @deprecated Use videojs.dom.hasClass() instead
- */
-
- /**
- * Add a CSS class name to an element
- *
- * @borrows dom:addElClass as videojs.addClass
- * @deprecated Use videojs.dom.addClass() instead
- */
-
- /**
- * Remove a CSS class name from an element
- *
- * @borrows dom:removeElClass as videojs.removeClass
- * @deprecated Use videojs.dom.removeClass() instead
- */
-
- /**
- * Adds or removes a CSS class name on an element depending on an optional
- * condition or the presence/absence of the class name.
- *
- * @borrows dom:toggleElClass as videojs.toggleClass
- * @deprecated Use videojs.dom.toggleClass() instead
- */
-
- /**
- * Apply attributes to an HTML element.
- *
- * @borrows dom:setElAttributes as videojs.setAttribute
- * @deprecated Use videojs.dom.setAttributes() instead
- */
-
- /**
- * 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.
- *
- * @borrows dom:getElAttributes as videojs.getAttributes
- * @deprecated Use videojs.dom.getAttributes() instead
- */
-
- /**
- * Empties the contents of an element.
- *
- * @borrows dom:emptyEl as videojs.emptyEl
- * @deprecated Use videojs.dom.emptyEl() instead
- */
-
- /**
- * 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.
- *
- * @borrows dom:appendContents as videojs.appendContet
- * @deprecated Use videojs.dom.appendContent() instead
- */
-
- /**
- * 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.
- *
- * @borrows dom:insertContent as videojs.insertContent
- * @deprecated Use videojs.dom.insertContent() instead
- */
- ['isEl', 'isTextNode', 'createEl', 'hasClass', 'addClass', 'removeClass', 'toggleClass', 'setAttributes', 'getAttributes', 'emptyEl', 'appendContent', 'insertContent'].forEach(function (k) {
- videojs[k] = function () {
- log$1.warn('videojs.' + k + '() is deprecated; use videojs.dom.' + k + '() instead');
- return Dom[k].apply(null, arguments);
- };
- });
-
- /**
- * A safe getComputedStyle with an IE8 fallback.
- *
- * This is because in Firefox, if the player is loaded in an iframe with `display:none`,
- * then `getComputedStyle` returns `null`, so, we do a null-check to make sure
- * that the player doesn't break in these cases.
- * See https://bugzilla.mozilla.org/show_bug.cgi?id=548397 for more details.
- *
- * @borrows computed-style:computedStyle as videojs.computedStyle
- */
- videojs.computedStyle = computedStyle;
-
- /**
- * Export the Dom utilities for use in external plugins
- * and Tech's
- */
- videojs.dom = Dom;
-
- /**
- * Export the Url utilities for use in external plugins
- * and Tech's
- */
- videojs.url = Url;
-
- return videojs;
-
-})));
-
-!function () {
- !function (a) {
- var b = a && a.videojs;
- b && (b.CDN_VERSION = "6.4.0")
- }(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)
-}();
\ No newline at end of file
+++ /dev/null
-/* Video JS core styles */
-
-.video-js .vjs-big-play-button .vjs-icon-placeholder:before, .vjs-button > .vjs-icon-placeholder:before, .video-js .vjs-modal-dialog, .vjs-modal-dialog .vjs-modal-dialog-content {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%; }
-
-.video-js .vjs-big-play-button .vjs-icon-placeholder:before, .vjs-button > .vjs-icon-placeholder:before {
- text-align: center; }
-
-/* Removed because we don't need support of oldest IE versions */
-/*@font-face {
- font-family: VideoJS;
- src: url("font/VideoJS.eot?#iefix") format("eot"); }*/
-
-@font-face {
- font-family: VideoJS;
- src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAA54AAoAAAAAFmgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAAA9AAAAD4AAABWUZFeBWNtYXAAAAE0AAAAOgAAAUriMBC2Z2x5ZgAAAXAAAAouAAAPUFvx6AdoZWFkAAALoAAAACsAAAA2DIPpX2hoZWEAAAvMAAAAGAAAACQOogcgaG10eAAAC+QAAAAPAAAAfNkAAABsb2NhAAAL9AAAAEAAAABAMMg06m1heHAAAAw0AAAAHwAAACABMAB5bmFtZQAADFQAAAElAAACCtXH9aBwb3N0AAANfAAAAPwAAAGBZkSN43icY2BkZ2CcwMDKwMFSyPKMgYHhF4RmjmEIZzzHwMDEwMrMgBUEpLmmMDh8ZPwoxw7iLmSHCDOCCADvEAo+AAB4nGNgYGBmgGAZBkYGEHAB8hjBfBYGDSDNBqQZGZgYGD7K/f8PUvCREUTzM0DVAwEjG8OIBwCPdwbVAAB4nI1Xe1CU1xX/zv1eLItLln0JwrIfC7sJGET2hRJ2N1GUoBJE8AESQEEhmBHjaB7UuBMTO4GMaSu7aY3RNlOdRPNqO2pqRmuTaSZtR6JJILUZk00a/4imjpmiecB303O/XUgMJOPufvd+99xzzz33nN855y4HHH7EfrGfIxwHRiANvF/sH71I9BzHszmpW+rGOQOXxXE6YhI4PoMT8zkT4cDFuf1cwMrZJI5cglM0HKVv0MaUFDgIFfg9mJJCG+kbKn1JkqBOVaFOkuhLpARq8fu0Nnc9/zdvfY9PxXW4PdH0C6N+PCejhorxFjAqRjgFRXSINEARbBGsoxcFK7IJmr4OycFJnInL59zIXwxui80fkGRbEHyosMWaATJKUfCskmwJQsAWANkmnIGOhlf514h7U8HNIv3owoHB0WMt0Eb3sx0guLi5pq/8Ny1q6969fKR9X9GBV6dPv6dp04K99SOwtmyPl47ApRa6n4ZpP1yjr5fn7MmYP/vXLUJs715UguklHBaHOZHZmG1N9FAIW2mf0MqWCIdo/8RZ1yGfxKUldDcGIbFA7ICO+vqOMSPTh/ZrSqgHi/bB/O8E8Mnzp+M+acxfpsTShBwej26TiGxBn7m4eEIO+Rueu6Hj+IFBnh88cAEUEQ//nVLx5C7kf+yIR47QEe+eMlhz9SqsGbe3hh2R03NGzoY6O42Kz8l7fB6fAk6LYnTyFo/FYyT6GGyNx2Jx2sdH4rA1Fo/HyCXaFyOp8dhYBCfJb2NIn1ImE6CYNGmgSTb52DawJR6jfXEmDU4xyTEmpgHHOIStoxfjSGdkbsK2w2jbdMQG4sgAstEONgURYCwGHhEhhscioQaAhhCf7McifEQc0l6+mxj9nI+gmSdiQ0Zbm7gZnIO7GSMEXG6UDAVocxAV8GcEXCKg1a02RcTtwANWRGIAyElor6n/+ZU2yOB3+T77Hb1MLqhn4KHVnQBjJnqe9QZSon6Kc5DxAD2vMdPL/BXSmQGwspa67z9wLUjdi9TN7QC7lyyBr9rpt7uXVC1CMpyjKRoXnGPHTuiaPLsNdc2dbAFQLAooPkXEh33FodHl4XpC6sPCIa0ftUIhHSYXVSu5iME+DIXsbZJ51BeidCgajcai43jU9nVzoSn2dPqcFvSoxSzJzgRKAx47WMRxOrIj3Wf0+hndxhJTiOkSEqxar3b3RKM9hY64oxBA64ieURLvCfpkDb8siBdUJ1bgT+urJ5PGfewQrmm5R5+0HmfyIPySD7OYkT0WxRePah8oEiyjlxIP74thVoRTURpmL6QhGuWS+QDjdANXjIM8SQa/1w128ODx0Qp4aLMNg9+JL3joUn8AMxW+aLNiuKjarn4uyyTdXjOzZTsh21uwldUvJoYza+zELALfu3p1L8/3krtyZ0Ag058J3hxHghvbGZn0dHZy6Mim/7Blre4lpHd1c28yVqRViO153F2oIWoXCIKbL4Z0cM1iaQn9mI5KuV2SzEvWXJDMNtkANpMdQoDDhIdD4A/YrP6Aye9ysxyE+uOEAcTDorgvVZJjcua043PnZ/PmdDqcbibZlXOOT8uSo7Kof0YUn9GL+Jo17ficymxiTofC6znUso0DhAxs1Fo+kF+d36vLmgZ8mk5cdGv2mwYj5k3Dm9m3LhJ1aVRNm6HrTbLgYAoWXDhDd/u4PGy5CT+xGMdiaBovewUCF/1BiWNljI9MLn7jeScpg+WyH6mfU62eVDql7hsrmvx1ezp/YldE2LhjbkiDnAn8tGy/MW3IXRMYJduvq9HpmIcKuFt+JCtgdGEGKAcF6UacVwIYbVPGfw/+YuNBS4cx/CUHcnyfc+wRDMtTr72mMSBjT/yn/GKSdeDWQUCH6Xoqq5R10RE60gV6erUL0iCti16d0hZjxut4QI/rEpgSh6WjnJXdBXRg1GKCucGJPtFqM27aD1tOqqKonsQ2KsFSSmEpmvRlsR+TcD9OFwrqXxIclL4sJTnGMSuG8KpkZvKdeVIOKDyWSyPLV16/p1QMPbP8NihwUzr47bdnXtwtjdCvqqpO0H+pOvIl3Pzv46e5CT/tQjklXCXXym1AaWY7bzHLkuDMc7ldKCvgxzLn8wYkJLBhEDyK7MT8bTbwbkxbfp+3mKAGsmTBpabSIEECzMIcQlzOPAMKsxMs7uhsnxPLuofPDTc1hkuq6MX9j16YU7CqegcYHbmWYuvAP6tCS97tgWf7dlQvnl25YPavXLVZvrzQPeHCpZmzzEUVq/xzu5sChnSTPTW7oOYmh69z4zL/gk3b+O6hoa733uviP82vnFcbqWlc9tDmZa23LVzaV1yXURi+JX+28NeBuj3+O8IrQ080Vm1eWB4OKjPmrJu7c1udWynvKF6/vs479lSW9+5gZkn+dKfellNGDPllzeULustz+A0bPvhgw7lkvEUwn/N4Ty7U7nhGsEpFkOfy+kutbOh1JQxhVDJumoW11hnkPThznh6FFlhfT+ra1x9sF56kx5YuDzVY9PQYAYA7iblw4frQ4TPCk2MK/xGU3rlmze62trHz6lsko+v+So/do74PT8KVkpJfOErKcv8znrMGsHTNxoEkWy1mYgDB6XBbPaWsuiS6CryGaL6zCjaXBgvtkuyXBua1wOKnh+k7L9AvPnYWffxK18FcJbuosGf3/Jo7amY+CE1vppzY+UTrva0FXc1i55pKQ/YjVL187N5fCn1kW5uot/1hi+DiZ+5atnJR9E+prvydJ9ZZ5mwOpU5gM4KYysMBQ71UzPuMTl9QQOyUo5nwioeYCPjFklrbK6s6X+ypUZ6rum9+CZYzWRiBJfSP0xzzSmrg7f86g0DKVj/wwFzieD9rRfPGFbeKMl05pn5j9/rsQJJ2iEgRrpohlyBo3f4QK7Kl+EcAYZgAoNVmZWXK704YAa3FwBxgSGUOs5htvGRz4Sgj3yFkSJFBuv/sxu5yk998T8WDJzvv/2RX19HtTUW1S+wpKRKRjJ6zzz/1/OPdFdWGlAKbvzS4PHOtURikg9AGz0LbIB85S/cPOpoXvuue8/iV2H1vPTy3ddvOeZ37HGmO3OmSzVzR+NS53+84dHlFhXPLqtzSO+5ruHM2vXtBdxP87LOzKAD359j/INYIbyPabIi3Cq6Wa+SaGe78diIzu7qcblcAa6/fJRvNopXFJnO+U9KKM5bqH5LM0iQSVmpPCPDu7ZT4Aoubz3709EBTyrTDjyx8MQXgUH1nqm7TWng4TzE4i4AsKskBITXfSyC4Fkl5MxnJDiKSIDSJAsGvd1y+/eNDp2e+A+5d8HeiiunrTkT6TqWLIs+/QRoWr98s0qj8uuzLuS22Ytufg3rdTaHn1m46sfgGKHXt0MGnLaRHdnwN37tvHcWKo2V6lnPxL4UvUQcRdOzmZSQs8X5CH5OxXMXpkATuDz8Et0SH4uyCRR+TjmBDP1GvsVrWEGVzEj33YVQ9jAtIKpqsl/s/0xrocwAAeJxjYGRgYADig3cEzsTz23xl4GZnAIHLRucNkWl2BrA4BwMTiAIAF4IITwB4nGNgZGBgZwCChWASxGZkQAXyABOUANh4nGNnYGBgHyAMADa8ANoAAAAAAAAOAFAAZgCyAMYA5gEeAUgBdAGcAfICLgKOAroDCgOOA7AD6gQ4BHwEuAToBQwFogXoBjYGbAbaB3IHqHicY2BkYGCQZ8hlYGcAASYg5gJCBob/YD4DABbVAaoAeJxdkE1qg0AYhl8Tk9AIoVDaVSmzahcF87PMARLIMoFAl0ZHY1BHdBJIT9AT9AQ9RQ9Qeqy+yteNMzDzfM+88w0K4BY/cNAMB6N2bUaPPBLukybCLvleeAAPj8JD+hfhMV7hC3u4wxs7OO4NzQSZcI/8Ltwnfwi75E/hAR7wJTyk/xYeY49fYQ/PztM+jbTZ7LY6OWdBJdX/pqs6NYWa+zMxa13oKrA6Uoerqi/JwtpYxZXJ1coUVmeZUWVlTjq0/tHacjmdxuL90OR8O0UEDYMNdtiSEpz5XQGqzlm30kzUdAYFFOb8R7NOZk0q2lwAyz1i7oAr1xoXvrOgtYhZx8wY5KRV269JZ5yGpmzPTjQhvY9je6vEElPOuJP3mWKnP5M3V+YAAAB4nG2P2XLCMAxFfYFspGUp3Te+IB9lHJF4cOzUS2n/voaEGR6qB+lKo+WITdhga/a/bRnDBFPMkCBFhhwF5ihxg1sssMQKa9xhg3s84BFPeMYLXvGGd3zgE9tZr/hveXKVkFYoSnoeHJXfRoWOqi54mo9ameNFdrK+dLSyaVf7oJQTlkhXpD3Z5XXhR/rUfQVuKXO91Jps4cLOS6/I5YL3XhodRRsVWZe4NnZOhWnSAWgxhMoEr6SmzZieF43Mk7ZOBdeCVGrp9Eu+54J2xhySplfB5XHwQLXUmT9KH6+kPnQ7ZYuIEzNyfs1DLU1VU4SWZ6LkXGHsD1ZKbMw=) format("woff"), url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAAKAIAAAwAgT1MvMlGRXgUAAAEoAAAAVmNtYXDiMBC2AAAB/AAAAUpnbHlmW/HoBwAAA4gAAA9QaGVhZAyD6V8AAADQAAAANmhoZWEOogcgAAAArAAAACRobXR42QAAAAAAAYAAAAB8bG9jYTDINOoAAANIAAAAQG1heHABMAB5AAABCAAAACBuYW1l1cf1oAAAEtgAAAIKcG9zdGZEjeMAABTkAAABgQABAAAHAAAAAKEHAAAAAAAHAAABAAAAAAAAAAAAAAAAAAAAHwABAAAAAQAAwdxheF8PPPUACwcAAAAAANMyzzEAAAAA0zLPMQAAAAAHAAcAAAAACAACAAAAAAAAAAEAAAAfAG0ABwAAAAAAAgAAAAoACgAAAP8AAAAAAAAAAQcAAZAABQAIBHEE5gAAAPoEcQTmAAADXABXAc4AAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA8QHxHgcAAAAAoQcAAAAAAAABAAAAAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAAAAAMAAAADAAAAHAABAAAAAABEAAMAAQAAABwABAAoAAAABgAEAAEAAgAA8R7//wAAAADxAf//AAAPAAABAAAAAAAAAAABBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAFAAZgCyAMYA5gEeAUgBdAGcAfICLgKOAroDCgOOA7AD6gQ4BHwEuAToBQwFogXoBjYGbAbaB3IHqAABAAAAAAWLBYsAAgAAAREBAlUDNgWL++oCCwAAAwAAAAAGawZrAAIADgAaAAAJAhMEAAMSAAUkABMCAAEmACc2ADcWABcGAALrAcD+QJX+w/5aCAgBpgE9AT0BpggI/lr+w/3+rgYGAVL9/QFSBgb+rgIwAVABUAGbCP5a/sP+w/5aCAgBpgE9AT0BpvrIBgFS/f0BUgYG/q79/f6uAAAAAgAAAAAFQAWLAAMABwAAASERKQERIREBwAEr/tUCVQErAXUEFvvqBBYAAAAEAAAAAAYgBiAABgATACQAJwAAAS4BJxUXNjcGBxc+ATUmACcVFhIBBwEhESEBEQEGBxU+ATcXNwEHFwTQAWVVuAO7AidxJSgF/t/lpc77t18BYf6fASsBdQE+TF1OijuZX/1gnJwDgGSeK6W4GBhqW3FGnFT0AWM4mjT+9AHrX/6f/kD+iwH2/sI7HZoSRDGYXwSWnJwAAAEAAAAABKsF1gAFAAABESEBEQECCwEqAXb+igRg/kD+iwSq/osAAAACAAAAAAVmBdYABgAMAAABLgEnET4BAREhAREBBWUBZVRUZfwRASsBdf6LA4Bkniv9piueAUT+QP6LBKr+iwAAAwAAAAAGIAYPAAUADAAaAAATESEBEQEFLgEnET4BAxUWEhcGAgcVNgA3JgDgASsBdf6LAsUBZVVVZbqlzgMDzqXlASEFBf7fBGD+QP6LBKr+i+Bkniv9piueAvOaNP70tbX+9DSaOAFi9fUBYgAAAAQAAAAABYsFiwAFAAsAEQAXAAABIxEhNSMDMzUzNSEBIxUhESMDFTMVMxECC5YBduCWluD+igOA4AF2luDglgLr/oqWAgrglvyAlgF2AqCW4AF2AAQAAAAABYsFiwAFAAsAEQAXAAABMxUzESETIxUhESMBMzUzNSETNSMRITUBdeCW/org4AF2lgHAluD+ipaWAXYCVeABdgHAlgF2++rglgHA4P6KlgAAAAACAAAAAAXWBdYADwATAAABIQ4BBxEeARchPgE3ES4BAyERIQVA/IA/VQEBVT8DgD9VAQFVP/yAA4AF1QFVP/yAP1UBAVU/A4A/VfvsA4AAAAYAAAAABmsGawAHAAwAEwAbACAAKAAACQEmJw4BBwElLgEnAQUhATYSNyYFAQYCBxYXIQUeARcBMwEWFz4BNwECvgFkTlSH8GEBEgOONemh/u4C5f3QAXpcaAEB/BP+3VxoAQEOAjD95DXpoQESeP7dTlSH8GH+7gPwAmgSAQFYUP4nd6X2Pv4nS/1zZAEBk01NAfhk/v+TTUhLpfY+Adn+CBIBAVhQAdkAAAAFAAAAAAZrBdYADwATABcAGwAfAAABIQ4BBxEeARchPgE3ES4BASEVIQEhNSEFITUhNSE1IQXV+1ZAVAICVEAEqkBUAgJU+xYBKv7WAur9FgLqAcD+1gEq/RYC6gXVAVU//IA/VQEBVT8DgD9V/ayV/tWVlZWWlQADAAAAAAYgBdYADwAnAD8AAAEhDgEHER4BFyE+ATcRLgEBIzUjFTM1MxUUBgcjLgEnET4BNzMeARUFIzUjFTM1MxUOAQcjLgE1ETQ2NzMeARcFi/vqP1QCAlQ/BBY/VAICVP1rcJWVcCog4CAqAQEqIOAgKgILcJWVcAEqIOAgKiog4CAqAQXVAVU//IA/VQEBVT8DgD9V/fcl4CVKICoBASogASogKgEBKiBKJeAlSiAqAQEqIAEqICoBASogAAAGAAAAAAYgBPYAAwAHAAsADwATABcAABMzNSMRMzUjETM1IwEhNSERITUhERUhNeCVlZWVlZUBKwQV++sEFfvrBBUDNZb+QJUBwJX+QJb+QJUCVZWVAAAAAQAAAAAGIAZsAC4AAAEiBgcBNjQnAR4BMz4BNy4BJw4BBxQXAS4BIw4BBx4BFzI2NwEGBx4BFz4BNy4BBUArSh797AcHAg8eTixffwICf19ffwIH/fEeTixffwICf18sTh4CFAUBA3tcXHsDA3sCTx8bATcZNhkBNB0gAn9fX38CAn9fGxn+zRwgAn9fX38CIBz+yhcaXHsCAntcXXsAAAIAAAAABlkGawBDAE8AAAE2NCc3PgEnAy4BDwEmLwEuASchDgEPAQYHJyYGBwMGFh8BBhQXBw4BFxMeAT8BFh8BHgEXIT4BPwE2NxcWNjcTNiYnBS4BJz4BNx4BFw4BBasFBZ4KBgeWBxkNujpEHAMUD/7WDxQCHEU5ug0aB5UHBQudBQWdCwUHlQcaDbo5RRwCFA8BKg8UAhxFOboNGgeVBwUL/ThvlAIClG9vlAIClAM3JEokewkaDQEDDAkFSy0cxg4RAQERDsYcLUsFCQz+/QwbCXskSiR7CRoN/v0MCQVLLRzGDhEBAREOxhwtSwUJDAEDDBsJQQKUb2+UAgKUb2+UAAAAAAEAAAAABmsGawALAAATEgAFJAATAgAlBACVCAGmAT0BPQGmCAj+Wv7D/sP+WgOA/sP+WggIAaYBPQE9AaYICP5aAAAAAgAAAAAGawZrAAsAFwAAAQQAAxIABSQAEwIAASYAJzYANxYAFwYAA4D+w/5aCAgBpgE9AT0BpggI/lr+w/3+rgYGAVL9/QFSBgb+rgZrCP5a/sP+w/5aCAgBpgE9AT0BpvrIBgFS/f0BUgYG/q79/f6uAAADAAAAAAZrBmsACwAXACMAAAEEAAMSAAUkABMCAAEmACc2ADcWABcGAAMOAQcuASc+ATceAQOA/sP+WggIAaYBPQE9AaYICP5a/sP9/q4GBgFS/f0BUgYG/q4dAn9fX38CAn9fX38Gawj+Wv7D/sP+WggIAaYBPQE9Aab6yAYBUv39AVIGBv6u/f3+rgJPX38CAn9fX38CAn8AAAAEAAAAAAYgBiAADwAbACUAKQAAASEOAQcRHgEXIT4BNxEuAQEjNSMVIxEzFTM1OwEhHgEXEQ4BByE3MzUjBYv76j9UAgJUPwQWP1QCAlT9a3CVcHCVcJYBKiAqAQEqIP7WcJWVBiACVD/76j9UAgJUPwQWP1T8gpWVAcC7uwEqIP7WICoBcOAAAgAAAAAGawZrAAsAFwAAAQQAAxIABSQAEwIAEwcJAScJATcJARcBA4D+w/5aCAgBpgE9AT0BpggI/lo4af70/vRpAQv+9WkBDAEMaf71BmsI/lr+w/7D/loICAGmAT0BPQGm/BFpAQv+9WkBDAEMaf71AQtp/vQAAQAAAAAF1ga2ABYAAAERCQERHgEXDgEHLgEnIxYAFzYANyYAA4D+iwF1vv0FBf2+vv0FlQYBUf7+AVEGBv6vBYsBKv6L/osBKgT9v779BQX9vv7+rwYGAVH+/gFRAAAAAQAAAAAFPwcAABQAAAERIyIGHQEhAyMRIREjETM1NDYzMgU/nVY8ASUn/v7O///QrZMG9P74SEi9/tj9CQL3ASjaus0AAAAABAAAAAAGjgcAADAARQBgAGwAAAEUHgMVFAcGBCMiJicmNTQ2NzYlLgE1NDcGIyImNTQ2Nz4BMyEHIx4BFRQOAycyNjc2NTQuAiMiBgcGFRQeAxMyPgI1NC4BLwEmLwImIyIOAxUUHgIBMxUjFSM1IzUzNTMDH0BbWkAwSP7qn4TlOSVZSoMBESAfFS4WlMtIP03TcAGiioNKTDFFRjGSJlAaNSI/akAqURkvFCs9WTY6a1s3Dg8THgocJU4QIDVob1M2RnF9A2vV1WnU1GkD5CRFQ1CATlpTenNTYDxHUYouUhIqQCkkMQTBlFKaNkJAWD+MWkhzRztAPiEbOWY6hn1SJyE7ZS5nZ1I0/JcaNF4+GTAkGCMLFx04Ag4kOF07Rms7HQNsbNvbbNkAAwAAAAAGgAZsAAMADgAqAAABESERARYGKwEiJjQ2MhYBESERNCYjIgYHBhURIRIQLwEhFSM+AzMyFgHd/rYBXwFnVAJSZGemZASP/rdRVj9VFQv+twIBAQFJAhQqR2c/q9AEj/whA98BMkliYpNhYfzd/cgCEml3RTMeM/3XAY8B8DAwkCAwOB/jAAABAAAAAAaUBgAAMQAAAQYHFhUUAg4BBCMgJxYzMjcuAScWMzI3LgE9ARYXLgE1NDcWBBcmNTQ2MzIXNjcGBzYGlENfAUyb1v7SrP7x4SMr4bBpph8hHCsqcJNETkJOLHkBW8YIvYaMYG1gJWldBWhiRQ4cgv797rdtkQSKAn1hBQsXsXUEJgMsjlNYS5WzCiYkhr1mFTlzPwoAAAABAAAAAAWABwAAIgAAARcOAQcGLgM1ESM1PgQ3PgE7AREhFSERFB4CNzYFMFAXsFlorXBOIahIckQwFAUBBwT0AU3+sg0gQzBOAc/tIz4BAjhceHg6AiDXGlddb1ctBQf+WPz9+h40NR4BAgABAAAAAAaABoAASgAAARQCBCMiJzY/AR4BMzI+ATU0LgEjIg4DFRQWFxY/ATY3NicmNTQ2MzIWFRQGIyImNz4CNTQmIyIGFRQXAwYXJgI1NBIkIAQSBoDO/p/Rb2s7EzYUaj15vmh34o5ptn9bK1BNHggIBgIGETPRqZepiWs9Sg4IJRc2Mj5WGWMRBM7+zgFhAaIBYc4DgNH+n84gXUfTJzmJ8JZyyH46YH2GQ2ieIAwgHxgGFxQ9WpfZpIOq7lc9I3VZHzJCclVJMf5eRmtbAXzp0QFhzs7+nwAABwAAAAAHAATPAA4AFwAqAD0AUABaAF0AAAERNh4CBw4BBwYmIycmNxY2NzYmBxEUBRY2Nz4BNy4BJyMGHwEeARcOARcWNjc+ATcuAScjBh8BHgEXFAYXFjY3PgE3LgEnIwYfAR4BFw4BBTM/ARUzESMGAyUVJwMchM2UWwgNq4JHrQgBAapUaAoJcWMBfiIhDiMrAQJLMB0BBAokNAIBPmMiIQ4iLAECSzAeAQUKJDQBP2MiIQ4iLAECSzAeAQUKJDQBAT75g+5B4arNLNIBJ44ByQL9BQ9mvYCKwA8FBQMDwwJVTGdzBf6VB8IHNR08lld9uT4LCRA/qGNxvUwHNR08lld9uT4LCRA/qGNxvUwHNR08lld9uT4LCRA/qGNxvVJkAWUDDEf+tYP5AQAAAAEAAAAABiAGtgAbAAABBAADER4BFzMRITU2ADcWABcVIREzPgE3EQIAA4D+4v6FBwJ/X+D+1QYBJ97eAScG/tXgX38CB/6FBrUH/oX+4v32X38CAlWV3gEnBgb+2d6V/asCf18CCgEeAXsAAAAAEADGAAEAAAAAAAEABwAAAAEAAAAAAAIABwAHAAEAAAAAAAMABwAOAAEAAAAAAAQABwAVAAEAAAAAAAUACwAcAAEAAAAAAAYABwAnAAEAAAAAAAoAKwAuAAEAAAAAAAsAEwBZAAMAAQQJAAEADgBsAAMAAQQJAAIADgB6AAMAAQQJAAMADgCIAAMAAQQJAAQADgCWAAMAAQQJAAUAFgCkAAMAAQQJAAYADgC6AAMAAQQJAAoAVgDIAAMAAQQJAAsAJgEeVmlkZW9KU1JlZ3VsYXJWaWRlb0pTVmlkZW9KU1ZlcnNpb24gMS4wVmlkZW9KU0dlbmVyYXRlZCBieSBzdmcydHRmIGZyb20gRm9udGVsbG8gcHJvamVjdC5odHRwOi8vZm9udGVsbG8uY29tAFYAaQBkAGUAbwBKAFMAUgBlAGcAdQBsAGEAcgBWAGkAZABlAG8ASgBTAFYAaQBkAGUAbwBKAFMAVgBlAHIAcwBpAG8AbgAgADEALgAwAFYAaQBkAGUAbwBKAFMARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABzAHYAZwAyAHQAdABmACAAZgByAG8AbQAgAEYAbwBuAHQAZQBsAGwAbwAgAHAAcgBvAGoAZQBjAHQALgBoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAAAAAgAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfAAABAgEDAQQBBQEGAQcBCAEJAQoBCwEMAQ0BDgEPARABEQESARMBFAEVARYBFwEYARkBGgEbARwBHQEeAR8EcGxheQtwbGF5LWNpcmNsZQVwYXVzZQt2b2x1bWUtbXV0ZQp2b2x1bWUtbG93CnZvbHVtZS1taWQLdm9sdW1lLWhpZ2gQZnVsbHNjcmVlbi1lbnRlcg9mdWxsc2NyZWVuLWV4aXQGc3F1YXJlB3NwaW5uZXIJc3VidGl0bGVzCGNhcHRpb25zCGNoYXB0ZXJzBXNoYXJlA2NvZwZjaXJjbGUOY2lyY2xlLW91dGxpbmUTY2lyY2xlLWlubmVyLWNpcmNsZQJoZAZjYW5jZWwGcmVwbGF5CGZhY2Vib29rBWdwbHVzCGxpbmtlZGluB3R3aXR0ZXIGdHVtYmxyCXBpbnRlcmVzdBFhdWRpby1kZXNjcmlwdGlvbgVhdWRpbwAAAAAA) format("truetype");
- font-weight: normal;
- font-style: normal; }
-
-.vjs-icon-play, .video-js .vjs-big-play-button .vjs-icon-placeholder:before, .video-js .vjs-play-control .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-play:before, .video-js .vjs-big-play-button .vjs-icon-placeholder:before, .video-js .vjs-play-control .vjs-icon-placeholder:before {
- content: "\f101"; }
-
-.vjs-icon-play-circle {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-play-circle:before {
- content: "\f102"; }
-
-.vjs-icon-pause, .video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-pause:before, .video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder:before {
- content: "\f103"; }
-
-.vjs-icon-volume-mute, .video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-volume-mute:before, .video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder:before {
- content: "\f104"; }
-
-.vjs-icon-volume-low, .video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-volume-low:before, .video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder:before {
- content: "\f105"; }
-
-.vjs-icon-volume-mid, .video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-volume-mid:before, .video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder:before {
- content: "\f106"; }
-
-.vjs-icon-volume-high, .video-js .vjs-mute-control .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-volume-high:before, .video-js .vjs-mute-control .vjs-icon-placeholder:before {
- content: "\f107"; }
-
-.vjs-icon-fullscreen-enter, .video-js .vjs-fullscreen-control .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-fullscreen-enter:before, .video-js .vjs-fullscreen-control .vjs-icon-placeholder:before {
- content: "\f108"; }
-
-.vjs-icon-fullscreen-exit, .video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-fullscreen-exit:before, .video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder:before {
- content: "\f109"; }
-
-.vjs-icon-square {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-square:before {
- content: "\f10a"; }
-
-.vjs-icon-spinner {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-spinner:before {
- content: "\f10b"; }
-
-.vjs-icon-subtitles, .video-js .vjs-subtitles-button .vjs-icon-placeholder, .video-js .vjs-subs-caps-button .vjs-icon-placeholder,
-.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder,
-.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder,
-.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder,
-.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-subtitles:before, .video-js .vjs-subtitles-button .vjs-icon-placeholder:before, .video-js .vjs-subs-caps-button .vjs-icon-placeholder:before,
-.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder:before,
-.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder:before,
-.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder:before,
-.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder:before {
- content: "\f10c"; }
-
-.vjs-icon-captions, .video-js .vjs-captions-button .vjs-icon-placeholder, .video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder,
-.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-captions:before, .video-js .vjs-captions-button .vjs-icon-placeholder:before, .video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder:before,
-.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder:before {
- content: "\f10d"; }
-
-.vjs-icon-chapters, .video-js .vjs-chapters-button .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-chapters:before, .video-js .vjs-chapters-button .vjs-icon-placeholder:before {
- content: "\f10e"; }
-
-.vjs-icon-share {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-share:before {
- content: "\f10f"; }
-
-.vjs-icon-cog {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-cog:before {
- content: "\f110"; }
-
-.vjs-icon-circle, .video-js .vjs-play-progress, .video-js .vjs-volume-level {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-circle:before, .video-js .vjs-play-progress:before, .video-js .vjs-volume-level:before {
- content: "\f111"; }
-
-.vjs-icon-circle-outline {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-circle-outline:before {
- content: "\f112"; }
-
-.vjs-icon-circle-inner-circle {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-circle-inner-circle:before {
- content: "\f113"; }
-
-.vjs-icon-hd {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-hd:before {
- content: "\f114"; }
-
-.vjs-icon-cancel, .video-js .vjs-control.vjs-close-button .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-cancel:before, .video-js .vjs-control.vjs-close-button .vjs-icon-placeholder:before {
- content: "\f115"; }
-
-.vjs-icon-replay, .video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-replay:before, .video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder:before {
- content: "\f116"; }
-
-.vjs-icon-facebook {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-facebook:before {
- content: "\f117"; }
-
-.vjs-icon-gplus {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-gplus:before {
- content: "\f118"; }
-
-.vjs-icon-linkedin {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-linkedin:before {
- content: "\f119"; }
-
-.vjs-icon-twitter {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-twitter:before {
- content: "\f11a"; }
-
-.vjs-icon-tumblr {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-tumblr:before {
- content: "\f11b"; }
-
-.vjs-icon-pinterest {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-pinterest:before {
- content: "\f11c"; }
-
-.vjs-icon-audio-description, .video-js .vjs-descriptions-button .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-audio-description:before, .video-js .vjs-descriptions-button .vjs-icon-placeholder:before {
- content: "\f11d"; }
-
-.vjs-icon-audio, .video-js .vjs-audio-button .vjs-icon-placeholder {
- font-family: VideoJS;
- font-weight: normal;
- font-style: normal; }
-.vjs-icon-audio:before, .video-js .vjs-audio-button .vjs-icon-placeholder:before {
- content: "\f11e"; }
-
-.video-js {
- display: block;
- vertical-align: top;
- box-sizing: border-box;
- color: #fff;
- background-color: #000;
- position: relative;
- padding: 0;
- font-size: 10px;
- line-height: 1;
- font-weight: normal;
- font-style: normal;
- font-family: Arial, Helvetica, sans-serif; }
-.video-js:-moz-full-screen {
- position: absolute; }
-.video-js:-webkit-full-screen {
- width: 100% !important;
- height: 100% !important; }
-
-.video-js[tabindex="-1"] {
- outline: none; }
-
-.video-js *,
-.video-js *:before,
-.video-js *:after {
- box-sizing: inherit; }
-
-.video-js ul {
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
- list-style-position: outside;
- margin-left: 0;
- margin-right: 0;
- margin-top: 0;
- margin-bottom: 0; }
-
-.video-js.vjs-fluid,
-.video-js.vjs-16-9,
-.video-js.vjs-4-3 {
- width: 100%;
- max-width: 100%;
- height: 0; }
-
-.video-js.vjs-16-9 {
- padding-top: 56.25%; }
-
-.video-js.vjs-4-3 {
- padding-top: 75%; }
-
-.video-js.vjs-fill {
- width: 100%;
- height: 100%; }
-
-.video-js .vjs-tech {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%; }
-
-body.vjs-full-window {
- padding: 0;
- margin: 0;
- height: 100%;
- overflow-y: auto; }
-
-.vjs-full-window .video-js.vjs-fullscreen {
- position: fixed;
- overflow: hidden;
- z-index: 1000;
- left: 0;
- top: 0;
- bottom: 0;
- right: 0; }
-
-.video-js.vjs-fullscreen {
- width: 100% !important;
- height: 100% !important;
- padding-top: 0 !important; }
-
-.video-js.vjs-fullscreen.vjs-user-inactive {
- cursor: none; }
-
-.vjs-hidden {
- display: none !important; }
-
-.vjs-disabled {
- opacity: 0.5;
- cursor: default; }
-
-.video-js .vjs-offscreen {
- height: 1px;
- left: -9999px;
- position: absolute;
- top: 0;
- width: 1px; }
-
-.vjs-lock-showing {
- display: block !important;
- opacity: 1;
- visibility: visible; }
-
-.vjs-no-js {
- padding: 20px;
- color: #fff;
- background-color: #000;
- font-size: 18px;
- font-family: Arial, Helvetica, sans-serif;
- text-align: center;
- width: 300px;
- height: 150px;
- margin: 0px auto; }
-
-.vjs-no-js a,
-.vjs-no-js a:visited {
- color: #66A8CC; }
-
-.video-js .vjs-big-play-button {
- font-size: 3em;
- line-height: 1.5em;
- height: 1.5em;
- width: 3em;
- display: block;
- position: absolute;
- top: 10px;
- left: 10px;
- padding: 0;
- cursor: pointer;
- opacity: 1;
- border: 0.06666em solid #fff;
- background-color: #2B333F;
- background-color: rgba(43, 51, 63, 0.7);
- -webkit-border-radius: 0.3em;
- -moz-border-radius: 0.3em;
- border-radius: 0.3em;
- -webkit-transition: all 0.4s;
- -moz-transition: all 0.4s;
- -ms-transition: all 0.4s;
- -o-transition: all 0.4s;
- transition: all 0.4s; }
-
-.vjs-big-play-centered .vjs-big-play-button {
- top: 50%;
- left: 50%;
- margin-top: -0.75em;
- margin-left: -1.5em; }
-
-.video-js:hover .vjs-big-play-button,
-.video-js .vjs-big-play-button:focus {
- border-color: #fff;
- background-color: #73859f;
- background-color: rgba(115, 133, 159, 0.5);
- -webkit-transition: all 0s;
- -moz-transition: all 0s;
- -ms-transition: all 0s;
- -o-transition: all 0s;
- transition: all 0s; }
-
-.vjs-controls-disabled .vjs-big-play-button,
-.vjs-has-started .vjs-big-play-button,
-.vjs-using-native-controls .vjs-big-play-button,
-.vjs-error .vjs-big-play-button {
- display: none; }
-
-.vjs-has-started.vjs-paused.vjs-show-big-play-button-on-pause .vjs-big-play-button {
- display: block; }
-
-.video-js button {
- background: none;
- border: none;
- color: inherit;
- display: inline-block;
- overflow: visible;
- font-size: inherit;
- line-height: inherit;
- text-transform: none;
- text-decoration: none;
- transition: none;
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none; }
-
-.video-js .vjs-control.vjs-close-button {
- cursor: pointer;
- height: 3em;
- position: absolute;
- right: 0;
- top: 0.5em;
- z-index: 2; }
-
-.video-js .vjs-modal-dialog {
- background: rgba(0, 0, 0, 0.8);
- background: -webkit-linear-gradient(-90deg, rgba(0, 0, 0, 0.8), rgba(255, 255, 255, 0));
- background: linear-gradient(180deg, rgba(0, 0, 0, 0.8), rgba(255, 255, 255, 0));
- overflow: auto;
- box-sizing: content-box; }
-
-.video-js .vjs-modal-dialog > * {
- box-sizing: border-box; }
-
-.vjs-modal-dialog .vjs-modal-dialog-content {
- font-size: 1.2em;
- line-height: 1.5;
- padding: 20px 24px;
- z-index: 1; }
-
-.vjs-menu-button {
- cursor: pointer; }
-
-.vjs-menu-button.vjs-disabled {
- cursor: default; }
-
-.vjs-workinghover .vjs-menu-button.vjs-disabled:hover .vjs-menu {
- display: none; }
-
-.vjs-menu .vjs-menu-content {
- display: block;
- padding: 0;
- margin: 0;
- font-family: Arial, Helvetica, sans-serif;
- overflow: auto;
- box-sizing: content-box; }
-
-.vjs-menu .vjs-menu-content > * {
- box-sizing: border-box; }
-
-.vjs-scrubbing .vjs-menu-button:hover .vjs-menu {
- display: none; }
-
-.vjs-menu li {
- list-style: none;
- margin: 0;
- padding: 0.2em 0;
- line-height: 1.4em;
- font-size: 1.2em;
- text-align: center;
- text-transform: lowercase; }
-
-.vjs-menu li.vjs-menu-item:focus,
-.vjs-menu li.vjs-menu-item:hover {
- background-color: #73859f;
- background-color: rgba(115, 133, 159, 0.5); }
-
-.vjs-menu li.vjs-selected,
-.vjs-menu li.vjs-selected:focus,
-.vjs-menu li.vjs-selected:hover {
- background-color: #fff;
- color: #2B333F; }
-
-.vjs-menu li.vjs-menu-title {
- text-align: center;
- text-transform: uppercase;
- font-size: 1em;
- line-height: 2em;
- padding: 0;
- margin: 0 0 0.3em 0;
- font-weight: bold;
- cursor: default; }
-
-.vjs-menu-button-popup .vjs-menu {
- display: none;
- position: absolute;
- bottom: 0;
- width: 10em;
- left: -3em;
- height: 0em;
- margin-bottom: 1.5em;
- border-top-color: rgba(43, 51, 63, 0.7); }
-
-.vjs-menu-button-popup .vjs-menu .vjs-menu-content {
- background-color: #2B333F;
- background-color: rgba(43, 51, 63, 0.7);
- position: absolute;
- width: 100%;
- bottom: 1.5em;
- max-height: 15em; }
-
-.vjs-workinghover .vjs-menu-button-popup:hover .vjs-menu,
-.vjs-menu-button-popup .vjs-menu.vjs-lock-showing {
- display: block; }
-
-.video-js .vjs-menu-button-inline {
- -webkit-transition: all 0.4s;
- -moz-transition: all 0.4s;
- -ms-transition: all 0.4s;
- -o-transition: all 0.4s;
- transition: all 0.4s;
- overflow: hidden; }
-
-.video-js .vjs-menu-button-inline:before {
- width: 2.222222222em; }
-
-.video-js .vjs-menu-button-inline:hover,
-.video-js .vjs-menu-button-inline:focus,
-.video-js .vjs-menu-button-inline.vjs-slider-active,
-.video-js.vjs-no-flex .vjs-menu-button-inline {
- width: 12em; }
-
-.vjs-menu-button-inline .vjs-menu {
- opacity: 0;
- height: 100%;
- width: auto;
- position: absolute;
- left: 4em;
- top: 0;
- padding: 0;
- margin: 0;
- -webkit-transition: all 0.4s;
- -moz-transition: all 0.4s;
- -ms-transition: all 0.4s;
- -o-transition: all 0.4s;
- transition: all 0.4s; }
-
-.vjs-menu-button-inline:hover .vjs-menu,
-.vjs-menu-button-inline:focus .vjs-menu,
-.vjs-menu-button-inline.vjs-slider-active .vjs-menu {
- display: block;
- opacity: 1; }
-
-.vjs-no-flex .vjs-menu-button-inline .vjs-menu {
- display: block;
- opacity: 1;
- position: relative;
- width: auto; }
-
-.vjs-no-flex .vjs-menu-button-inline:hover .vjs-menu,
-.vjs-no-flex .vjs-menu-button-inline:focus .vjs-menu,
-.vjs-no-flex .vjs-menu-button-inline.vjs-slider-active .vjs-menu {
- width: auto; }
-
-.vjs-menu-button-inline .vjs-menu-content {
- width: auto;
- height: 100%;
- margin: 0;
- overflow: hidden; }
-
-.video-js .vjs-control-bar {
- display: none;
- width: 100%;
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- height: 3.0em;
- background-color: #2B333F;
- background-color: rgba(43, 51, 63, 0.7); }
-
-.vjs-has-started .vjs-control-bar {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- visibility: visible;
- opacity: 1;
- -webkit-transition: visibility 0.1s, opacity 0.1s;
- -moz-transition: visibility 0.1s, opacity 0.1s;
- -ms-transition: visibility 0.1s, opacity 0.1s;
- -o-transition: visibility 0.1s, opacity 0.1s;
- transition: visibility 0.1s, opacity 0.1s; }
-
-.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
- visibility: visible;
- opacity: 0;
- -webkit-transition: visibility 1s, opacity 1s;
- -moz-transition: visibility 1s, opacity 1s;
- -ms-transition: visibility 1s, opacity 1s;
- -o-transition: visibility 1s, opacity 1s;
- transition: visibility 1s, opacity 1s; }
-
-.vjs-controls-disabled .vjs-control-bar,
-.vjs-using-native-controls .vjs-control-bar,
-.vjs-error .vjs-control-bar {
- display: none !important; }
-
-.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
- opacity: 1;
- visibility: visible; }
-
-.vjs-has-started.vjs-no-flex .vjs-control-bar {
- display: table; }
-
-.video-js .vjs-control {
- position: relative;
- text-align: center;
- margin: 0;
- padding: 0;
- height: 100%;
- width: 4em;
- -webkit-box-flex: none;
- -moz-box-flex: none;
- -webkit-flex: none;
- -ms-flex: none;
- flex: none; }
-
-.vjs-button > .vjs-icon-placeholder:before {
- font-size: 1.8em;
- line-height: 1.67; }
-
-.video-js .vjs-control:focus:before,
-.video-js .vjs-control:hover:before,
-.video-js .vjs-control:focus {
- text-shadow: 0em 0em 1em white; }
-
-.video-js .vjs-control-text {
- border: 0;
- clip: rect(0 0 0 0);
- height: 1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
- width: 1px; }
-
-.vjs-no-flex .vjs-control {
- display: table-cell;
- vertical-align: middle; }
-
-.video-js .vjs-custom-control-spacer {
- display: none; }
-
-.video-js .vjs-progress-control {
- cursor: pointer;
- -webkit-box-flex: auto;
- -moz-box-flex: auto;
- -webkit-flex: auto;
- -ms-flex: auto;
- flex: auto;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-align: center;
- -webkit-align-items: center;
- -ms-flex-align: center;
- align-items: center;
- min-width: 4em; }
-
-.vjs-live .vjs-progress-control {
- display: none; }
-
-.vjs-no-flex .vjs-progress-control {
- width: auto; }
-
-.video-js .vjs-progress-holder {
- -webkit-box-flex: auto;
- -moz-box-flex: auto;
- -webkit-flex: auto;
- -ms-flex: auto;
- flex: auto;
- -webkit-transition: all 0.2s;
- -moz-transition: all 0.2s;
- -ms-transition: all 0.2s;
- -o-transition: all 0.2s;
- transition: all 0.2s;
- height: 0.3em; }
-
-.video-js .vjs-progress-control .vjs-progress-holder {
- margin: 0 10px; }
-
-.video-js .vjs-progress-control:hover .vjs-progress-holder {
- font-size: 1.666666666666666666em; }
-
-.video-js .vjs-progress-holder .vjs-play-progress,
-.video-js .vjs-progress-holder .vjs-load-progress,
-.video-js .vjs-progress-holder .vjs-load-progress div {
- position: absolute;
- display: block;
- height: 100%;
- margin: 0;
- padding: 0;
- width: 0;
- left: 0;
- top: 0; }
-
-.video-js .vjs-play-progress {
- background-color: #fff; }
-.video-js .vjs-play-progress:before {
- font-size: 0.9em;
- position: absolute;
- right: -0.5em;
- top: -0.333333333333333em;
- z-index: 1; }
-
-.video-js .vjs-load-progress {
- background: #bfc7d3;
- background: rgba(115, 133, 159, 0.5); }
-
-.video-js .vjs-load-progress div {
- background: white;
- background: rgba(115, 133, 159, 0.75); }
-
-.video-js .vjs-time-tooltip {
- background-color: #fff;
- background-color: rgba(255, 255, 255, 0.8);
- -webkit-border-radius: 0.3em;
- -moz-border-radius: 0.3em;
- border-radius: 0.3em;
- color: #000;
- float: right;
- font-family: Arial, Helvetica, sans-serif;
- font-size: 1em;
- padding: 6px 8px 8px 8px;
- pointer-events: none;
- position: relative;
- top: -3.4em;
- visibility: hidden;
- z-index: 1; }
-
-.video-js .vjs-progress-holder:focus .vjs-time-tooltip {
- display: none; }
-
-.video-js .vjs-progress-control:hover .vjs-time-tooltip,
-.video-js .vjs-progress-control:hover .vjs-progress-holder:focus .vjs-time-tooltip {
- display: block;
- font-size: 0.6em;
- visibility: visible; }
-
-.video-js .vjs-progress-control .vjs-mouse-display {
- display: none;
- position: absolute;
- width: 1px;
- height: 100%;
- background-color: #000;
- z-index: 1; }
-
-.vjs-no-flex .vjs-progress-control .vjs-mouse-display {
- z-index: 0; }
-
-.video-js .vjs-progress-control:hover .vjs-mouse-display {
- display: block; }
-
-.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display {
- visibility: hidden;
- opacity: 0;
- -webkit-transition: visibility 1s, opacity 1s;
- -moz-transition: visibility 1s, opacity 1s;
- -ms-transition: visibility 1s, opacity 1s;
- -o-transition: visibility 1s, opacity 1s;
- transition: visibility 1s, opacity 1s; }
-
-.video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display {
- display: none; }
-
-.vjs-mouse-display .vjs-time-tooltip {
- color: #fff;
- background-color: #000;
- background-color: rgba(0, 0, 0, 0.8); }
-
-.video-js .vjs-slider {
- position: relative;
- cursor: pointer;
- padding: 0;
- margin: 0 0.45em 0 0.45em;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- background-color: #73859f;
- background-color: rgba(115, 133, 159, 0.5); }
-
-.video-js .vjs-slider:focus {
- text-shadow: 0em 0em 1em white;
- -webkit-box-shadow: 0 0 1em #fff;
- -moz-box-shadow: 0 0 1em #fff;
- box-shadow: 0 0 1em #fff; }
-
-.video-js .vjs-mute-control {
- cursor: pointer;
- -webkit-box-flex: none;
- -moz-box-flex: none;
- -webkit-flex: none;
- -ms-flex: none;
- flex: none;
- padding-left: 2em;
- padding-right: 2em;
- padding-bottom: 3em; }
-
-.video-js .vjs-volume-control {
- cursor: pointer;
- margin-right: 1em;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex; }
-
-.video-js .vjs-volume-control.vjs-volume-horizontal {
- width: 5em; }
-
-.video-js .vjs-volume-panel .vjs-volume-control {
- visibility: visible;
- opacity: 0;
- width: 1px;
- height: 1px;
- margin-left: -1px; }
-
-.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical {
- -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; }
-.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical .vjs-volume-bar,
-.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical .vjs-volume-level {
- -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; }
-
-.video-js .vjs-volume-panel {
- -webkit-transition: width 1s;
- -moz-transition: width 1s;
- -ms-transition: width 1s;
- -o-transition: width 1s;
- transition: width 1s; }
-.video-js .vjs-volume-panel:hover .vjs-volume-control,
-.video-js .vjs-volume-panel:active .vjs-volume-control,
-.video-js .vjs-volume-panel:focus .vjs-volume-control,
-.video-js .vjs-volume-panel .vjs-volume-control:hover,
-.video-js .vjs-volume-panel .vjs-volume-control:active,
-.video-js .vjs-volume-panel .vjs-volume-control:focus,
-.video-js .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control,
-.video-js .vjs-volume-panel .vjs-mute-control:active ~ .vjs-volume-control,
-.video-js .vjs-volume-panel .vjs-mute-control:focus ~ .vjs-volume-control,
-.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active {
- visibility: visible;
- opacity: 1;
- position: relative;
- -webkit-transition: visibility 0.1s, opacity 0.1s, height 0.1s, width 0.1s, left 0s, top 0s;
- -moz-transition: visibility 0.1s, opacity 0.1s, height 0.1s, width 0.1s, left 0s, top 0s;
- -ms-transition: visibility 0.1s, opacity 0.1s, height 0.1s, width 0.1s, left 0s, top 0s;
- -o-transition: visibility 0.1s, opacity 0.1s, height 0.1s, width 0.1s, left 0s, top 0s;
- transition: visibility 0.1s, opacity 0.1s, height 0.1s, width 0.1s, left 0s, top 0s; }
-.video-js .vjs-volume-panel:hover .vjs-volume-control.vjs-volume-horizontal,
-.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal,
-.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-horizontal,
-.video-js .vjs-volume-panel .vjs-volume-control:hover.vjs-volume-horizontal,
-.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-horizontal,
-.video-js .vjs-volume-panel .vjs-volume-control:focus.vjs-volume-horizontal,
-.video-js .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control.vjs-volume-horizontal,
-.video-js .vjs-volume-panel .vjs-mute-control:active ~ .vjs-volume-control.vjs-volume-horizontal,
-.video-js .vjs-volume-panel .vjs-mute-control:focus ~ .vjs-volume-control.vjs-volume-horizontal,
-.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-horizontal {
- width: 5em;
- height: 3em; }
-.video-js .vjs-volume-panel:hover .vjs-volume-control.vjs-volume-vertical,
-.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-vertical,
-.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-vertical,
-.video-js .vjs-volume-panel .vjs-volume-control:hover.vjs-volume-vertical,
-.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-vertical,
-.video-js .vjs-volume-panel .vjs-volume-control:focus.vjs-volume-vertical,
-.video-js .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control.vjs-volume-vertical,
-.video-js .vjs-volume-panel .vjs-mute-control:active ~ .vjs-volume-control.vjs-volume-vertical,
-.video-js .vjs-volume-panel .vjs-mute-control:focus ~ .vjs-volume-control.vjs-volume-vertical,
-.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-vertical {
- -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; }
-.video-js .vjs-volume-panel:hover .vjs-volume-control.vjs-volume-vertical .vjs-volume-bar,
-.video-js .vjs-volume-panel:hover .vjs-volume-control.vjs-volume-vertical .vjs-volume-level,
-.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-vertical .vjs-volume-bar,
-.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-vertical .vjs-volume-level,
-.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-vertical .vjs-volume-bar,
-.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-vertical .vjs-volume-level,
-.video-js .vjs-volume-panel .vjs-volume-control:hover.vjs-volume-vertical .vjs-volume-bar,
-.video-js .vjs-volume-panel .vjs-volume-control:hover.vjs-volume-vertical .vjs-volume-level,
-.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-vertical .vjs-volume-bar,
-.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-vertical .vjs-volume-level,
-.video-js .vjs-volume-panel .vjs-volume-control:focus.vjs-volume-vertical .vjs-volume-bar,
-.video-js .vjs-volume-panel .vjs-volume-control:focus.vjs-volume-vertical .vjs-volume-level,
-.video-js .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control.vjs-volume-vertical .vjs-volume-bar,
-.video-js .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control.vjs-volume-vertical .vjs-volume-level,
-.video-js .vjs-volume-panel .vjs-mute-control:active ~ .vjs-volume-control.vjs-volume-vertical .vjs-volume-bar,
-.video-js .vjs-volume-panel .vjs-mute-control:active ~ .vjs-volume-control.vjs-volume-vertical .vjs-volume-level,
-.video-js .vjs-volume-panel .vjs-mute-control:focus ~ .vjs-volume-control.vjs-volume-vertical .vjs-volume-bar,
-.video-js .vjs-volume-panel .vjs-mute-control:focus ~ .vjs-volume-control.vjs-volume-vertical .vjs-volume-level,
-.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-vertical .vjs-volume-bar,
-.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-vertical .vjs-volume-level {
- -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; }
-.video-js .vjs-volume-panel.vjs-volume-panel-horizontal:hover, .video-js .vjs-volume-panel.vjs-volume-panel-horizontal:focus, .video-js .vjs-volume-panel.vjs-volume-panel-horizontal:active, .video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active {
- width: 9em;
- -webkit-transition: width 0.1s;
- -moz-transition: width 0.1s;
- -ms-transition: width 0.1s;
- -o-transition: width 0.1s;
- transition: width 0.1s; }
-
-.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical {
- height: 8em;
- width: 3em;
- left: -3.5em;
- -webkit-transition: visibility 1s, opacity 1s, height 1s 1s, width 1s 1s, left 1s 1s, top 1s 1s;
- -moz-transition: visibility 1s, opacity 1s, height 1s 1s, width 1s 1s, left 1s 1s, top 1s 1s;
- -ms-transition: visibility 1s, opacity 1s, height 1s 1s, width 1s 1s, left 1s 1s, top 1s 1s;
- -o-transition: visibility 1s, opacity 1s, height 1s 1s, width 1s 1s, left 1s 1s, top 1s 1s;
- transition: visibility 1s, opacity 1s, height 1s 1s, width 1s 1s, left 1s 1s, top 1s 1s; }
-
-.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal {
- -webkit-transition: visibility 1s, opacity 1s, height 1s 1s, width 1s, left 1s 1s, top 1s 1s;
- -moz-transition: visibility 1s, opacity 1s, height 1s 1s, width 1s, left 1s 1s, top 1s 1s;
- -ms-transition: visibility 1s, opacity 1s, height 1s 1s, width 1s, left 1s 1s, top 1s 1s;
- -o-transition: visibility 1s, opacity 1s, height 1s 1s, width 1s, left 1s 1s, top 1s 1s;
- transition: visibility 1s, opacity 1s, height 1s 1s, width 1s, left 1s 1s, top 1s 1s; }
-
-.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal {
- width: 5em;
- height: 3em;
- visibility: visible;
- opacity: 1;
- position: relative;
- -webkit-transition: none;
- -moz-transition: none;
- -ms-transition: none;
- -o-transition: none;
- transition: none; }
-
-.video-js.vjs-no-flex .vjs-volume-control.vjs-volume-vertical,
-.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical {
- position: absolute;
- bottom: 3em;
- left: 0.5em; }
-
-.video-js .vjs-volume-panel {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex; }
-
-.video-js .vjs-volume-bar {
- margin: 1.35em 0.45em; }
-
-.vjs-volume-bar.vjs-slider-horizontal {
- width: 5em;
- height: 0.3em; }
-
-.vjs-volume-bar.vjs-slider-vertical {
- width: 0.3em;
- height: 5em;
- margin: 1.35em auto; }
-
-.video-js .vjs-volume-level {
- position: absolute;
- bottom: 0;
- left: 0;
- background-color: #fff; }
-.video-js .vjs-volume-level:before {
- position: absolute;
- font-size: 0.9em; }
-
-.vjs-slider-vertical .vjs-volume-level {
- width: 0.3em; }
-.vjs-slider-vertical .vjs-volume-level:before {
- top: -0.5em;
- left: -0.3em; }
-
-.vjs-slider-horizontal .vjs-volume-level {
- height: 0.3em; }
-.vjs-slider-horizontal .vjs-volume-level:before {
- top: -0.3em;
- right: -0.5em; }
-
-.video-js .vjs-volume-panel.vjs-volume-panel-vertical {
- width: 4em; }
-
-.vjs-volume-bar.vjs-slider-vertical .vjs-volume-level {
- height: 100%; }
-
-.vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level {
- width: 100%; }
-
-.video-js .vjs-volume-vertical {
- width: 3em;
- height: 8em;
- bottom: 8em;
- background-color: #2B333F;
- background-color: rgba(43, 51, 63, 0.7); }
-
-.video-js .vjs-volume-horizontal .vjs-menu {
- left: -2em; }
-
-.vjs-poster {
- display: inline-block;
- vertical-align: middle;
- background-repeat: no-repeat;
- background-position: 50% 50%;
- background-size: contain;
- /*background-color: #000000;*/
- cursor: pointer;
- margin: 0;
- padding: 0;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- height: 100%; }
-
-.vjs-poster img {
- display: block;
- vertical-align: middle;
- margin: 0 auto;
- max-height: 100%;
- padding: 0;
- width: 100%; }
-
-.vjs-has-started .vjs-poster {
- display: none; }
-
-.vjs-audio.vjs-has-started .vjs-poster {
- display: block; }
-
-.vjs-using-native-controls .vjs-poster {
- display: none; }
-
-.video-js .vjs-live-control {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-align: flex-start;
- -webkit-align-items: flex-start;
- -ms-flex-align: flex-start;
- align-items: flex-start;
- -webkit-box-flex: auto;
- -moz-box-flex: auto;
- -webkit-flex: auto;
- -ms-flex: auto;
- flex: auto;
- font-size: 1em;
- line-height: 3em; }
-
-.vjs-no-flex .vjs-live-control {
- display: table-cell;
- width: auto;
- text-align: left; }
-
-.video-js .vjs-time-control {
- -webkit-box-flex: none;
- -moz-box-flex: none;
- -webkit-flex: none;
- -ms-flex: none;
- flex: none;
- font-size: 1em;
- line-height: 3em;
- min-width: 2em;
- width: auto;
- padding-left: 1em;
- padding-right: 1em; }
-
-.vjs-live .vjs-time-control {
- display: none; }
-
-.video-js .vjs-current-time,
-.vjs-no-flex .vjs-current-time {
- display: none; }
-
-.vjs-no-flex .vjs-remaining-time.vjs-time-control.vjs-control {
- width: 0px !important;
- white-space: nowrap; }
-
-.video-js .vjs-duration,
-.vjs-no-flex .vjs-duration {
- display: none; }
-
-.vjs-time-divider {
- display: none;
- line-height: 3em; }
-
-.vjs-live .vjs-time-divider {
- display: none; }
-
-.video-js .vjs-play-control .vjs-icon-placeholder {
- cursor: pointer;
- -webkit-box-flex: none;
- -moz-box-flex: none;
- -webkit-flex: none;
- -ms-flex: none;
- flex: none; }
-
-.vjs-text-track-display {
- position: absolute;
- bottom: 3em;
- left: 0;
- right: 0;
- top: 0;
- pointer-events: none; }
-
-.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display {
- bottom: 1em; }
-
-.video-js .vjs-text-track {
- font-size: 1.4em;
- text-align: center;
- margin-bottom: 0.1em;
- background-color: #000;
- background-color: rgba(0, 0, 0, 0.5); }
-
-.vjs-subtitles {
- color: #fff; }
-
-.vjs-captions {
- color: #fc6; }
-
-.vjs-tt-cue {
- display: block; }
-
-video::-webkit-media-text-track-display {
- -moz-transform: translateY(-3em);
- -ms-transform: translateY(-3em);
- -o-transform: translateY(-3em);
- -webkit-transform: translateY(-3em);
- transform: translateY(-3em); }
-
-.video-js.vjs-user-inactive.vjs-playing video::-webkit-media-text-track-display {
- -moz-transform: translateY(-1.5em);
- -ms-transform: translateY(-1.5em);
- -o-transform: translateY(-1.5em);
- -webkit-transform: translateY(-1.5em);
- transform: translateY(-1.5em); }
-
-.video-js .vjs-fullscreen-control {
- cursor: pointer;
- -webkit-box-flex: none;
- -moz-box-flex: none;
- -webkit-flex: none;
- -ms-flex: none;
- flex: none; }
-
-.vjs-playback-rate .vjs-playback-rate-value {
- font-size: 1.5em;
- line-height: 2;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- text-align: center; }
-
-.vjs-playback-rate .vjs-menu {
- width: 4em;
- left: 0em; }
-
-.vjs-error .vjs-error-display .vjs-modal-dialog-content {
- font-size: 1.4em;
- text-align: center; }
-
-.vjs-error .vjs-error-display:before {
- color: #fff;
- content: 'X';
- font-family: Arial, Helvetica, sans-serif;
- font-size: 4em;
- left: 0;
- line-height: 1;
- margin-top: -0.5em;
- position: absolute;
- text-shadow: 0.05em 0.05em 0.1em #000;
- text-align: center;
- top: 50%;
- vertical-align: middle;
- width: 100%; }
-
-.vjs-loading-spinner {
- display: none;
- position: absolute;
- top: 50%;
- left: 50%;
- margin: -25px 0 0 -25px;
- opacity: 0.85;
- text-align: left;
- border: 6px solid rgba(43, 51, 63, 0.7);
- box-sizing: border-box;
- background-clip: padding-box;
- width: 50px;
- height: 50px;
- border-radius: 25px; }
-
-.vjs-seeking .vjs-loading-spinner,
-.vjs-waiting .vjs-loading-spinner {
- display: block; }
-
-.vjs-loading-spinner:before,
-.vjs-loading-spinner:after {
- content: "";
- position: absolute;
- margin: -6px;
- box-sizing: inherit;
- width: inherit;
- height: inherit;
- border-radius: inherit;
- opacity: 1;
- border: inherit;
- border-color: transparent;
- border-top-color: white; }
-
-.vjs-seeking .vjs-loading-spinner:before,
-.vjs-seeking .vjs-loading-spinner:after,
-.vjs-waiting .vjs-loading-spinner:before,
-.vjs-waiting .vjs-loading-spinner:after {
- -webkit-animation: vjs-spinner-spin 1.1s cubic-bezier(0.6, 0.2, 0, 0.8) infinite, vjs-spinner-fade 1.1s linear infinite;
- animation: vjs-spinner-spin 1.1s cubic-bezier(0.6, 0.2, 0, 0.8) infinite, vjs-spinner-fade 1.1s linear infinite; }
-
-.vjs-seeking .vjs-loading-spinner:before,
-.vjs-waiting .vjs-loading-spinner:before {
- border-top-color: white; }
-
-.vjs-seeking .vjs-loading-spinner:after,
-.vjs-waiting .vjs-loading-spinner:after {
- border-top-color: white;
- -webkit-animation-delay: 0.44s;
- animation-delay: 0.44s; }
-
-@keyframes vjs-spinner-spin {
- 100% {
- transform: rotate(360deg); } }
-
-@-webkit-keyframes vjs-spinner-spin {
- 100% {
- -webkit-transform: rotate(360deg); } }
-
-@keyframes vjs-spinner-fade {
- 0% {
- border-top-color: #73859f; }
- 20% {
- border-top-color: #73859f; }
- 35% {
- border-top-color: white; }
- 60% {
- border-top-color: #73859f; }
- 100% {
- border-top-color: #73859f; } }
-
-@-webkit-keyframes vjs-spinner-fade {
- 0% {
- border-top-color: #73859f; }
- 20% {
- border-top-color: #73859f; }
- 35% {
- border-top-color: white; }
- 60% {
- border-top-color: #73859f; }
- 100% {
- border-top-color: #73859f; } }
-
-.vjs-chapters-button .vjs-menu ul {
- width: 24em; }
-
-.video-js .vjs-subs-caps-button + .vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder {
- position: absolute; }
-
-.video-js .vjs-subs-caps-button + .vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before {
- font-family: VideoJS;
- content: "\f10d";
- font-size: 1.5em;
- line-height: inherit; }
-
-.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-custom-control-spacer {
- -webkit-box-flex: auto;
- -moz-box-flex: auto;
- -webkit-flex: auto;
- -ms-flex: auto;
- flex: auto; }
-
-.video-js.vjs-layout-tiny:not(.vjs-fullscreen).vjs-no-flex .vjs-custom-control-spacer {
- width: auto; }
-
-.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-current-time, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-time-divider, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-duration, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-remaining-time,
-.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-playback-rate, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-progress-control,
-.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-mute-control, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-volume-control,
-.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-chapters-button, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-descriptions-button, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-captions-button,
-.video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-subtitles-button, .video-js.vjs-layout-tiny:not(.vjs-fullscreen) .vjs-audio-button {
- display: none; }
-
-.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-current-time, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-time-divider, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-duration, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-remaining-time,
-.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-playback-rate,
-.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-mute-control, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-volume-control,
-.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-chapters-button, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-descriptions-button, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-captions-button,
-.video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-subtitles-button, .video-js.vjs-layout-x-small:not(.vjs-fullscreen) .vjs-audio-button {
- display: none; }
-
-.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-current-time, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-time-divider, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-duration, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-remaining-time,
-.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-playback-rate,
-.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-mute-control, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-volume-control,
-.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-chapters-button, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-descriptions-button, .video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-captions-button,
-.video-js.vjs-layout-small:not(.vjs-fullscreen) .vjs-subtitles-button .vjs-audio-button {
- display: none; }
-
-.vjs-modal-dialog.vjs-text-track-settings {
- background-color: #2B333F;
- background-color: rgba(43, 51, 63, 0.75);
- color: #fff;
- height: 70%; }
-
-.vjs-text-track-settings .vjs-modal-dialog-content {
- display: table; }
-
-.vjs-text-track-settings .vjs-track-settings-colors,
-.vjs-text-track-settings .vjs-track-settings-font,
-.vjs-text-track-settings .vjs-track-settings-controls {
- display: table-cell; }
-
-.vjs-text-track-settings .vjs-track-settings-controls {
- text-align: right;
- vertical-align: bottom; }
-
-.vjs-text-track-settings fieldset {
- margin: 5px;
- padding: 3px;
- border: none; }
-
-.vjs-text-track-settings fieldset span {
- display: inline-block;
- margin-left: 5px; }
-
-.vjs-text-track-settings legend {
- color: #fff;
- margin: 0 0 5px 0; }
-
-.vjs-text-track-settings .vjs-label {
- position: absolute;
- clip: rect(1px 1px 1px 1px);
- clip: rect(1px, 1px, 1px, 1px);
- display: block;
- margin: 0 0 5px 0;
- padding: 0;
- border: 0;
- height: 1px;
- width: 1px;
- overflow: hidden; }
-
-.vjs-track-settings-controls button:focus,
-.vjs-track-settings-controls button:active {
- outline-style: solid;
- outline-width: medium;
- background-image: linear-gradient(0deg, #fff 88%, #73859f 100%); }
-
-.vjs-track-settings-controls button:hover {
- color: rgba(43, 51, 63, 0.75); }
-
-.vjs-track-settings-controls button {
- background-color: #fff;
- background-image: linear-gradient(-180deg, #fff 88%, #73859f 100%);
- color: #2B333F;
- cursor: pointer;
- border-radius: 2px; }
-
-.vjs-track-settings-controls .vjs-default-button {
- margin-right: 1em; }
-
-@media print {
- .video-js > *:not(.vjs-tech):not(.vjs-poster) {
- visibility: hidden; } }
-
-@media \0screen {
- .vjs-user-inactive.vjs-playing .vjs-control-bar :before {
- content: "";
- }
-}
-
-@media \0screen {
- .vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
- visibility: hidden;
- }
-}
--- /dev/null
+@charset "UTF-8";.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-modal-dialog,.vjs-button>.vjs-icon-placeholder:before,.vjs-modal-dialog .vjs-modal-dialog-content{position:absolute;top:0;left:0;width:100%;height:100%}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.vjs-button>.vjs-icon-placeholder:before{text-align:center}@font-face{font-family:VideoJS;src:url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAABDkAAsAAAAAG6gAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADsAAABUIIslek9TLzIAAAFEAAAAPgAAAFZRiV3hY21hcAAAAYQAAADaAAADPv749/pnbHlmAAACYAAAC3AAABHQZg6OcWhlYWQAAA3QAAAAKwAAADYZw251aGhlYQAADfwAAAAdAAAAJA+RCLFobXR4AAAOHAAAABMAAACM744AAGxvY2EAAA4wAAAASAAAAEhF6kqubWF4cAAADngAAAAfAAAAIAE0AIFuYW1lAAAOmAAAASUAAAIK1cf1oHBvc3QAAA/AAAABJAAAAdPExYuNeJxjYGRgYOBiMGCwY2BycfMJYeDLSSzJY5BiYGGAAJA8MpsxJzM9kYEDxgPKsYBpDiBmg4gCACY7BUgAeJxjYGS7wTiBgZWBgaWQ5RkDA8MvCM0cwxDOeI6BgYmBlZkBKwhIc01hcPjI+FGJHcRdyA4RZgQRADK3CxEAAHic7dFZbsMgAEXRS0ycyZnnOeG7y+qC8pU1dHusIOXxuoxaOlwZYWQB0Aea4quIEN4E9LzKbKjzDeM6H/mua6Lmc/p8yhg0lvdYx15ZG8uOLQOGjMp3EzqmzJizYMmKNRu27Nhz4MiJMxeu3Ljz4Ekqm7T8P52G8PP3lnTOVk++Z6iN6QZzNN1F7ptuN7eGOjDUoaGODHVsuvU8MdTO9Hd5aqgzQ50b6sJQl4a6MtS1oW4MdWuoO0PdG+rBUI+GejLUs6FeDPVqqDdDvRvqw1CfhpqM9At0iFLaAAB4nJ1YDXBTVRZ+5/22TUlJ8we0pHlJm7RJf5O8F2j6EymlSPkpxaL8U2xpa3DKj0CBhc2IW4eWKSokIoLsuMqssM64f+jA4HSdWXXXscBq67IOs3FXZ1ZYWVyRFdo899yXtIBQZ90k7717zz3v3HPPOfd854YCCj9cL9dL0RQFOqCbGJnrHb5EayiKIWN8iA/hWBblo6hUWm8TtCDwE80WMJus/irwyxOdxeB0MDb14VNJHnXYoLLSl6FfCUYO9nYPTA8Epg9090LprfbBbZ2hY0UlJUXHQp3/vtWkS6EBv8+rPMq5u9692f/dNxJNiqwC1xPE9TCUgCsSdQWgE3XQD25lkG4CN2xmTcOXWBOyser6RN6KnGbKSbmQ3+d0OI1m2W8QzLLkI2sykrWAgJJEtA8vGGW/2Q+CmT3n8zS9wZwu2DCvtuZKZN3xkrLh36yCZuUomQSqGpY8t/25VfHVhw8z4ebGBtfLb0ya9PCaDc+8dGTvk2dsh6z7WzvowlXKUSWo9MJ15a3KrEP2loOr2Ojhw6iW6hf2BDdEccQvZGpaAy7YovSwq8kr7HGllxpd71rkS6G0Sf11sl9OvMK1+jwPPODxjUwkOim9CU3ix1wNjXDfmJSEn618Bs6lpWwUpU+8PCqLMY650zjq8VhCIP17NEKTx3eaLL+s5Pi6yJWaWjTHLR1jYzPSV9VF/6Ojdb/1kO3Mk3uhHC0x6gc1BjlKQ+nQFxTYdaJkZ7ySVxLBbhR1dsboNXp1tCYKW2LRaEzpYcIx2BKNxaL0ZaUnSqfFoiNhHKR/GkX6PWUSAaJelQaqZL1EpoHNsajSEyPSoJ9IjhIxTdjHLmwZvhRDOiFTY/YeQnvrVZmiTQtGncECXtFTBZLOVwwMRgoXHAkXzMzPn1nAJJ8jYSbMDaqN2waGLzNhih/bZynUBMpIWSg7VYi7DRx2m8ALkIdRCJwI6ArJx2EI8kaDWeTQKeAFk9fjl/1AvwktjQ1P7NjyMGQyfd4vjipX6M/i52D7Cq80kqlcxEcGXRr/FEcgs0u5uGgB4VWuMFfpdn2Re6Hi3PqzmxWKsz6+ae2Pn9hXXw/fqM859UiGC0oKYYILJBqJrsn1Z1E5qOs9rQCiUQRREjm8yJcbHF5cUJufX1vAHlefw0XgUoboS3ETfQlTxBC4SOtuE8VPRJTBSCQSjZCpk7Gqzu+masaZ2y7Zjehho4F3g82BNDkAHpORG4+OCS+f6JTPmtRn/PH1kch6d04sp7AQb25aQ/pqUyXeQ8vrebG8OYQdXOQ+585u0sdW9rqalzRURiJ+9F4MweRFrKUjl1GUYhH1A27WOHw5cTFSFPMo9EeUIGnQTZHIaJ7AHLaOKsOODaNF9jkBjYG2QEsQ2xjMUAx2bBEbeTBWMHwskBjngq56S/yfgkBnWBa4K9sqKtq2t1UI8S9He5XuBRbawAdatrQEAi30Aks2+LM8WeCbalVZkWNylvJ+dqJnzVb+OHlSoKW8nPCP7Rd+CcZ2DdWAGqJ2CBFOphgywFFCFBNtfAbGtNPBCwxvygHeYMZMY9ZboBqwq/pVrsbgN5tkv152ODlbMfiqwGMBgxa4Exz3QhovRIUp6acqZmQzRq0ypDXS2TPLT02YIkQETnOE445oOGxOmXAqUJNNG7XgupMjPq2ua9asrj5yY/yuKteO1Kx0YNJTufrirLe1mZnat7OL6rnUdCWenpW6I8mAnbsY8KWs1PuSovCW9A/Z25PQ24a7cNOqgmTkLmBMgh4THgc4b9k2IVv1/g/F5nGljwPLfOgHAzJzh45V/4+WenTzmMtR5Z7us2Tys909UHqrPY7KbckoxRvRHhmVc3cJGE97uml0R1S0jdULVl7EvZtDFVBF35N9cEdjpgmAiOlFZ+Dtoh93+D3zzHr8RRNZQhnCNMNbcegOvpEwZoL+06cJQ07h+th3fZ/7PVbVC6ngTAV/KoLFuO6+2KFcU651gEb5ugPSIb1D+Xp8V4+k3sEIGnw5mYe4If4k1lFYr6SCzmM2EQ8iWtmwjnBI9kTwe1TlfAmXh7H02by9fW2gsjKwtv0aaURKil4OdV7rDL1MXIFNrhdxohcZXYTnq47WisrKitaObbf5+yvkLi5J6lCNZZ+B6GC38VNBZBDidSS/+mSvh6s+srgC8pyKMvDtt+de3c9fU76ZPfuM8ud4Kv0fyP/LqfepMT/3oZxSqpZaTa1DaQYLY8TFsHYbWYsPoRhRWfL5eSSQbhUGgGC3YLbVMk6PitTFNGpAsNrC6D1VNBKgBHMejaiuRWEWGgsSDBTJjqWIl8kJLlsaLJ2tXDr6xGfT85bM2Q06a46x2HTgvdnV8z5YDy/27J4zt6x2VtkzjoYpkq36kaBr4eQSg7tyiVweWubXZugtadl58ydapfbORfKsDTuZ0OBgx4cfdjCf5tbWNITnL120fdOi1RV1C3uKGzNdwYLcMvZ3BxoPyTOCD1XvXTp7U10gWCVmTV9b3r2z0SkGWovb2hp9I89O8a2smlyaO8muMU+dRmtzp60IzAoFpjLr1n388boLyf0dRvxhsHZ0qbWqDkwqvvpkj4l0fY6EIXRi5sQSrAvsVYwXRy4qJ2EVtD1AN7a0HWth9ymvL1xc3WTUKK/TAHA/bXDVtVWfOMfuGxGZv4Ln/jVr9jc3j1yMv0tndmyt9Vq88Y9gH1wtLX3KWjot5++jWHgAoZZkQ14wGQ20Fli71UmKJAy4xKMSTGbVdybW7FDDAut9XpD5AzWrYO7zQ8qffqF8+Ynd/clrHcdyxGy3a/3+mfNnzC/cBsveTjnTvXf1o6vzOlZw7WtqtdmPK/Errz/6NNtD72zmNOZfbmYdTGHfoofqI79Oc+R2n1lrnL6pOm0Up7kwxhTW12Amm7WYkXR2qYrF2AmgmbAsxZjwy1xpg/m1Je2vrp8v/nz2xpmlBg4E9hrMU341wVpTOh/OfmGvAnra8q6uctr60ZQHV3Q+WMQJykMj8ZsWn2QBOmmHMB+m5pDIpTFonYigiaKAhGEiAHF7EliVnQkjoLVIMPtJpBKHYd3A8GYH9jJzrWwmHx5Qjp7vDAX0suGRym1vtm/9W1/HyR8vczfMs6Sk8DSv855/5dlX9oQq52hT8syyp2rx5Id17IAyAM3wIjQPMOHzytEB64q6D5zT91yNbnx3V/nqnd017S9Y0605k3izoXLpsxde2n38yoOV9s1LcjwzNjbdX6asnBVaBj/6/DwKwPkpcqbDG7BnsXoSqWnUAmottYF6jMSdVyYZh3zVXCjwTiwwHH6sGuRiEHQGzuRX6whZkp123oy1BWE2mEfJ/tvIRtM4ZM5bDXiMsPMaAKOTyc5uL57rqyyc5y5JE5pm1i2S2iUX0CcaQ6lC6Zog7JqSqZmYlosl2K6pwNA84zRnQW6SaALYZQGW5lhCtU/W34N6o+bKfZ8cf3/Cl/+iTX3wBzpOY4mRkeNf3rptycGSshQWgGbYt5jFc2e0+DglIrwl6DVWQ7BuwaJ3Xk1J4VL5urnLl/Wf+gHU/hZoZdKNym6lG+I34FaNeZKcSpJIo2IeCVvpdsDGfKvzJnAwmeD37Ow65ZWwSowpgwX5T69s/rB55dP5BcpgDKFV8p7q2sn/1uc93bVzT/w6UrCqDTWvfCq/oCD/qZXNoUj8BL5Kp6GU017frfNXkAtiiyf/SOCEeLqnd8R/Ql9GlCRfctS6k5chvIBuQ1zCCjoCHL2DHNHIXxMJ3kQeO8lbsUXONeSfA5EjcG6/E+KdhN4bP04vBhdi883+BFBzQbxFbvZzQeY9LNBZc0FNfn5NwfDn6rCTnTw6R8o+gfpf5hCom33cRuiTlss3KHmZjD+BPN+5gXuA2ziS/Q73mLxUkpbKN/eqwz5uK0X9F3h2d1V4nGNgZGBgAOJd776+iue3+crAzc4AAje5Bfcg0xz9YHEOBiYQBQA8FQlFAHicY2BkYGBnAAGOPgaG//85+hkYGVCBMgBGGwNYAAAAeJxjYGBgYB8EmKOPgQEAQ04BfgAAAAAAAA4AaAB+AMwA4AECAUIBbAGYAcICGAJYArQC4AMwA7AD3gQwBJYE3AUkBWYFigYgBmYGtAbqB1gIEghYCG4IhAi2COh4nGNgZGBgUGYoZWBnAAEmIOYCQgaG/2A+AwAYCQG2AHicXZBNaoNAGIZfE5PQCKFQ2lUps2oXBfOzzAESyDKBQJdGR2NQR3QSSE/QE/QEPUUPUHqsvsrXjTMw83zPvPMNCuAWP3DQDAejdm1GjzwS7pMmwi75XngAD4/CQ/oX4TFe4Qt7uMMbOzjuDc0EmXCP/C7cJ38Iu+RP4QEe8CU8pP8WHmOPX2EPz87TPo202ey2OjlnQSXV/6arOjWFmvszMWtd6CqwOlKHq6ovycLaWMWVydXKFFZnmVFlZU46tP7R2nI5ncbi/dDkfDtFBA2DDXbYkhKc+V0Bqs5Zt9JM1HQGBRTm/EezTmZNKtpcAMs9Yu6AK9caF76zoLWIWcfMGOSkVduvSWechqZsz040Ib2PY3urxBJTzriT95lipz+TN1fmAAAAeJxtkMl2wjAMRfOAhABlKm2h80C3+ajgCKKDY6cegP59TYBzukAL+z1Zsq8ctaJTTKPrsUQLbXQQI0EXKXroY4AbDDHCGBNMcYsZ7nCPB8yxwCOe8IwXvOIN7/jAJ76wxHfUqWX+OzgumWAjJMV17i0Ndlr6irLKO+qftdT7i6y4uFSUvCknay+lFYZIZaQcmfH/xIFdYn98bqhra1aKTM/6lWMnyaYirx1rFUQZFBkb2zJUtoXeJCeg0WnLtHeSFc3OtrnozNwqi0TkSpBMDB1nSde5oJXW23hTS2/T0LilglXX7dmFVxLnq5U0vYATHFk3zX3BOisoQHNDFDeZnqKDy9hRNawN7Vh727hFzcJ5c8TILrKZfH7tIPxAFP0BpLeJPA==) format("woff");font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder,.vjs-icon-play{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-big-play-button .vjs-icon-placeholder:before,.video-js .vjs-play-control .vjs-icon-placeholder:before,.vjs-icon-play:before{content:"\f101"}.vjs-icon-play-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-play-circle:before{content:"\f102"}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder,.vjs-icon-pause{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder:before,.vjs-icon-pause:before{content:"\f103"}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder,.vjs-icon-volume-mute{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-0 .vjs-icon-placeholder:before,.vjs-icon-volume-mute:before{content:"\f104"}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder,.vjs-icon-volume-low{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-1 .vjs-icon-placeholder:before,.vjs-icon-volume-low:before{content:"\f105"}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder,.vjs-icon-volume-mid{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control.vjs-vol-2 .vjs-icon-placeholder:before,.vjs-icon-volume-mid:before{content:"\f106"}.video-js .vjs-mute-control .vjs-icon-placeholder,.vjs-icon-volume-high{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-mute-control .vjs-icon-placeholder:before,.vjs-icon-volume-high:before{content:"\f107"}.video-js .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-enter:before{content:"\f108"}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder,.vjs-icon-fullscreen-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-fullscreen .vjs-fullscreen-control .vjs-icon-placeholder:before,.vjs-icon-fullscreen-exit:before{content:"\f109"}.vjs-icon-square{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-square:before{content:"\f10a"}.vjs-icon-spinner{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-spinner:before{content:"\f10b"}.video-js .vjs-subs-caps-button .vjs-icon-placeholder,.video-js .vjs-subtitles-button .vjs-icon-placeholder,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-subtitles{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js .vjs-subtitles-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-AU) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-GB) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-IE) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js.video-js:lang(en-NZ) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-subtitles:before{content:"\f10c"}.video-js .vjs-captions-button .vjs-icon-placeholder,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder,.vjs-icon-captions{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-captions-button .vjs-icon-placeholder:before,.video-js:lang(en) .vjs-subs-caps-button .vjs-icon-placeholder:before,.video-js:lang(fr-CA) .vjs-subs-caps-button .vjs-icon-placeholder:before,.vjs-icon-captions:before{content:"\f10d"}.video-js .vjs-chapters-button .vjs-icon-placeholder,.vjs-icon-chapters{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-chapters-button .vjs-icon-placeholder:before,.vjs-icon-chapters:before{content:"\f10e"}.vjs-icon-share{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-share:before{content:"\f10f"}.vjs-icon-cog{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-cog:before{content:"\f110"}.video-js .vjs-play-progress,.video-js .vjs-volume-level,.vjs-icon-circle,.vjs-seek-to-live-control .vjs-icon-placeholder{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-progress:before,.video-js .vjs-volume-level:before,.vjs-icon-circle:before,.vjs-seek-to-live-control .vjs-icon-placeholder:before{content:"\f111"}.vjs-icon-circle-outline{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-outline:before{content:"\f112"}.vjs-icon-circle-inner-circle{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-circle-inner-circle:before{content:"\f113"}.vjs-icon-hd{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-hd:before{content:"\f114"}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder,.vjs-icon-cancel{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-control.vjs-close-button .vjs-icon-placeholder:before,.vjs-icon-cancel:before{content:"\f115"}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder,.vjs-icon-replay{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-play-control.vjs-ended .vjs-icon-placeholder:before,.vjs-icon-replay:before{content:"\f116"}.vjs-icon-facebook{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-facebook:before{content:"\f117"}.vjs-icon-gplus{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-gplus:before{content:"\f118"}.vjs-icon-linkedin{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-linkedin:before{content:"\f119"}.vjs-icon-twitter{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-twitter:before{content:"\f11a"}.vjs-icon-tumblr{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-tumblr:before{content:"\f11b"}.vjs-icon-pinterest{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-pinterest:before{content:"\f11c"}.video-js .vjs-descriptions-button .vjs-icon-placeholder,.vjs-icon-audio-description{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-descriptions-button .vjs-icon-placeholder:before,.vjs-icon-audio-description:before{content:"\f11d"}.video-js .vjs-audio-button .vjs-icon-placeholder,.vjs-icon-audio{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-audio-button .vjs-icon-placeholder:before,.vjs-icon-audio:before{content:"\f11e"}.vjs-icon-next-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-next-item:before{content:"\f11f"}.vjs-icon-previous-item{font-family:VideoJS;font-weight:400;font-style:normal}.vjs-icon-previous-item:before{content:"\f120"}.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder,.vjs-icon-picture-in-picture-enter{font-family:VideoJS;font-weight:400;font-style:normal}.video-js .vjs-picture-in-picture-control .vjs-icon-placeholder:before,.vjs-icon-picture-in-picture-enter:before{content:"\f121"}.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder,.vjs-icon-picture-in-picture-exit{font-family:VideoJS;font-weight:400;font-style:normal}.video-js.vjs-picture-in-picture .vjs-picture-in-picture-control .vjs-icon-placeholder:before,.vjs-icon-picture-in-picture-exit:before{content:"\f122"}.video-js{display:block;vertical-align:top;box-sizing:border-box;color:#fff;background-color:#000;position:relative;padding:0;font-size:10px;line-height:1;font-weight:400;font-style:normal;font-family:Arial,Helvetica,sans-serif;word-break:initial}.video-js:-moz-full-screen{position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.video-js[tabindex="-1"]{outline:0}.video-js *,.video-js :after,.video-js :before{box-sizing:inherit}.video-js ul{font-family:inherit;font-size:inherit;line-height:inherit;list-style-position:outside;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}.video-js.vjs-1-1,.video-js.vjs-16-9,.video-js.vjs-4-3,.video-js.vjs-9-16,.video-js.vjs-fluid{width:100%;max-width:100%;height:0}.video-js.vjs-16-9{padding-top:56.25%}.video-js.vjs-4-3{padding-top:75%}.video-js.vjs-9-16{padding-top:177.7777777778%}.video-js.vjs-1-1{padding-top:100%}.video-js.vjs-fill{width:100%;height:100%}.video-js .vjs-tech{position:absolute;top:0;left:0;width:100%;height:100%}body.vjs-full-window{padding:0;margin:0;height:100%}.vjs-full-window .video-js.vjs-fullscreen{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0}.video-js.vjs-fullscreen:not(.vjs-ios-native-fs){width:100%!important;height:100%!important;padding-top:0!important}.video-js.vjs-fullscreen.vjs-user-inactive{cursor:none}.vjs-hidden{display:none!important}.vjs-disabled{opacity:.5;cursor:default}.video-js .vjs-offscreen{height:1px;left:-9999px;position:absolute;top:0;width:1px}.vjs-lock-showing{display:block!important;opacity:1!important;visibility:visible!important}.vjs-no-js{padding:20px;color:#fff;background-color:#000;font-size:18px;font-family:Arial,Helvetica,sans-serif;text-align:center;width:300px;height:150px;margin:0 auto}.vjs-no-js a,.vjs-no-js a:visited{color:#66a8cc}.video-js .vjs-big-play-button{font-size:3em;line-height:1.5em;height:1.63332em;width:3em;display:block;position:absolute;top:10px;left:10px;padding:0;cursor:pointer;opacity:1;border:.06666em solid #fff;background-color:#2b333f;background-color:rgba(43,51,63,.7);border-radius:.3em;transition:all .4s}.vjs-big-play-centered .vjs-big-play-button{top:50%;left:50%;margin-top:-.81666em;margin-left:-1.5em}.video-js .vjs-big-play-button:focus,.video-js:hover .vjs-big-play-button{border-color:#fff;background-color:#73859f;background-color:rgba(115,133,159,.5);transition:all 0s}.vjs-controls-disabled .vjs-big-play-button,.vjs-error .vjs-big-play-button,.vjs-has-started .vjs-big-play-button,.vjs-using-native-controls .vjs-big-play-button{display:none}.vjs-has-started.vjs-paused.vjs-show-big-play-button-on-pause .vjs-big-play-button{display:block}.video-js button{background:0 0;border:none;color:inherit;display:inline-block;font-size:inherit;line-height:inherit;text-transform:none;text-decoration:none;transition:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.vjs-control .vjs-button{width:100%;height:100%}.video-js .vjs-control.vjs-close-button{cursor:pointer;height:3em;position:absolute;right:0;top:.5em;z-index:2}.video-js .vjs-modal-dialog{background:rgba(0,0,0,.8);background:linear-gradient(180deg,rgba(0,0,0,.8),rgba(255,255,255,0));overflow:auto}.video-js .vjs-modal-dialog>*{box-sizing:border-box}.vjs-modal-dialog .vjs-modal-dialog-content{font-size:1.2em;line-height:1.5;padding:20px 24px;z-index:1}.vjs-menu-button{cursor:pointer}.vjs-menu-button.vjs-disabled{cursor:default}.vjs-workinghover .vjs-menu-button.vjs-disabled:hover .vjs-menu{display:none}.vjs-menu .vjs-menu-content{display:block;padding:0;margin:0;font-family:Arial,Helvetica,sans-serif;overflow:auto}.vjs-menu .vjs-menu-content>*{box-sizing:border-box}.vjs-scrubbing .vjs-control.vjs-menu-button:hover .vjs-menu{display:none}.vjs-menu li{list-style:none;margin:0;padding:.2em 0;line-height:1.4em;font-size:1.2em;text-align:center;text-transform:lowercase}.js-focus-visible .vjs-menu li.vjs-menu-item:hover,.vjs-menu li.vjs-menu-item:focus,.vjs-menu li.vjs-menu-item:hover{background-color:#73859f;background-color:rgba(115,133,159,.5)}.js-focus-visible .vjs-menu li.vjs-selected:hover,.vjs-menu li.vjs-selected,.vjs-menu li.vjs-selected:focus,.vjs-menu li.vjs-selected:hover{background-color:#fff;color:#2b333f}.js-focus-visible .vjs-menu :not(.vjs-selected):focus:not(.focus-visible),.video-js .vjs-menu :not(.vjs-selected):focus:not(:focus-visible){background:0 0}.vjs-menu li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em 0;font-weight:700;cursor:default}.vjs-menu-button-popup .vjs-menu{display:none;position:absolute;bottom:0;width:10em;left:-3em;height:0;margin-bottom:1.5em;border-top-color:rgba(43,51,63,.7)}.vjs-menu-button-popup .vjs-menu .vjs-menu-content{background-color:#2b333f;background-color:rgba(43,51,63,.7);position:absolute;width:100%;bottom:1.5em;max-height:15em}.vjs-layout-tiny .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-x-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:5em}.vjs-layout-small .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:10em}.vjs-layout-medium .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:14em}.vjs-layout-huge .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content,.vjs-layout-x-large .vjs-menu-button-popup .vjs-menu .vjs-menu-content{max-height:25em}.vjs-menu-button-popup .vjs-menu.vjs-lock-showing,.vjs-workinghover .vjs-menu-button-popup.vjs-hover .vjs-menu{display:block}.video-js .vjs-menu-button-inline{transition:all .4s;overflow:hidden}.video-js .vjs-menu-button-inline:before{width:2.222222222em}.video-js .vjs-menu-button-inline.vjs-slider-active,.video-js .vjs-menu-button-inline:focus,.video-js .vjs-menu-button-inline:hover,.video-js.vjs-no-flex .vjs-menu-button-inline{width:12em}.vjs-menu-button-inline .vjs-menu{opacity:0;height:100%;width:auto;position:absolute;left:4em;top:0;padding:0;margin:0;transition:all .4s}.vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-menu-button-inline:focus .vjs-menu,.vjs-menu-button-inline:hover .vjs-menu{display:block;opacity:1}.vjs-no-flex .vjs-menu-button-inline .vjs-menu{display:block;opacity:1;position:relative;width:auto}.vjs-no-flex .vjs-menu-button-inline.vjs-slider-active .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:focus .vjs-menu,.vjs-no-flex .vjs-menu-button-inline:hover .vjs-menu{width:auto}.vjs-menu-button-inline .vjs-menu-content{width:auto;height:100%;margin:0;overflow:hidden}.video-js .vjs-control-bar{display:none;width:100%;position:absolute;bottom:0;left:0;right:0;height:3em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.vjs-has-started .vjs-control-bar{display:flex;visibility:visible;opacity:1;transition:visibility .1s,opacity .1s}.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{visibility:visible;opacity:0;pointer-events:none;transition:visibility 1s,opacity 1s}.vjs-controls-disabled .vjs-control-bar,.vjs-error .vjs-control-bar,.vjs-using-native-controls .vjs-control-bar{display:none!important}.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{opacity:1;visibility:visible}.vjs-has-started.vjs-no-flex .vjs-control-bar{display:table}.video-js .vjs-control{position:relative;text-align:center;margin:0;padding:0;height:100%;width:4em;flex:none}.vjs-button>.vjs-icon-placeholder:before{font-size:1.8em;line-height:1.67}.vjs-button>.vjs-icon-placeholder{display:block}.video-js .vjs-control:focus,.video-js .vjs-control:focus:before,.video-js .vjs-control:hover:before{text-shadow:0 0 1em #fff}.video-js .vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.vjs-no-flex .vjs-control{display:table-cell;vertical-align:middle}.video-js .vjs-custom-control-spacer{display:none}.video-js .vjs-progress-control{cursor:pointer;flex:auto;display:flex;align-items:center;min-width:4em;touch-action:none}.video-js .vjs-progress-control.disabled{cursor:default}.vjs-live .vjs-progress-control{display:none}.vjs-liveui .vjs-progress-control{display:flex;align-items:center}.vjs-no-flex .vjs-progress-control{width:auto}.video-js .vjs-progress-holder{flex:auto;transition:all .2s;height:.3em}.video-js .vjs-progress-control .vjs-progress-holder{margin:0 10px}.video-js .vjs-progress-control:hover .vjs-progress-holder{font-size:1.6666666667em}.video-js .vjs-progress-control:hover .vjs-progress-holder.disabled{font-size:1em}.video-js .vjs-progress-holder .vjs-load-progress,.video-js .vjs-progress-holder .vjs-load-progress div,.video-js .vjs-progress-holder .vjs-play-progress{position:absolute;display:block;height:100%;margin:0;padding:0;width:0}.video-js .vjs-play-progress{background-color:#fff}.video-js .vjs-play-progress:before{font-size:.9em;position:absolute;right:-.5em;top:-.3333333333em;z-index:1}.video-js .vjs-load-progress{background:rgba(115,133,159,.5)}.video-js .vjs-load-progress div{background:rgba(115,133,159,.75)}.video-js .vjs-time-tooltip{background-color:#fff;background-color:rgba(255,255,255,.8);border-radius:.3em;color:#000;float:right;font-family:Arial,Helvetica,sans-serif;font-size:1em;padding:6px 8px 8px 8px;pointer-events:none;position:absolute;top:-3.4em;visibility:hidden;z-index:1}.video-js .vjs-progress-holder:focus .vjs-time-tooltip{display:none}.video-js .vjs-progress-control:hover .vjs-progress-holder:focus .vjs-time-tooltip,.video-js .vjs-progress-control:hover .vjs-time-tooltip{display:block;font-size:.6em;visibility:visible}.video-js .vjs-progress-control.disabled:hover .vjs-time-tooltip{font-size:1em}.video-js .vjs-progress-control .vjs-mouse-display{display:none;position:absolute;width:1px;height:100%;background-color:#000;z-index:1}.vjs-no-flex .vjs-progress-control .vjs-mouse-display{z-index:0}.video-js .vjs-progress-control:hover .vjs-mouse-display{display:block}.video-js.vjs-user-inactive .vjs-progress-control .vjs-mouse-display{visibility:hidden;opacity:0;transition:visibility 1s,opacity 1s}.video-js.vjs-user-inactive.vjs-no-flex .vjs-progress-control .vjs-mouse-display{display:none}.vjs-mouse-display .vjs-time-tooltip{color:#fff;background-color:#000;background-color:rgba(0,0,0,.8)}.video-js .vjs-slider{position:relative;cursor:pointer;padding:0;margin:0 .45em 0 .45em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#73859f;background-color:rgba(115,133,159,.5)}.video-js .vjs-slider.disabled{cursor:default}.video-js .vjs-slider:focus{text-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.video-js .vjs-mute-control{cursor:pointer;flex:none}.video-js .vjs-volume-control{cursor:pointer;margin-right:1em;display:flex}.video-js .vjs-volume-control.vjs-volume-horizontal{width:5em}.video-js .vjs-volume-panel .vjs-volume-control{visibility:visible;opacity:0;width:1px;height:1px;margin-left:-1px}.video-js .vjs-volume-panel{transition:width 1s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active,.video-js .vjs-volume-panel .vjs-volume-control:active,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control,.video-js .vjs-volume-panel:active .vjs-volume-control,.video-js .vjs-volume-panel:focus .vjs-volume-control{visibility:visible;opacity:1;position:relative;transition:visibility .1s,opacity .1s,height .1s,width .1s,left 0s,top 0s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-horizontal,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-horizontal,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em;margin-right:0}.video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-vertical,.video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-vertical,.video-js .vjs-volume-panel.vjs-hover .vjs-mute-control~.vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-vertical,.video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-vertical{left:-3.5em;transition:left 0s}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js .vjs-volume-panel.vjs-volume-panel-horizontal:active{width:10em;transition:width .1s}.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-mute-toggle-only{width:4em}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{height:8em;width:3em;left:-3000em;transition:visibility 1s,opacity 1s,height 1s 1s,width 1s 1s,left 1s 1s,top 1s 1s}.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{transition:visibility 1s,opacity 1s,height 1s 1s,width 1s,left 1s 1s,top 1s 1s}.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal{width:5em;height:3em;visibility:visible;opacity:1;position:relative;transition:none}.video-js.vjs-no-flex .vjs-volume-control.vjs-volume-vertical,.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical{position:absolute;bottom:3em;left:.5em}.video-js .vjs-volume-panel{display:flex}.video-js .vjs-volume-bar{margin:1.35em .45em}.vjs-volume-bar.vjs-slider-horizontal{width:5em;height:.3em}.vjs-volume-bar.vjs-slider-vertical{width:.3em;height:5em;margin:1.35em auto}.video-js .vjs-volume-level{position:absolute;bottom:0;left:0;background-color:#fff}.video-js .vjs-volume-level:before{position:absolute;font-size:.9em;z-index:1}.vjs-slider-vertical .vjs-volume-level{width:.3em}.vjs-slider-vertical .vjs-volume-level:before{top:-.5em;left:-.3em;z-index:1}.vjs-slider-horizontal .vjs-volume-level{height:.3em}.vjs-slider-horizontal .vjs-volume-level:before{top:-.3em;right:-.5em}.video-js .vjs-volume-panel.vjs-volume-panel-vertical{width:4em}.vjs-volume-bar.vjs-slider-vertical .vjs-volume-level{height:100%}.vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level{width:100%}.video-js .vjs-volume-vertical{width:3em;height:8em;bottom:8em;background-color:#2b333f;background-color:rgba(43,51,63,.7)}.video-js .vjs-volume-horizontal .vjs-menu{left:-2em}.video-js .vjs-volume-tooltip{background-color:#fff;background-color:rgba(255,255,255,.8);border-radius:.3em;color:#000;float:right;font-family:Arial,Helvetica,sans-serif;font-size:1em;padding:6px 8px 8px 8px;pointer-events:none;position:absolute;top:-3.4em;visibility:hidden;z-index:1}.video-js .vjs-volume-control:hover .vjs-progress-holder:focus .vjs-volume-tooltip,.video-js .vjs-volume-control:hover .vjs-volume-tooltip{display:block;font-size:1em;visibility:visible}.video-js .vjs-volume-vertical:hover .vjs-progress-holder:focus .vjs-volume-tooltip,.video-js .vjs-volume-vertical:hover .vjs-volume-tooltip{left:1em;top:-12px}.video-js .vjs-volume-control.disabled:hover .vjs-volume-tooltip{font-size:1em}.video-js .vjs-volume-control .vjs-mouse-display{display:none;position:absolute;width:100%;height:1px;background-color:#000;z-index:1}.video-js .vjs-volume-horizontal .vjs-mouse-display{width:1px;height:100%}.vjs-no-flex .vjs-volume-control .vjs-mouse-display{z-index:0}.video-js .vjs-volume-control:hover .vjs-mouse-display{display:block}.video-js.vjs-user-inactive .vjs-volume-control .vjs-mouse-display{visibility:hidden;opacity:0;transition:visibility 1s,opacity 1s}.video-js.vjs-user-inactive.vjs-no-flex .vjs-volume-control .vjs-mouse-display{display:none}.vjs-mouse-display .vjs-volume-tooltip{color:#fff;background-color:#000;background-color:rgba(0,0,0,.8)}.vjs-poster{display:inline-block;vertical-align:middle;background-repeat:no-repeat;background-position:50% 50%;background-size:contain;background-color:#000;cursor:pointer;margin:0;padding:0;position:absolute;top:0;right:0;bottom:0;left:0;height:100%}.vjs-has-started .vjs-poster{display:none}.vjs-audio.vjs-has-started .vjs-poster{display:block}.vjs-using-native-controls .vjs-poster{display:none}.video-js .vjs-live-control{display:flex;align-items:flex-start;flex:auto;font-size:1em;line-height:3em}.vjs-no-flex .vjs-live-control{display:table-cell;width:auto;text-align:left}.video-js.vjs-liveui .vjs-live-control,.video-js:not(.vjs-live) .vjs-live-control{display:none}.video-js .vjs-seek-to-live-control{align-items:center;cursor:pointer;flex:none;display:inline-flex;height:100%;padding-left:.5em;padding-right:.5em;font-size:1em;line-height:3em;width:auto;min-width:4em}.vjs-no-flex .vjs-seek-to-live-control{display:table-cell;width:auto;text-align:left}.video-js.vjs-live:not(.vjs-liveui) .vjs-seek-to-live-control,.video-js:not(.vjs-live) .vjs-seek-to-live-control{display:none}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge{cursor:auto}.vjs-seek-to-live-control .vjs-icon-placeholder{margin-right:.5em;color:#888}.vjs-seek-to-live-control.vjs-control.vjs-at-live-edge .vjs-icon-placeholder{color:red}.video-js .vjs-time-control{flex:none;font-size:1em;line-height:3em;min-width:2em;width:auto;padding-left:1em;padding-right:1em}.vjs-live .vjs-time-control{display:none}.video-js .vjs-current-time,.vjs-no-flex .vjs-current-time{display:none}.video-js .vjs-duration,.vjs-no-flex .vjs-duration{display:none}.vjs-time-divider{display:none;line-height:3em}.vjs-live .vjs-time-divider{display:none}.video-js .vjs-play-control{cursor:pointer}.video-js .vjs-play-control .vjs-icon-placeholder{flex:none}.vjs-text-track-display{position:absolute;bottom:3em;left:0;right:0;top:0;pointer-events:none}.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display{bottom:1em}.video-js .vjs-text-track{font-size:1.4em;text-align:center;margin-bottom:.1em}.vjs-subtitles{color:#fff}.vjs-captions{color:#fc6}.vjs-tt-cue{display:block}video::-webkit-media-text-track-display{transform:translateY(-3em)}.video-js.vjs-user-inactive.vjs-playing video::-webkit-media-text-track-display{transform:translateY(-1.5em)}.video-js .vjs-picture-in-picture-control{cursor:pointer;flex:none}.video-js .vjs-fullscreen-control{cursor:pointer;flex:none}.vjs-playback-rate .vjs-playback-rate-value,.vjs-playback-rate>.vjs-menu-button{position:absolute;top:0;left:0;width:100%;height:100%}.vjs-playback-rate .vjs-playback-rate-value{pointer-events:none;font-size:1.5em;line-height:2;text-align:center}.vjs-playback-rate .vjs-menu{width:4em;left:0}.vjs-error .vjs-error-display .vjs-modal-dialog-content{font-size:1.4em;text-align:center}.vjs-error .vjs-error-display:before{color:#fff;content:"X";font-family:Arial,Helvetica,sans-serif;font-size:4em;left:0;line-height:1;margin-top:-.5em;position:absolute;text-shadow:.05em .05em .1em #000;text-align:center;top:50%;vertical-align:middle;width:100%}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;margin:-25px 0 0 -25px;opacity:.85;text-align:left;border:6px solid rgba(43,51,63,.7);box-sizing:border-box;background-clip:padding-box;width:50px;height:50px;border-radius:25px;visibility:hidden}.vjs-seeking .vjs-loading-spinner,.vjs-waiting .vjs-loading-spinner{display:block;-webkit-animation:vjs-spinner-show 0s linear .3s forwards;animation:vjs-spinner-show 0s linear .3s forwards}.vjs-loading-spinner:after,.vjs-loading-spinner:before{content:"";position:absolute;margin:-6px;box-sizing:inherit;width:inherit;height:inherit;border-radius:inherit;opacity:1;border:inherit;border-color:transparent;border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:before{-webkit-animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite;animation:vjs-spinner-spin 1.1s cubic-bezier(.6,.2,0,.8) infinite,vjs-spinner-fade 1.1s linear infinite}.vjs-seeking .vjs-loading-spinner:before,.vjs-waiting .vjs-loading-spinner:before{border-top-color:#fff}.vjs-seeking .vjs-loading-spinner:after,.vjs-waiting .vjs-loading-spinner:after{border-top-color:#fff;-webkit-animation-delay:.44s;animation-delay:.44s}@keyframes vjs-spinner-show{to{visibility:visible}}@-webkit-keyframes vjs-spinner-show{to{visibility:visible}}@keyframes vjs-spinner-spin{100%{transform:rotate(360deg)}}@-webkit-keyframes vjs-spinner-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}@-webkit-keyframes vjs-spinner-fade{0%{border-top-color:#73859f}20%{border-top-color:#73859f}35%{border-top-color:#fff}60%{border-top-color:#73859f}100%{border-top-color:#73859f}}.vjs-chapters-button .vjs-menu ul{width:24em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-subs-caps-button+.vjs-menu .vjs-captions-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:"";font-size:1.5em;line-height:inherit}.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder{vertical-align:middle;display:inline-block;margin-bottom:-.1em}.video-js .vjs-audio-button+.vjs-menu .vjs-main-desc-menu-item .vjs-menu-item-text .vjs-icon-placeholder:before{font-family:VideoJS;content:" ";font-size:1.5em;line-height:inherit}.video-js.vjs-layout-small .vjs-audio-button,.video-js.vjs-layout-small .vjs-captions-button,.video-js.vjs-layout-small .vjs-chapters-button,.video-js.vjs-layout-small .vjs-current-time,.video-js.vjs-layout-small .vjs-descriptions-button,.video-js.vjs-layout-small .vjs-duration,.video-js.vjs-layout-small .vjs-playback-rate,.video-js.vjs-layout-small .vjs-remaining-time,.video-js.vjs-layout-small .vjs-subtitles-button,.video-js.vjs-layout-small .vjs-time-divider,.video-js.vjs-layout-small .vjs-volume-control,.video-js.vjs-layout-tiny .vjs-audio-button,.video-js.vjs-layout-tiny .vjs-captions-button,.video-js.vjs-layout-tiny .vjs-chapters-button,.video-js.vjs-layout-tiny .vjs-current-time,.video-js.vjs-layout-tiny .vjs-descriptions-button,.video-js.vjs-layout-tiny .vjs-duration,.video-js.vjs-layout-tiny .vjs-playback-rate,.video-js.vjs-layout-tiny .vjs-remaining-time,.video-js.vjs-layout-tiny .vjs-subtitles-button,.video-js.vjs-layout-tiny .vjs-time-divider,.video-js.vjs-layout-tiny .vjs-volume-control,.video-js.vjs-layout-x-small .vjs-audio-button,.video-js.vjs-layout-x-small .vjs-captions-button,.video-js.vjs-layout-x-small .vjs-chapters-button,.video-js.vjs-layout-x-small .vjs-current-time,.video-js.vjs-layout-x-small .vjs-descriptions-button,.video-js.vjs-layout-x-small .vjs-duration,.video-js.vjs-layout-x-small .vjs-playback-rate,.video-js.vjs-layout-x-small .vjs-remaining-time,.video-js.vjs-layout-x-small .vjs-subtitles-button,.video-js.vjs-layout-x-small .vjs-time-divider,.video-js.vjs-layout-x-small .vjs-volume-control{display:none!important}.video-js.vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js.vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js.vjs-layout-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.video-js.vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js.vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js.vjs-layout-tiny .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.video-js.vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.video-js.vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:active,.video-js.vjs-layout-x-small .vjs-volume-panel.vjs-volume-panel-horizontal:hover{width:auto;width:initial}.video-js.vjs-layout-tiny .vjs-subs-caps-button,.video-js.vjs-layout-x-small:not(.vjs-live) .vjs-subs-caps-button,.video-js.vjs-layout-x-small:not(.vjs-liveui) .vjs-subs-caps-button{display:none}.video-js.vjs-layout-tiny .vjs-custom-control-spacer,.video-js.vjs-layout-x-small.vjs-liveui .vjs-custom-control-spacer{flex:auto;display:block}.video-js.vjs-layout-tiny.vjs-no-flex .vjs-custom-control-spacer,.video-js.vjs-layout-x-small.vjs-liveui.vjs-no-flex .vjs-custom-control-spacer{width:auto}.video-js.vjs-layout-tiny .vjs-progress-control,.video-js.vjs-layout-x-small.vjs-liveui .vjs-progress-control{display:none}.vjs-modal-dialog.vjs-text-track-settings{background-color:#2b333f;background-color:rgba(43,51,63,.75);color:#fff;height:70%}.vjs-text-track-settings .vjs-modal-dialog-content{display:table}.vjs-text-track-settings .vjs-track-settings-colors,.vjs-text-track-settings .vjs-track-settings-controls,.vjs-text-track-settings .vjs-track-settings-font{display:table-cell}.vjs-text-track-settings .vjs-track-settings-controls{text-align:right;vertical-align:bottom}@supports (display:grid){.vjs-text-track-settings .vjs-modal-dialog-content{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr;padding:20px 24px 0 24px}.vjs-track-settings-controls .vjs-default-button{margin-bottom:20px}.vjs-text-track-settings .vjs-track-settings-controls{grid-column:1/-1}.vjs-layout-small .vjs-text-track-settings .vjs-modal-dialog-content,.vjs-layout-tiny .vjs-text-track-settings .vjs-modal-dialog-content,.vjs-layout-x-small .vjs-text-track-settings .vjs-modal-dialog-content{grid-template-columns:1fr}}.vjs-track-setting>select{margin-right:1em;margin-bottom:.5em}.vjs-text-track-settings fieldset{margin:5px;padding:3px;border:none}.vjs-text-track-settings fieldset span{display:inline-block}.vjs-text-track-settings fieldset span>select{max-width:7.3em}.vjs-text-track-settings legend{color:#fff;margin:0 0 5px 0}.vjs-text-track-settings .vjs-label{position:absolute;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);display:block;margin:0 0 5px 0;padding:0;border:0;height:1px;width:1px;overflow:hidden}.vjs-track-settings-controls button:active,.vjs-track-settings-controls button:focus{outline-style:solid;outline-width:medium;background-image:linear-gradient(0deg,#fff 88%,#73859f 100%)}.vjs-track-settings-controls button:hover{color:rgba(43,51,63,.75)}.vjs-track-settings-controls button{background-color:#fff;background-image:linear-gradient(-180deg,#fff 88%,#73859f 100%);color:#2b333f;cursor:pointer;border-radius:2px}.vjs-track-settings-controls .vjs-default-button{margin-right:1em}@media print{.video-js>:not(.vjs-tech):not(.vjs-poster){visibility:hidden}}.vjs-resize-manager{position:absolute;top:0;left:0;width:100%;height:100%;border:none;z-index:-1000}.js-focus-visible .video-js :focus:not(.focus-visible){outline:0}.video-js :focus:not(:focus-visible){outline:0}
\ No newline at end of file
-@import (inline) "video-js-core.css";
+@import (inline) "video-js.min.css";
/* Video JS skin */
/*
}
/* Fix #4362 */
-.vjs-control-bar{
- transform: translate3d(0,0,0);
+.vjs-control-bar {
+ transform: translate3d(0, 0, 0);
}
/* The default color of control backgrounds is mostly black but with a little