github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/themes/wind/static/libs/video-js-5.9.0/video.js (about)

     1  /**
     2   * @license
     3   * Video.js 5.9.0 <http://videojs.com/>
     4   * Copyright Brightcove, Inc. <https://www.brightcove.com/>
     5   * Available under Apache License Version 2.0
     6   * <https://github.com/videojs/video.js/blob/master/LICENSE>
     7   *
     8   * Includes vtt.js <https://github.com/mozilla/vtt.js>
     9   * Available under Apache License Version 2.0
    10   * <https://github.com/mozilla/vtt.js/blob/master/LICENSE>
    11   */
    12  
    13  (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.videojs = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
    14  (function (global){
    15  var topLevel = typeof global !== 'undefined' ? global :
    16      typeof window !== 'undefined' ? window : {}
    17  var minDoc = _dereq_('min-document');
    18  
    19  if (typeof document !== 'undefined') {
    20      module.exports = document;
    21  } else {
    22      var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];
    23  
    24      if (!doccy) {
    25          doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;
    26      }
    27  
    28      module.exports = doccy;
    29  }
    30  
    31  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    32  //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9nbG9iYWwvZG9jdW1lbnQuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgdG9wTGV2ZWwgPSB0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbCA6XG4gICAgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB7fVxudmFyIG1pbkRvYyA9IHJlcXVpcmUoJ21pbi1kb2N1bWVudCcpO1xuXG5pZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZG9jdW1lbnQ7XG59IGVsc2Uge1xuICAgIHZhciBkb2NjeSA9IHRvcExldmVsWydfX0dMT0JBTF9ET0NVTUVOVF9DQUNIRUA0J107XG5cbiAgICBpZiAoIWRvY2N5KSB7XG4gICAgICAgIGRvY2N5ID0gdG9wTGV2ZWxbJ19fR0xPQkFMX0RPQ1VNRU5UX0NBQ0hFQDQnXSA9IG1pbkRvYztcbiAgICB9XG5cbiAgICBtb2R1bGUuZXhwb3J0cyA9IGRvY2N5O1xufVxuIl19
    33  },{"min-document":3}],2:[function(_dereq_,module,exports){
    34  (function (global){
    35  if (typeof window !== "undefined") {
    36      module.exports = window;
    37  } else if (typeof global !== "undefined") {
    38      module.exports = global;
    39  } else if (typeof self !== "undefined"){
    40      module.exports = self;
    41  } else {
    42      module.exports = {};
    43  }
    44  
    45  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
    46  //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9nbG9iYWwvd2luZG93LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHdpbmRvdztcbn0gZWxzZSBpZiAodHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZ2xvYmFsO1xufSBlbHNlIGlmICh0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIil7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBzZWxmO1xufSBlbHNlIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHt9O1xufVxuIl19
    47  },{}],3:[function(_dereq_,module,exports){
    48  
    49  },{}],4:[function(_dereq_,module,exports){
    50  var getNative = _dereq_('../internal/getNative');
    51  
    52  /* Native method references for those with the same name as other `lodash` methods. */
    53  var nativeNow = getNative(Date, 'now');
    54  
    55  /**
    56   * Gets the number of milliseconds that have elapsed since the Unix epoch
    57   * (1 January 1970 00:00:00 UTC).
    58   *
    59   * @static
    60   * @memberOf _
    61   * @category Date
    62   * @example
    63   *
    64   * _.defer(function(stamp) {
    65   *   console.log(_.now() - stamp);
    66   * }, _.now());
    67   * // => logs the number of milliseconds it took for the deferred function to be invoked
    68   */
    69  var now = nativeNow || function() {
    70    return new Date().getTime();
    71  };
    72  
    73  module.exports = now;
    74  
    75  },{"../internal/getNative":20}],5:[function(_dereq_,module,exports){
    76  var isObject = _dereq_('../lang/isObject'),
    77      now = _dereq_('../date/now');
    78  
    79  /** Used as the `TypeError` message for "Functions" methods. */
    80  var FUNC_ERROR_TEXT = 'Expected a function';
    81  
    82  /* Native method references for those with the same name as other `lodash` methods. */
    83  var nativeMax = Math.max;
    84  
    85  /**
    86   * Creates a debounced function that delays invoking `func` until after `wait`
    87   * milliseconds have elapsed since the last time the debounced function was
    88   * invoked. The debounced function comes with a `cancel` method to cancel
    89   * delayed invocations. Provide an options object to indicate that `func`
    90   * should be invoked on the leading and/or trailing edge of the `wait` timeout.
    91   * Subsequent calls to the debounced function return the result of the last
    92   * `func` invocation.
    93   *
    94   * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
    95   * on the trailing edge of the timeout only if the the debounced function is
    96   * invoked more than once during the `wait` timeout.
    97   *
    98   * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
    99   * for details over the differences between `_.debounce` and `_.throttle`.
   100   *
   101   * @static
   102   * @memberOf _
   103   * @category Function
   104   * @param {Function} func The function to debounce.
   105   * @param {number} [wait=0] The number of milliseconds to delay.
   106   * @param {Object} [options] The options object.
   107   * @param {boolean} [options.leading=false] Specify invoking on the leading
   108   *  edge of the timeout.
   109   * @param {number} [options.maxWait] The maximum time `func` is allowed to be
   110   *  delayed before it's invoked.
   111   * @param {boolean} [options.trailing=true] Specify invoking on the trailing
   112   *  edge of the timeout.
   113   * @returns {Function} Returns the new debounced function.
   114   * @example
   115   *
   116   * // avoid costly calculations while the window size is in flux
   117   * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
   118   *
   119   * // invoke `sendMail` when the click event is fired, debouncing subsequent calls
   120   * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
   121   *   'leading': true,
   122   *   'trailing': false
   123   * }));
   124   *
   125   * // ensure `batchLog` is invoked once after 1 second of debounced calls
   126   * var source = new EventSource('/stream');
   127   * jQuery(source).on('message', _.debounce(batchLog, 250, {
   128   *   'maxWait': 1000
   129   * }));
   130   *
   131   * // cancel a debounced call
   132   * var todoChanges = _.debounce(batchLog, 1000);
   133   * Object.observe(models.todo, todoChanges);
   134   *
   135   * Object.observe(models, function(changes) {
   136   *   if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) {
   137   *     todoChanges.cancel();
   138   *   }
   139   * }, ['delete']);
   140   *
   141   * // ...at some point `models.todo` is changed
   142   * models.todo.completed = true;
   143   *
   144   * // ...before 1 second has passed `models.todo` is deleted
   145   * // which cancels the debounced `todoChanges` call
   146   * delete models.todo;
   147   */
   148  function debounce(func, wait, options) {
   149    var args,
   150        maxTimeoutId,
   151        result,
   152        stamp,
   153        thisArg,
   154        timeoutId,
   155        trailingCall,
   156        lastCalled = 0,
   157        maxWait = false,
   158        trailing = true;
   159  
   160    if (typeof func != 'function') {
   161      throw new TypeError(FUNC_ERROR_TEXT);
   162    }
   163    wait = wait < 0 ? 0 : (+wait || 0);
   164    if (options === true) {
   165      var leading = true;
   166      trailing = false;
   167    } else if (isObject(options)) {
   168      leading = !!options.leading;
   169      maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);
   170      trailing = 'trailing' in options ? !!options.trailing : trailing;
   171    }
   172  
   173    function cancel() {
   174      if (timeoutId) {
   175        clearTimeout(timeoutId);
   176      }
   177      if (maxTimeoutId) {
   178        clearTimeout(maxTimeoutId);
   179      }
   180      lastCalled = 0;
   181      maxTimeoutId = timeoutId = trailingCall = undefined;
   182    }
   183  
   184    function complete(isCalled, id) {
   185      if (id) {
   186        clearTimeout(id);
   187      }
   188      maxTimeoutId = timeoutId = trailingCall = undefined;
   189      if (isCalled) {
   190        lastCalled = now();
   191        result = func.apply(thisArg, args);
   192        if (!timeoutId && !maxTimeoutId) {
   193          args = thisArg = undefined;
   194        }
   195      }
   196    }
   197  
   198    function delayed() {
   199      var remaining = wait - (now() - stamp);
   200      if (remaining <= 0 || remaining > wait) {
   201        complete(trailingCall, maxTimeoutId);
   202      } else {
   203        timeoutId = setTimeout(delayed, remaining);
   204      }
   205    }
   206  
   207    function maxDelayed() {
   208      complete(trailing, timeoutId);
   209    }
   210  
   211    function debounced() {
   212      args = arguments;
   213      stamp = now();
   214      thisArg = this;
   215      trailingCall = trailing && (timeoutId || !leading);
   216  
   217      if (maxWait === false) {
   218        var leadingCall = leading && !timeoutId;
   219      } else {
   220        if (!maxTimeoutId && !leading) {
   221          lastCalled = stamp;
   222        }
   223        var remaining = maxWait - (stamp - lastCalled),
   224            isCalled = remaining <= 0 || remaining > maxWait;
   225  
   226        if (isCalled) {
   227          if (maxTimeoutId) {
   228            maxTimeoutId = clearTimeout(maxTimeoutId);
   229          }
   230          lastCalled = stamp;
   231          result = func.apply(thisArg, args);
   232        }
   233        else if (!maxTimeoutId) {
   234          maxTimeoutId = setTimeout(maxDelayed, remaining);
   235        }
   236      }
   237      if (isCalled && timeoutId) {
   238        timeoutId = clearTimeout(timeoutId);
   239      }
   240      else if (!timeoutId && wait !== maxWait) {
   241        timeoutId = setTimeout(delayed, wait);
   242      }
   243      if (leadingCall) {
   244        isCalled = true;
   245        result = func.apply(thisArg, args);
   246      }
   247      if (isCalled && !timeoutId && !maxTimeoutId) {
   248        args = thisArg = undefined;
   249      }
   250      return result;
   251    }
   252    debounced.cancel = cancel;
   253    return debounced;
   254  }
   255  
   256  module.exports = debounce;
   257  
   258  },{"../date/now":4,"../lang/isObject":33}],6:[function(_dereq_,module,exports){
   259  /** Used as the `TypeError` message for "Functions" methods. */
   260  var FUNC_ERROR_TEXT = 'Expected a function';
   261  
   262  /* Native method references for those with the same name as other `lodash` methods. */
   263  var nativeMax = Math.max;
   264  
   265  /**
   266   * Creates a function that invokes `func` with the `this` binding of the
   267   * created function and arguments from `start` and beyond provided as an array.
   268   *
   269   * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).
   270   *
   271   * @static
   272   * @memberOf _
   273   * @category Function
   274   * @param {Function} func The function to apply a rest parameter to.
   275   * @param {number} [start=func.length-1] The start position of the rest parameter.
   276   * @returns {Function} Returns the new function.
   277   * @example
   278   *
   279   * var say = _.restParam(function(what, names) {
   280   *   return what + ' ' + _.initial(names).join(', ') +
   281   *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
   282   * });
   283   *
   284   * say('hello', 'fred', 'barney', 'pebbles');
   285   * // => 'hello fred, barney, & pebbles'
   286   */
   287  function restParam(func, start) {
   288    if (typeof func != 'function') {
   289      throw new TypeError(FUNC_ERROR_TEXT);
   290    }
   291    start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
   292    return function() {
   293      var args = arguments,
   294          index = -1,
   295          length = nativeMax(args.length - start, 0),
   296          rest = Array(length);
   297  
   298      while (++index < length) {
   299        rest[index] = args[start + index];
   300      }
   301      switch (start) {
   302        case 0: return func.call(this, rest);
   303        case 1: return func.call(this, args[0], rest);
   304        case 2: return func.call(this, args[0], args[1], rest);
   305      }
   306      var otherArgs = Array(start + 1);
   307      index = -1;
   308      while (++index < start) {
   309        otherArgs[index] = args[index];
   310      }
   311      otherArgs[start] = rest;
   312      return func.apply(this, otherArgs);
   313    };
   314  }
   315  
   316  module.exports = restParam;
   317  
   318  },{}],7:[function(_dereq_,module,exports){
   319  var debounce = _dereq_('./debounce'),
   320      isObject = _dereq_('../lang/isObject');
   321  
   322  /** Used as the `TypeError` message for "Functions" methods. */
   323  var FUNC_ERROR_TEXT = 'Expected a function';
   324  
   325  /**
   326   * Creates a throttled function that only invokes `func` at most once per
   327   * every `wait` milliseconds. The throttled function comes with a `cancel`
   328   * method to cancel delayed invocations. Provide an options object to indicate
   329   * that `func` should be invoked on the leading and/or trailing edge of the
   330   * `wait` timeout. Subsequent calls to the throttled function return the
   331   * result of the last `func` call.
   332   *
   333   * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
   334   * on the trailing edge of the timeout only if the the throttled function is
   335   * invoked more than once during the `wait` timeout.
   336   *
   337   * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
   338   * for details over the differences between `_.throttle` and `_.debounce`.
   339   *
   340   * @static
   341   * @memberOf _
   342   * @category Function
   343   * @param {Function} func The function to throttle.
   344   * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
   345   * @param {Object} [options] The options object.
   346   * @param {boolean} [options.leading=true] Specify invoking on the leading
   347   *  edge of the timeout.
   348   * @param {boolean} [options.trailing=true] Specify invoking on the trailing
   349   *  edge of the timeout.
   350   * @returns {Function} Returns the new throttled function.
   351   * @example
   352   *
   353   * // avoid excessively updating the position while scrolling
   354   * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
   355   *
   356   * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes
   357   * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
   358   *   'trailing': false
   359   * }));
   360   *
   361   * // cancel a trailing throttled call
   362   * jQuery(window).on('popstate', throttled.cancel);
   363   */
   364  function throttle(func, wait, options) {
   365    var leading = true,
   366        trailing = true;
   367  
   368    if (typeof func != 'function') {
   369      throw new TypeError(FUNC_ERROR_TEXT);
   370    }
   371    if (options === false) {
   372      leading = false;
   373    } else if (isObject(options)) {
   374      leading = 'leading' in options ? !!options.leading : leading;
   375      trailing = 'trailing' in options ? !!options.trailing : trailing;
   376    }
   377    return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing });
   378  }
   379  
   380  module.exports = throttle;
   381  
   382  },{"../lang/isObject":33,"./debounce":5}],8:[function(_dereq_,module,exports){
   383  /**
   384   * Copies the values of `source` to `array`.
   385   *
   386   * @private
   387   * @param {Array} source The array to copy values from.
   388   * @param {Array} [array=[]] The array to copy values to.
   389   * @returns {Array} Returns `array`.
   390   */
   391  function arrayCopy(source, array) {
   392    var index = -1,
   393        length = source.length;
   394  
   395    array || (array = Array(length));
   396    while (++index < length) {
   397      array[index] = source[index];
   398    }
   399    return array;
   400  }
   401  
   402  module.exports = arrayCopy;
   403  
   404  },{}],9:[function(_dereq_,module,exports){
   405  /**
   406   * A specialized version of `_.forEach` for arrays without support for callback
   407   * shorthands and `this` binding.
   408   *
   409   * @private
   410   * @param {Array} array The array to iterate over.
   411   * @param {Function} iteratee The function invoked per iteration.
   412   * @returns {Array} Returns `array`.
   413   */
   414  function arrayEach(array, iteratee) {
   415    var index = -1,
   416        length = array.length;
   417  
   418    while (++index < length) {
   419      if (iteratee(array[index], index, array) === false) {
   420        break;
   421      }
   422    }
   423    return array;
   424  }
   425  
   426  module.exports = arrayEach;
   427  
   428  },{}],10:[function(_dereq_,module,exports){
   429  /**
   430   * Copies properties of `source` to `object`.
   431   *
   432   * @private
   433   * @param {Object} source The object to copy properties from.
   434   * @param {Array} props The property names to copy.
   435   * @param {Object} [object={}] The object to copy properties to.
   436   * @returns {Object} Returns `object`.
   437   */
   438  function baseCopy(source, props, object) {
   439    object || (object = {});
   440  
   441    var index = -1,
   442        length = props.length;
   443  
   444    while (++index < length) {
   445      var key = props[index];
   446      object[key] = source[key];
   447    }
   448    return object;
   449  }
   450  
   451  module.exports = baseCopy;
   452  
   453  },{}],11:[function(_dereq_,module,exports){
   454  var createBaseFor = _dereq_('./createBaseFor');
   455  
   456  /**
   457   * The base implementation of `baseForIn` and `baseForOwn` which iterates
   458   * over `object` properties returned by `keysFunc` invoking `iteratee` for
   459   * each property. Iteratee functions may exit iteration early by explicitly
   460   * returning `false`.
   461   *
   462   * @private
   463   * @param {Object} object The object to iterate over.
   464   * @param {Function} iteratee The function invoked per iteration.
   465   * @param {Function} keysFunc The function to get the keys of `object`.
   466   * @returns {Object} Returns `object`.
   467   */
   468  var baseFor = createBaseFor();
   469  
   470  module.exports = baseFor;
   471  
   472  },{"./createBaseFor":18}],12:[function(_dereq_,module,exports){
   473  var baseFor = _dereq_('./baseFor'),
   474      keysIn = _dereq_('../object/keysIn');
   475  
   476  /**
   477   * The base implementation of `_.forIn` without support for callback
   478   * shorthands and `this` binding.
   479   *
   480   * @private
   481   * @param {Object} object The object to iterate over.
   482   * @param {Function} iteratee The function invoked per iteration.
   483   * @returns {Object} Returns `object`.
   484   */
   485  function baseForIn(object, iteratee) {
   486    return baseFor(object, iteratee, keysIn);
   487  }
   488  
   489  module.exports = baseForIn;
   490  
   491  },{"../object/keysIn":39,"./baseFor":11}],13:[function(_dereq_,module,exports){
   492  var arrayEach = _dereq_('./arrayEach'),
   493      baseMergeDeep = _dereq_('./baseMergeDeep'),
   494      isArray = _dereq_('../lang/isArray'),
   495      isArrayLike = _dereq_('./isArrayLike'),
   496      isObject = _dereq_('../lang/isObject'),
   497      isObjectLike = _dereq_('./isObjectLike'),
   498      isTypedArray = _dereq_('../lang/isTypedArray'),
   499      keys = _dereq_('../object/keys');
   500  
   501  /**
   502   * The base implementation of `_.merge` without support for argument juggling,
   503   * multiple sources, and `this` binding `customizer` functions.
   504   *
   505   * @private
   506   * @param {Object} object The destination object.
   507   * @param {Object} source The source object.
   508   * @param {Function} [customizer] The function to customize merged values.
   509   * @param {Array} [stackA=[]] Tracks traversed source objects.
   510   * @param {Array} [stackB=[]] Associates values with source counterparts.
   511   * @returns {Object} Returns `object`.
   512   */
   513  function baseMerge(object, source, customizer, stackA, stackB) {
   514    if (!isObject(object)) {
   515      return object;
   516    }
   517    var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)),
   518        props = isSrcArr ? undefined : keys(source);
   519  
   520    arrayEach(props || source, function(srcValue, key) {
   521      if (props) {
   522        key = srcValue;
   523        srcValue = source[key];
   524      }
   525      if (isObjectLike(srcValue)) {
   526        stackA || (stackA = []);
   527        stackB || (stackB = []);
   528        baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
   529      }
   530      else {
   531        var value = object[key],
   532            result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
   533            isCommon = result === undefined;
   534  
   535        if (isCommon) {
   536          result = srcValue;
   537        }
   538        if ((result !== undefined || (isSrcArr && !(key in object))) &&
   539            (isCommon || (result === result ? (result !== value) : (value === value)))) {
   540          object[key] = result;
   541        }
   542      }
   543    });
   544    return object;
   545  }
   546  
   547  module.exports = baseMerge;
   548  
   549  },{"../lang/isArray":30,"../lang/isObject":33,"../lang/isTypedArray":36,"../object/keys":38,"./arrayEach":9,"./baseMergeDeep":14,"./isArrayLike":21,"./isObjectLike":26}],14:[function(_dereq_,module,exports){
   550  var arrayCopy = _dereq_('./arrayCopy'),
   551      isArguments = _dereq_('../lang/isArguments'),
   552      isArray = _dereq_('../lang/isArray'),
   553      isArrayLike = _dereq_('./isArrayLike'),
   554      isPlainObject = _dereq_('../lang/isPlainObject'),
   555      isTypedArray = _dereq_('../lang/isTypedArray'),
   556      toPlainObject = _dereq_('../lang/toPlainObject');
   557  
   558  /**
   559   * A specialized version of `baseMerge` for arrays and objects which performs
   560   * deep merges and tracks traversed objects enabling objects with circular
   561   * references to be merged.
   562   *
   563   * @private
   564   * @param {Object} object The destination object.
   565   * @param {Object} source The source object.
   566   * @param {string} key The key of the value to merge.
   567   * @param {Function} mergeFunc The function to merge values.
   568   * @param {Function} [customizer] The function to customize merged values.
   569   * @param {Array} [stackA=[]] Tracks traversed source objects.
   570   * @param {Array} [stackB=[]] Associates values with source counterparts.
   571   * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
   572   */
   573  function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {
   574    var length = stackA.length,
   575        srcValue = source[key];
   576  
   577    while (length--) {
   578      if (stackA[length] == srcValue) {
   579        object[key] = stackB[length];
   580        return;
   581      }
   582    }
   583    var value = object[key],
   584        result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
   585        isCommon = result === undefined;
   586  
   587    if (isCommon) {
   588      result = srcValue;
   589      if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) {
   590        result = isArray(value)
   591          ? value
   592          : (isArrayLike(value) ? arrayCopy(value) : []);
   593      }
   594      else if (isPlainObject(srcValue) || isArguments(srcValue)) {
   595        result = isArguments(value)
   596          ? toPlainObject(value)
   597          : (isPlainObject(value) ? value : {});
   598      }
   599      else {
   600        isCommon = false;
   601      }
   602    }
   603    // Add the source value to the stack of traversed objects and associate
   604    // it with its merged value.
   605    stackA.push(srcValue);
   606    stackB.push(result);
   607  
   608    if (isCommon) {
   609      // Recursively merge objects and arrays (susceptible to call stack limits).
   610      object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
   611    } else if (result === result ? (result !== value) : (value === value)) {
   612      object[key] = result;
   613    }
   614  }
   615  
   616  module.exports = baseMergeDeep;
   617  
   618  },{"../lang/isArguments":29,"../lang/isArray":30,"../lang/isPlainObject":34,"../lang/isTypedArray":36,"../lang/toPlainObject":37,"./arrayCopy":8,"./isArrayLike":21}],15:[function(_dereq_,module,exports){
   619  var toObject = _dereq_('./toObject');
   620  
   621  /**
   622   * The base implementation of `_.property` without support for deep paths.
   623   *
   624   * @private
   625   * @param {string} key The key of the property to get.
   626   * @returns {Function} Returns the new function.
   627   */
   628  function baseProperty(key) {
   629    return function(object) {
   630      return object == null ? undefined : toObject(object)[key];
   631    };
   632  }
   633  
   634  module.exports = baseProperty;
   635  
   636  },{"./toObject":28}],16:[function(_dereq_,module,exports){
   637  var identity = _dereq_('../utility/identity');
   638  
   639  /**
   640   * A specialized version of `baseCallback` which only supports `this` binding
   641   * and specifying the number of arguments to provide to `func`.
   642   *
   643   * @private
   644   * @param {Function} func The function to bind.
   645   * @param {*} thisArg The `this` binding of `func`.
   646   * @param {number} [argCount] The number of arguments to provide to `func`.
   647   * @returns {Function} Returns the callback.
   648   */
   649  function bindCallback(func, thisArg, argCount) {
   650    if (typeof func != 'function') {
   651      return identity;
   652    }
   653    if (thisArg === undefined) {
   654      return func;
   655    }
   656    switch (argCount) {
   657      case 1: return function(value) {
   658        return func.call(thisArg, value);
   659      };
   660      case 3: return function(value, index, collection) {
   661        return func.call(thisArg, value, index, collection);
   662      };
   663      case 4: return function(accumulator, value, index, collection) {
   664        return func.call(thisArg, accumulator, value, index, collection);
   665      };
   666      case 5: return function(value, other, key, object, source) {
   667        return func.call(thisArg, value, other, key, object, source);
   668      };
   669    }
   670    return function() {
   671      return func.apply(thisArg, arguments);
   672    };
   673  }
   674  
   675  module.exports = bindCallback;
   676  
   677  },{"../utility/identity":42}],17:[function(_dereq_,module,exports){
   678  var bindCallback = _dereq_('./bindCallback'),
   679      isIterateeCall = _dereq_('./isIterateeCall'),
   680      restParam = _dereq_('../function/restParam');
   681  
   682  /**
   683   * Creates a `_.assign`, `_.defaults`, or `_.merge` function.
   684   *
   685   * @private
   686   * @param {Function} assigner The function to assign values.
   687   * @returns {Function} Returns the new assigner function.
   688   */
   689  function createAssigner(assigner) {
   690    return restParam(function(object, sources) {
   691      var index = -1,
   692          length = object == null ? 0 : sources.length,
   693          customizer = length > 2 ? sources[length - 2] : undefined,
   694          guard = length > 2 ? sources[2] : undefined,
   695          thisArg = length > 1 ? sources[length - 1] : undefined;
   696  
   697      if (typeof customizer == 'function') {
   698        customizer = bindCallback(customizer, thisArg, 5);
   699        length -= 2;
   700      } else {
   701        customizer = typeof thisArg == 'function' ? thisArg : undefined;
   702        length -= (customizer ? 1 : 0);
   703      }
   704      if (guard && isIterateeCall(sources[0], sources[1], guard)) {
   705        customizer = length < 3 ? undefined : customizer;
   706        length = 1;
   707      }
   708      while (++index < length) {
   709        var source = sources[index];
   710        if (source) {
   711          assigner(object, source, customizer);
   712        }
   713      }
   714      return object;
   715    });
   716  }
   717  
   718  module.exports = createAssigner;
   719  
   720  },{"../function/restParam":6,"./bindCallback":16,"./isIterateeCall":24}],18:[function(_dereq_,module,exports){
   721  var toObject = _dereq_('./toObject');
   722  
   723  /**
   724   * Creates a base function for `_.forIn` or `_.forInRight`.
   725   *
   726   * @private
   727   * @param {boolean} [fromRight] Specify iterating from right to left.
   728   * @returns {Function} Returns the new base function.
   729   */
   730  function createBaseFor(fromRight) {
   731    return function(object, iteratee, keysFunc) {
   732      var iterable = toObject(object),
   733          props = keysFunc(object),
   734          length = props.length,
   735          index = fromRight ? length : -1;
   736  
   737      while ((fromRight ? index-- : ++index < length)) {
   738        var key = props[index];
   739        if (iteratee(iterable[key], key, iterable) === false) {
   740          break;
   741        }
   742      }
   743      return object;
   744    };
   745  }
   746  
   747  module.exports = createBaseFor;
   748  
   749  },{"./toObject":28}],19:[function(_dereq_,module,exports){
   750  var baseProperty = _dereq_('./baseProperty');
   751  
   752  /**
   753   * Gets the "length" property value of `object`.
   754   *
   755   * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
   756   * that affects Safari on at least iOS 8.1-8.3 ARM64.
   757   *
   758   * @private
   759   * @param {Object} object The object to query.
   760   * @returns {*} Returns the "length" value.
   761   */
   762  var getLength = baseProperty('length');
   763  
   764  module.exports = getLength;
   765  
   766  },{"./baseProperty":15}],20:[function(_dereq_,module,exports){
   767  var isNative = _dereq_('../lang/isNative');
   768  
   769  /**
   770   * Gets the native function at `key` of `object`.
   771   *
   772   * @private
   773   * @param {Object} object The object to query.
   774   * @param {string} key The key of the method to get.
   775   * @returns {*} Returns the function if it's native, else `undefined`.
   776   */
   777  function getNative(object, key) {
   778    var value = object == null ? undefined : object[key];
   779    return isNative(value) ? value : undefined;
   780  }
   781  
   782  module.exports = getNative;
   783  
   784  },{"../lang/isNative":32}],21:[function(_dereq_,module,exports){
   785  var getLength = _dereq_('./getLength'),
   786      isLength = _dereq_('./isLength');
   787  
   788  /**
   789   * Checks if `value` is array-like.
   790   *
   791   * @private
   792   * @param {*} value The value to check.
   793   * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
   794   */
   795  function isArrayLike(value) {
   796    return value != null && isLength(getLength(value));
   797  }
   798  
   799  module.exports = isArrayLike;
   800  
   801  },{"./getLength":19,"./isLength":25}],22:[function(_dereq_,module,exports){
   802  /**
   803   * Checks if `value` is a host object in IE < 9.
   804   *
   805   * @private
   806   * @param {*} value The value to check.
   807   * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
   808   */
   809  var isHostObject = (function() {
   810    try {
   811      Object({ 'toString': 0 } + '');
   812    } catch(e) {
   813      return function() { return false; };
   814    }
   815    return function(value) {
   816      // IE < 9 presents many host objects as `Object` objects that can coerce
   817      // to strings despite having improperly defined `toString` methods.
   818      return typeof value.toString != 'function' && typeof (value + '') == 'string';
   819    };
   820  }());
   821  
   822  module.exports = isHostObject;
   823  
   824  },{}],23:[function(_dereq_,module,exports){
   825  /** Used to detect unsigned integer values. */
   826  var reIsUint = /^\d+$/;
   827  
   828  /**
   829   * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
   830   * of an array-like value.
   831   */
   832  var MAX_SAFE_INTEGER = 9007199254740991;
   833  
   834  /**
   835   * Checks if `value` is a valid array-like index.
   836   *
   837   * @private
   838   * @param {*} value The value to check.
   839   * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
   840   * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
   841   */
   842  function isIndex(value, length) {
   843    value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
   844    length = length == null ? MAX_SAFE_INTEGER : length;
   845    return value > -1 && value % 1 == 0 && value < length;
   846  }
   847  
   848  module.exports = isIndex;
   849  
   850  },{}],24:[function(_dereq_,module,exports){
   851  var isArrayLike = _dereq_('./isArrayLike'),
   852      isIndex = _dereq_('./isIndex'),
   853      isObject = _dereq_('../lang/isObject');
   854  
   855  /**
   856   * Checks if the provided arguments are from an iteratee call.
   857   *
   858   * @private
   859   * @param {*} value The potential iteratee value argument.
   860   * @param {*} index The potential iteratee index or key argument.
   861   * @param {*} object The potential iteratee object argument.
   862   * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
   863   */
   864  function isIterateeCall(value, index, object) {
   865    if (!isObject(object)) {
   866      return false;
   867    }
   868    var type = typeof index;
   869    if (type == 'number'
   870        ? (isArrayLike(object) && isIndex(index, object.length))
   871        : (type == 'string' && index in object)) {
   872      var other = object[index];
   873      return value === value ? (value === other) : (other !== other);
   874    }
   875    return false;
   876  }
   877  
   878  module.exports = isIterateeCall;
   879  
   880  },{"../lang/isObject":33,"./isArrayLike":21,"./isIndex":23}],25:[function(_dereq_,module,exports){
   881  /**
   882   * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
   883   * of an array-like value.
   884   */
   885  var MAX_SAFE_INTEGER = 9007199254740991;
   886  
   887  /**
   888   * Checks if `value` is a valid array-like length.
   889   *
   890   * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
   891   *
   892   * @private
   893   * @param {*} value The value to check.
   894   * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
   895   */
   896  function isLength(value) {
   897    return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
   898  }
   899  
   900  module.exports = isLength;
   901  
   902  },{}],26:[function(_dereq_,module,exports){
   903  /**
   904   * Checks if `value` is object-like.
   905   *
   906   * @private
   907   * @param {*} value The value to check.
   908   * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
   909   */
   910  function isObjectLike(value) {
   911    return !!value && typeof value == 'object';
   912  }
   913  
   914  module.exports = isObjectLike;
   915  
   916  },{}],27:[function(_dereq_,module,exports){
   917  var isArguments = _dereq_('../lang/isArguments'),
   918      isArray = _dereq_('../lang/isArray'),
   919      isIndex = _dereq_('./isIndex'),
   920      isLength = _dereq_('./isLength'),
   921      isString = _dereq_('../lang/isString'),
   922      keysIn = _dereq_('../object/keysIn');
   923  
   924  /** Used for native method references. */
   925  var objectProto = Object.prototype;
   926  
   927  /** Used to check objects for own properties. */
   928  var hasOwnProperty = objectProto.hasOwnProperty;
   929  
   930  /**
   931   * A fallback implementation of `Object.keys` which creates an array of the
   932   * own enumerable property names of `object`.
   933   *
   934   * @private
   935   * @param {Object} object The object to query.
   936   * @returns {Array} Returns the array of property names.
   937   */
   938  function shimKeys(object) {
   939    var props = keysIn(object),
   940        propsLength = props.length,
   941        length = propsLength && object.length;
   942  
   943    var allowIndexes = !!length && isLength(length) &&
   944      (isArray(object) || isArguments(object) || isString(object));
   945  
   946    var index = -1,
   947        result = [];
   948  
   949    while (++index < propsLength) {
   950      var key = props[index];
   951      if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
   952        result.push(key);
   953      }
   954    }
   955    return result;
   956  }
   957  
   958  module.exports = shimKeys;
   959  
   960  },{"../lang/isArguments":29,"../lang/isArray":30,"../lang/isString":35,"../object/keysIn":39,"./isIndex":23,"./isLength":25}],28:[function(_dereq_,module,exports){
   961  var isObject = _dereq_('../lang/isObject'),
   962      isString = _dereq_('../lang/isString'),
   963      support = _dereq_('../support');
   964  
   965  /**
   966   * Converts `value` to an object if it's not one.
   967   *
   968   * @private
   969   * @param {*} value The value to process.
   970   * @returns {Object} Returns the object.
   971   */
   972  function toObject(value) {
   973    if (support.unindexedChars && isString(value)) {
   974      var index = -1,
   975          length = value.length,
   976          result = Object(value);
   977  
   978      while (++index < length) {
   979        result[index] = value.charAt(index);
   980      }
   981      return result;
   982    }
   983    return isObject(value) ? value : Object(value);
   984  }
   985  
   986  module.exports = toObject;
   987  
   988  },{"../lang/isObject":33,"../lang/isString":35,"../support":41}],29:[function(_dereq_,module,exports){
   989  var isArrayLike = _dereq_('../internal/isArrayLike'),
   990      isObjectLike = _dereq_('../internal/isObjectLike');
   991  
   992  /** Used for native method references. */
   993  var objectProto = Object.prototype;
   994  
   995  /** Used to check objects for own properties. */
   996  var hasOwnProperty = objectProto.hasOwnProperty;
   997  
   998  /** Native method references. */
   999  var propertyIsEnumerable = objectProto.propertyIsEnumerable;
  1000  
  1001  /**
  1002   * Checks if `value` is classified as an `arguments` object.
  1003   *
  1004   * @static
  1005   * @memberOf _
  1006   * @category Lang
  1007   * @param {*} value The value to check.
  1008   * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
  1009   * @example
  1010   *
  1011   * _.isArguments(function() { return arguments; }());
  1012   * // => true
  1013   *
  1014   * _.isArguments([1, 2, 3]);
  1015   * // => false
  1016   */
  1017  function isArguments(value) {
  1018    return isObjectLike(value) && isArrayLike(value) &&
  1019      hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
  1020  }
  1021  
  1022  module.exports = isArguments;
  1023  
  1024  },{"../internal/isArrayLike":21,"../internal/isObjectLike":26}],30:[function(_dereq_,module,exports){
  1025  var getNative = _dereq_('../internal/getNative'),
  1026      isLength = _dereq_('../internal/isLength'),
  1027      isObjectLike = _dereq_('../internal/isObjectLike');
  1028  
  1029  /** `Object#toString` result references. */
  1030  var arrayTag = '[object Array]';
  1031  
  1032  /** Used for native method references. */
  1033  var objectProto = Object.prototype;
  1034  
  1035  /**
  1036   * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
  1037   * of values.
  1038   */
  1039  var objToString = objectProto.toString;
  1040  
  1041  /* Native method references for those with the same name as other `lodash` methods. */
  1042  var nativeIsArray = getNative(Array, 'isArray');
  1043  
  1044  /**
  1045   * Checks if `value` is classified as an `Array` object.
  1046   *
  1047   * @static
  1048   * @memberOf _
  1049   * @category Lang
  1050   * @param {*} value The value to check.
  1051   * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
  1052   * @example
  1053   *
  1054   * _.isArray([1, 2, 3]);
  1055   * // => true
  1056   *
  1057   * _.isArray(function() { return arguments; }());
  1058   * // => false
  1059   */
  1060  var isArray = nativeIsArray || function(value) {
  1061    return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
  1062  };
  1063  
  1064  module.exports = isArray;
  1065  
  1066  },{"../internal/getNative":20,"../internal/isLength":25,"../internal/isObjectLike":26}],31:[function(_dereq_,module,exports){
  1067  var isObject = _dereq_('./isObject');
  1068  
  1069  /** `Object#toString` result references. */
  1070  var funcTag = '[object Function]';
  1071  
  1072  /** Used for native method references. */
  1073  var objectProto = Object.prototype;
  1074  
  1075  /**
  1076   * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
  1077   * of values.
  1078   */
  1079  var objToString = objectProto.toString;
  1080  
  1081  /**
  1082   * Checks if `value` is classified as a `Function` object.
  1083   *
  1084   * @static
  1085   * @memberOf _
  1086   * @category Lang
  1087   * @param {*} value The value to check.
  1088   * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
  1089   * @example
  1090   *
  1091   * _.isFunction(_);
  1092   * // => true
  1093   *
  1094   * _.isFunction(/abc/);
  1095   * // => false
  1096   */
  1097  function isFunction(value) {
  1098    // The use of `Object#toString` avoids issues with the `typeof` operator
  1099    // in older versions of Chrome and Safari which return 'function' for regexes
  1100    // and Safari 8 which returns 'object' for typed array constructors.
  1101    return isObject(value) && objToString.call(value) == funcTag;
  1102  }
  1103  
  1104  module.exports = isFunction;
  1105  
  1106  },{"./isObject":33}],32:[function(_dereq_,module,exports){
  1107  var isFunction = _dereq_('./isFunction'),
  1108      isHostObject = _dereq_('../internal/isHostObject'),
  1109      isObjectLike = _dereq_('../internal/isObjectLike');
  1110  
  1111  /** Used to detect host constructors (Safari > 5). */
  1112  var reIsHostCtor = /^\[object .+?Constructor\]$/;
  1113  
  1114  /** Used for native method references. */
  1115  var objectProto = Object.prototype;
  1116  
  1117  /** Used to resolve the decompiled source of functions. */
  1118  var fnToString = Function.prototype.toString;
  1119  
  1120  /** Used to check objects for own properties. */
  1121  var hasOwnProperty = objectProto.hasOwnProperty;
  1122  
  1123  /** Used to detect if a method is native. */
  1124  var reIsNative = RegExp('^' +
  1125    fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
  1126    .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
  1127  );
  1128  
  1129  /**
  1130   * Checks if `value` is a native function.
  1131   *
  1132   * @static
  1133   * @memberOf _
  1134   * @category Lang
  1135   * @param {*} value The value to check.
  1136   * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
  1137   * @example
  1138   *
  1139   * _.isNative(Array.prototype.push);
  1140   * // => true
  1141   *
  1142   * _.isNative(_);
  1143   * // => false
  1144   */
  1145  function isNative(value) {
  1146    if (value == null) {
  1147      return false;
  1148    }
  1149    if (isFunction(value)) {
  1150      return reIsNative.test(fnToString.call(value));
  1151    }
  1152    return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
  1153  }
  1154  
  1155  module.exports = isNative;
  1156  
  1157  },{"../internal/isHostObject":22,"../internal/isObjectLike":26,"./isFunction":31}],33:[function(_dereq_,module,exports){
  1158  /**
  1159   * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
  1160   * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  1161   *
  1162   * @static
  1163   * @memberOf _
  1164   * @category Lang
  1165   * @param {*} value The value to check.
  1166   * @returns {boolean} Returns `true` if `value` is an object, else `false`.
  1167   * @example
  1168   *
  1169   * _.isObject({});
  1170   * // => true
  1171   *
  1172   * _.isObject([1, 2, 3]);
  1173   * // => true
  1174   *
  1175   * _.isObject(1);
  1176   * // => false
  1177   */
  1178  function isObject(value) {
  1179    // Avoid a V8 JIT bug in Chrome 19-20.
  1180    // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
  1181    var type = typeof value;
  1182    return !!value && (type == 'object' || type == 'function');
  1183  }
  1184  
  1185  module.exports = isObject;
  1186  
  1187  },{}],34:[function(_dereq_,module,exports){
  1188  var baseForIn = _dereq_('../internal/baseForIn'),
  1189      isArguments = _dereq_('./isArguments'),
  1190      isHostObject = _dereq_('../internal/isHostObject'),
  1191      isObjectLike = _dereq_('../internal/isObjectLike'),
  1192      support = _dereq_('../support');
  1193  
  1194  /** `Object#toString` result references. */
  1195  var objectTag = '[object Object]';
  1196  
  1197  /** Used for native method references. */
  1198  var objectProto = Object.prototype;
  1199  
  1200  /** Used to check objects for own properties. */
  1201  var hasOwnProperty = objectProto.hasOwnProperty;
  1202  
  1203  /**
  1204   * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
  1205   * of values.
  1206   */
  1207  var objToString = objectProto.toString;
  1208  
  1209  /**
  1210   * Checks if `value` is a plain object, that is, an object created by the
  1211   * `Object` constructor or one with a `[[Prototype]]` of `null`.
  1212   *
  1213   * **Note:** This method assumes objects created by the `Object` constructor
  1214   * have no inherited enumerable properties.
  1215   *
  1216   * @static
  1217   * @memberOf _
  1218   * @category Lang
  1219   * @param {*} value The value to check.
  1220   * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
  1221   * @example
  1222   *
  1223   * function Foo() {
  1224   *   this.a = 1;
  1225   * }
  1226   *
  1227   * _.isPlainObject(new Foo);
  1228   * // => false
  1229   *
  1230   * _.isPlainObject([1, 2, 3]);
  1231   * // => false
  1232   *
  1233   * _.isPlainObject({ 'x': 0, 'y': 0 });
  1234   * // => true
  1235   *
  1236   * _.isPlainObject(Object.create(null));
  1237   * // => true
  1238   */
  1239  function isPlainObject(value) {
  1240    var Ctor;
  1241  
  1242    // Exit early for non `Object` objects.
  1243    if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) ||
  1244        (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
  1245      return false;
  1246    }
  1247    // IE < 9 iterates inherited properties before own properties. If the first
  1248    // iterated property is an object's own property then there are no inherited
  1249    // enumerable properties.
  1250    var result;
  1251    if (support.ownLast) {
  1252      baseForIn(value, function(subValue, key, object) {
  1253        result = hasOwnProperty.call(object, key);
  1254        return false;
  1255      });
  1256      return result !== false;
  1257    }
  1258    // In most environments an object's own properties are iterated before
  1259    // its inherited properties. If the last iterated property is an object's
  1260    // own property then there are no inherited enumerable properties.
  1261    baseForIn(value, function(subValue, key) {
  1262      result = key;
  1263    });
  1264    return result === undefined || hasOwnProperty.call(value, result);
  1265  }
  1266  
  1267  module.exports = isPlainObject;
  1268  
  1269  },{"../internal/baseForIn":12,"../internal/isHostObject":22,"../internal/isObjectLike":26,"../support":41,"./isArguments":29}],35:[function(_dereq_,module,exports){
  1270  var isObjectLike = _dereq_('../internal/isObjectLike');
  1271  
  1272  /** `Object#toString` result references. */
  1273  var stringTag = '[object String]';
  1274  
  1275  /** Used for native method references. */
  1276  var objectProto = Object.prototype;
  1277  
  1278  /**
  1279   * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
  1280   * of values.
  1281   */
  1282  var objToString = objectProto.toString;
  1283  
  1284  /**
  1285   * Checks if `value` is classified as a `String` primitive or object.
  1286   *
  1287   * @static
  1288   * @memberOf _
  1289   * @category Lang
  1290   * @param {*} value The value to check.
  1291   * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
  1292   * @example
  1293   *
  1294   * _.isString('abc');
  1295   * // => true
  1296   *
  1297   * _.isString(1);
  1298   * // => false
  1299   */
  1300  function isString(value) {
  1301    return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
  1302  }
  1303  
  1304  module.exports = isString;
  1305  
  1306  },{"../internal/isObjectLike":26}],36:[function(_dereq_,module,exports){
  1307  var isLength = _dereq_('../internal/isLength'),
  1308      isObjectLike = _dereq_('../internal/isObjectLike');
  1309  
  1310  /** `Object#toString` result references. */
  1311  var argsTag = '[object Arguments]',
  1312      arrayTag = '[object Array]',
  1313      boolTag = '[object Boolean]',
  1314      dateTag = '[object Date]',
  1315      errorTag = '[object Error]',
  1316      funcTag = '[object Function]',
  1317      mapTag = '[object Map]',
  1318      numberTag = '[object Number]',
  1319      objectTag = '[object Object]',
  1320      regexpTag = '[object RegExp]',
  1321      setTag = '[object Set]',
  1322      stringTag = '[object String]',
  1323      weakMapTag = '[object WeakMap]';
  1324  
  1325  var arrayBufferTag = '[object ArrayBuffer]',
  1326      float32Tag = '[object Float32Array]',
  1327      float64Tag = '[object Float64Array]',
  1328      int8Tag = '[object Int8Array]',
  1329      int16Tag = '[object Int16Array]',
  1330      int32Tag = '[object Int32Array]',
  1331      uint8Tag = '[object Uint8Array]',
  1332      uint8ClampedTag = '[object Uint8ClampedArray]',
  1333      uint16Tag = '[object Uint16Array]',
  1334      uint32Tag = '[object Uint32Array]';
  1335  
  1336  /** Used to identify `toStringTag` values of typed arrays. */
  1337  var typedArrayTags = {};
  1338  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
  1339  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
  1340  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
  1341  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
  1342  typedArrayTags[uint32Tag] = true;
  1343  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
  1344  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
  1345  typedArrayTags[dateTag] = typedArrayTags[errorTag] =
  1346  typedArrayTags[funcTag] = typedArrayTags[mapTag] =
  1347  typedArrayTags[numberTag] = typedArrayTags[objectTag] =
  1348  typedArrayTags[regexpTag] = typedArrayTags[setTag] =
  1349  typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
  1350  
  1351  /** Used for native method references. */
  1352  var objectProto = Object.prototype;
  1353  
  1354  /**
  1355   * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
  1356   * of values.
  1357   */
  1358  var objToString = objectProto.toString;
  1359  
  1360  /**
  1361   * Checks if `value` is classified as a typed array.
  1362   *
  1363   * @static
  1364   * @memberOf _
  1365   * @category Lang
  1366   * @param {*} value The value to check.
  1367   * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
  1368   * @example
  1369   *
  1370   * _.isTypedArray(new Uint8Array);
  1371   * // => true
  1372   *
  1373   * _.isTypedArray([]);
  1374   * // => false
  1375   */
  1376  function isTypedArray(value) {
  1377    return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
  1378  }
  1379  
  1380  module.exports = isTypedArray;
  1381  
  1382  },{"../internal/isLength":25,"../internal/isObjectLike":26}],37:[function(_dereq_,module,exports){
  1383  var baseCopy = _dereq_('../internal/baseCopy'),
  1384      keysIn = _dereq_('../object/keysIn');
  1385  
  1386  /**
  1387   * Converts `value` to a plain object flattening inherited enumerable
  1388   * properties of `value` to own properties of the plain object.
  1389   *
  1390   * @static
  1391   * @memberOf _
  1392   * @category Lang
  1393   * @param {*} value The value to convert.
  1394   * @returns {Object} Returns the converted plain object.
  1395   * @example
  1396   *
  1397   * function Foo() {
  1398   *   this.b = 2;
  1399   * }
  1400   *
  1401   * Foo.prototype.c = 3;
  1402   *
  1403   * _.assign({ 'a': 1 }, new Foo);
  1404   * // => { 'a': 1, 'b': 2 }
  1405   *
  1406   * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
  1407   * // => { 'a': 1, 'b': 2, 'c': 3 }
  1408   */
  1409  function toPlainObject(value) {
  1410    return baseCopy(value, keysIn(value));
  1411  }
  1412  
  1413  module.exports = toPlainObject;
  1414  
  1415  },{"../internal/baseCopy":10,"../object/keysIn":39}],38:[function(_dereq_,module,exports){
  1416  var getNative = _dereq_('../internal/getNative'),
  1417      isArrayLike = _dereq_('../internal/isArrayLike'),
  1418      isObject = _dereq_('../lang/isObject'),
  1419      shimKeys = _dereq_('../internal/shimKeys'),
  1420      support = _dereq_('../support');
  1421  
  1422  /* Native method references for those with the same name as other `lodash` methods. */
  1423  var nativeKeys = getNative(Object, 'keys');
  1424  
  1425  /**
  1426   * Creates an array of the own enumerable property names of `object`.
  1427   *
  1428   * **Note:** Non-object values are coerced to objects. See the
  1429   * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
  1430   * for more details.
  1431   *
  1432   * @static
  1433   * @memberOf _
  1434   * @category Object
  1435   * @param {Object} object The object to query.
  1436   * @returns {Array} Returns the array of property names.
  1437   * @example
  1438   *
  1439   * function Foo() {
  1440   *   this.a = 1;
  1441   *   this.b = 2;
  1442   * }
  1443   *
  1444   * Foo.prototype.c = 3;
  1445   *
  1446   * _.keys(new Foo);
  1447   * // => ['a', 'b'] (iteration order is not guaranteed)
  1448   *
  1449   * _.keys('hi');
  1450   * // => ['0', '1']
  1451   */
  1452  var keys = !nativeKeys ? shimKeys : function(object) {
  1453    var Ctor = object == null ? undefined : object.constructor;
  1454    if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
  1455        (typeof object == 'function' ? support.enumPrototypes : isArrayLike(object))) {
  1456      return shimKeys(object);
  1457    }
  1458    return isObject(object) ? nativeKeys(object) : [];
  1459  };
  1460  
  1461  module.exports = keys;
  1462  
  1463  },{"../internal/getNative":20,"../internal/isArrayLike":21,"../internal/shimKeys":27,"../lang/isObject":33,"../support":41}],39:[function(_dereq_,module,exports){
  1464  var arrayEach = _dereq_('../internal/arrayEach'),
  1465      isArguments = _dereq_('../lang/isArguments'),
  1466      isArray = _dereq_('../lang/isArray'),
  1467      isFunction = _dereq_('../lang/isFunction'),
  1468      isIndex = _dereq_('../internal/isIndex'),
  1469      isLength = _dereq_('../internal/isLength'),
  1470      isObject = _dereq_('../lang/isObject'),
  1471      isString = _dereq_('../lang/isString'),
  1472      support = _dereq_('../support');
  1473  
  1474  /** `Object#toString` result references. */
  1475  var arrayTag = '[object Array]',
  1476      boolTag = '[object Boolean]',
  1477      dateTag = '[object Date]',
  1478      errorTag = '[object Error]',
  1479      funcTag = '[object Function]',
  1480      numberTag = '[object Number]',
  1481      objectTag = '[object Object]',
  1482      regexpTag = '[object RegExp]',
  1483      stringTag = '[object String]';
  1484  
  1485  /** Used to fix the JScript `[[DontEnum]]` bug. */
  1486  var shadowProps = [
  1487    'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
  1488    'toLocaleString', 'toString', 'valueOf'
  1489  ];
  1490  
  1491  /** Used for native method references. */
  1492  var errorProto = Error.prototype,
  1493      objectProto = Object.prototype,
  1494      stringProto = String.prototype;
  1495  
  1496  /** Used to check objects for own properties. */
  1497  var hasOwnProperty = objectProto.hasOwnProperty;
  1498  
  1499  /**
  1500   * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
  1501   * of values.
  1502   */
  1503  var objToString = objectProto.toString;
  1504  
  1505  /** Used to avoid iterating over non-enumerable properties in IE < 9. */
  1506  var nonEnumProps = {};
  1507  nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
  1508  nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true };
  1509  nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true };
  1510  nonEnumProps[objectTag] = { 'constructor': true };
  1511  
  1512  arrayEach(shadowProps, function(key) {
  1513    for (var tag in nonEnumProps) {
  1514      if (hasOwnProperty.call(nonEnumProps, tag)) {
  1515        var props = nonEnumProps[tag];
  1516        props[key] = hasOwnProperty.call(props, key);
  1517      }
  1518    }
  1519  });
  1520  
  1521  /**
  1522   * Creates an array of the own and inherited enumerable property names of `object`.
  1523   *
  1524   * **Note:** Non-object values are coerced to objects.
  1525   *
  1526   * @static
  1527   * @memberOf _
  1528   * @category Object
  1529   * @param {Object} object The object to query.
  1530   * @returns {Array} Returns the array of property names.
  1531   * @example
  1532   *
  1533   * function Foo() {
  1534   *   this.a = 1;
  1535   *   this.b = 2;
  1536   * }
  1537   *
  1538   * Foo.prototype.c = 3;
  1539   *
  1540   * _.keysIn(new Foo);
  1541   * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
  1542   */
  1543  function keysIn(object) {
  1544    if (object == null) {
  1545      return [];
  1546    }
  1547    if (!isObject(object)) {
  1548      object = Object(object);
  1549    }
  1550    var length = object.length;
  1551  
  1552    length = (length && isLength(length) &&
  1553      (isArray(object) || isArguments(object) || isString(object)) && length) || 0;
  1554  
  1555    var Ctor = object.constructor,
  1556        index = -1,
  1557        proto = (isFunction(Ctor) && Ctor.prototype) || objectProto,
  1558        isProto = proto === object,
  1559        result = Array(length),
  1560        skipIndexes = length > 0,
  1561        skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error),
  1562        skipProto = support.enumPrototypes && isFunction(object);
  1563  
  1564    while (++index < length) {
  1565      result[index] = (index + '');
  1566    }
  1567    // lodash skips the `constructor` property when it infers it's iterating
  1568    // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]`
  1569    // attribute of an existing property and the `constructor` property of a
  1570    // prototype defaults to non-enumerable.
  1571    for (var key in object) {
  1572      if (!(skipProto && key == 'prototype') &&
  1573          !(skipErrorProps && (key == 'message' || key == 'name')) &&
  1574          !(skipIndexes && isIndex(key, length)) &&
  1575          !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
  1576        result.push(key);
  1577      }
  1578    }
  1579    if (support.nonEnumShadows && object !== objectProto) {
  1580      var tag = object === stringProto ? stringTag : (object === errorProto ? errorTag : objToString.call(object)),
  1581          nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag];
  1582  
  1583      if (tag == objectTag) {
  1584        proto = objectProto;
  1585      }
  1586      length = shadowProps.length;
  1587      while (length--) {
  1588        key = shadowProps[length];
  1589        var nonEnum = nonEnums[key];
  1590        if (!(isProto && nonEnum) &&
  1591            (nonEnum ? hasOwnProperty.call(object, key) : object[key] !== proto[key])) {
  1592          result.push(key);
  1593        }
  1594      }
  1595    }
  1596    return result;
  1597  }
  1598  
  1599  module.exports = keysIn;
  1600  
  1601  },{"../internal/arrayEach":9,"../internal/isIndex":23,"../internal/isLength":25,"../lang/isArguments":29,"../lang/isArray":30,"../lang/isFunction":31,"../lang/isObject":33,"../lang/isString":35,"../support":41}],40:[function(_dereq_,module,exports){
  1602  var baseMerge = _dereq_('../internal/baseMerge'),
  1603      createAssigner = _dereq_('../internal/createAssigner');
  1604  
  1605  /**
  1606   * Recursively merges own enumerable properties of the source object(s), that
  1607   * don't resolve to `undefined` into the destination object. Subsequent sources
  1608   * overwrite property assignments of previous sources. If `customizer` is
  1609   * provided it's invoked to produce the merged values of the destination and
  1610   * source properties. If `customizer` returns `undefined` merging is handled
  1611   * by the method instead. The `customizer` is bound to `thisArg` and invoked
  1612   * with five arguments: (objectValue, sourceValue, key, object, source).
  1613   *
  1614   * @static
  1615   * @memberOf _
  1616   * @category Object
  1617   * @param {Object} object The destination object.
  1618   * @param {...Object} [sources] The source objects.
  1619   * @param {Function} [customizer] The function to customize assigned values.
  1620   * @param {*} [thisArg] The `this` binding of `customizer`.
  1621   * @returns {Object} Returns `object`.
  1622   * @example
  1623   *
  1624   * var users = {
  1625   *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
  1626   * };
  1627   *
  1628   * var ages = {
  1629   *   'data': [{ 'age': 36 }, { 'age': 40 }]
  1630   * };
  1631   *
  1632   * _.merge(users, ages);
  1633   * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
  1634   *
  1635   * // using a customizer callback
  1636   * var object = {
  1637   *   'fruits': ['apple'],
  1638   *   'vegetables': ['beet']
  1639   * };
  1640   *
  1641   * var other = {
  1642   *   'fruits': ['banana'],
  1643   *   'vegetables': ['carrot']
  1644   * };
  1645   *
  1646   * _.merge(object, other, function(a, b) {
  1647   *   if (_.isArray(a)) {
  1648   *     return a.concat(b);
  1649   *   }
  1650   * });
  1651   * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
  1652   */
  1653  var merge = createAssigner(baseMerge);
  1654  
  1655  module.exports = merge;
  1656  
  1657  },{"../internal/baseMerge":13,"../internal/createAssigner":17}],41:[function(_dereq_,module,exports){
  1658  /** Used for native method references. */
  1659  var arrayProto = Array.prototype,
  1660      errorProto = Error.prototype,
  1661      objectProto = Object.prototype;
  1662  
  1663  /** Native method references. */
  1664  var propertyIsEnumerable = objectProto.propertyIsEnumerable,
  1665      splice = arrayProto.splice;
  1666  
  1667  /**
  1668   * An object environment feature flags.
  1669   *
  1670   * @static
  1671   * @memberOf _
  1672   * @type Object
  1673   */
  1674  var support = {};
  1675  
  1676  (function(x) {
  1677    var Ctor = function() { this.x = x; },
  1678        object = { '0': x, 'length': x },
  1679        props = [];
  1680  
  1681    Ctor.prototype = { 'valueOf': x, 'y': x };
  1682    for (var key in new Ctor) { props.push(key); }
  1683  
  1684    /**
  1685     * Detect if `name` or `message` properties of `Error.prototype` are
  1686     * enumerable by default (IE < 9, Safari < 5.1).
  1687     *
  1688     * @memberOf _.support
  1689     * @type boolean
  1690     */
  1691    support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') ||
  1692      propertyIsEnumerable.call(errorProto, 'name');
  1693  
  1694    /**
  1695     * Detect if `prototype` properties are enumerable by default.
  1696     *
  1697     * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
  1698     * (if the prototype or a property on the prototype has been set)
  1699     * incorrectly set the `[[Enumerable]]` value of a function's `prototype`
  1700     * property to `true`.
  1701     *
  1702     * @memberOf _.support
  1703     * @type boolean
  1704     */
  1705    support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype');
  1706  
  1707    /**
  1708     * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
  1709     *
  1710     * In IE < 9 an object's own properties, shadowing non-enumerable ones,
  1711     * are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug).
  1712     *
  1713     * @memberOf _.support
  1714     * @type boolean
  1715     */
  1716    support.nonEnumShadows = !/valueOf/.test(props);
  1717  
  1718    /**
  1719     * Detect if own properties are iterated after inherited properties (IE < 9).
  1720     *
  1721     * @memberOf _.support
  1722     * @type boolean
  1723     */
  1724    support.ownLast = props[0] != 'x';
  1725  
  1726    /**
  1727     * Detect if `Array#shift` and `Array#splice` augment array-like objects
  1728     * correctly.
  1729     *
  1730     * Firefox < 10, compatibility modes of IE 8, and IE < 9 have buggy Array
  1731     * `shift()` and `splice()` functions that fail to remove the last element,
  1732     * `value[0]`, of array-like objects even though the "length" property is
  1733     * set to `0`. The `shift()` method is buggy in compatibility modes of IE 8,
  1734     * while `splice()` is buggy regardless of mode in IE < 9.
  1735     *
  1736     * @memberOf _.support
  1737     * @type boolean
  1738     */
  1739    support.spliceObjects = (splice.call(object, 0, 1), !object[0]);
  1740  
  1741    /**
  1742     * Detect lack of support for accessing string characters by index.
  1743     *
  1744     * IE < 8 can't access characters by index. IE 8 can only access characters
  1745     * by index on string literals, not string objects.
  1746     *
  1747     * @memberOf _.support
  1748     * @type boolean
  1749     */
  1750    support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
  1751  }(1, 0));
  1752  
  1753  module.exports = support;
  1754  
  1755  },{}],42:[function(_dereq_,module,exports){
  1756  /**
  1757   * This method returns the first argument provided to it.
  1758   *
  1759   * @static
  1760   * @memberOf _
  1761   * @category Utility
  1762   * @param {*} value Any value.
  1763   * @returns {*} Returns `value`.
  1764   * @example
  1765   *
  1766   * var object = { 'user': 'fred' };
  1767   *
  1768   * _.identity(object) === object;
  1769   * // => true
  1770   */
  1771  function identity(value) {
  1772    return value;
  1773  }
  1774  
  1775  module.exports = identity;
  1776  
  1777  },{}],43:[function(_dereq_,module,exports){
  1778  'use strict';
  1779  
  1780  var keys = _dereq_('object-keys');
  1781  
  1782  module.exports = function hasSymbols() {
  1783  	if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }
  1784  	if (typeof Symbol.iterator === 'symbol') { return true; }
  1785  
  1786  	var obj = {};
  1787  	var sym = Symbol('test');
  1788  	if (typeof sym === 'string') { return false; }
  1789  
  1790  	// temp disabled per https://github.com/ljharb/object.assign/issues/17
  1791  	// if (sym instanceof Symbol) { return false; }
  1792  	// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4
  1793  	// if (!(Object(sym) instanceof Symbol)) { return false; }
  1794  
  1795  	var symVal = 42;
  1796  	obj[sym] = symVal;
  1797  	for (sym in obj) { return false; }
  1798  	if (keys(obj).length !== 0) { return false; }
  1799  	if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }
  1800  
  1801  	if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }
  1802  
  1803  	var syms = Object.getOwnPropertySymbols(obj);
  1804  	if (syms.length !== 1 || syms[0] !== sym) { return false; }
  1805  
  1806  	if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }
  1807  
  1808  	if (typeof Object.getOwnPropertyDescriptor === 'function') {
  1809  		var descriptor = Object.getOwnPropertyDescriptor(obj, sym);
  1810  		if (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }
  1811  	}
  1812  
  1813  	return true;
  1814  };
  1815  
  1816  },{"object-keys":50}],44:[function(_dereq_,module,exports){
  1817  'use strict';
  1818  
  1819  // modified from https://github.com/es-shims/es6-shim
  1820  var keys = _dereq_('object-keys');
  1821  var bind = _dereq_('function-bind');
  1822  var canBeObject = function (obj) {
  1823  	return typeof obj !== 'undefined' && obj !== null;
  1824  };
  1825  var hasSymbols = _dereq_('./hasSymbols')();
  1826  var toObject = Object;
  1827  var push = bind.call(Function.call, Array.prototype.push);
  1828  var propIsEnumerable = bind.call(Function.call, Object.prototype.propertyIsEnumerable);
  1829  
  1830  module.exports = function assign(target, source1) {
  1831  	if (!canBeObject(target)) { throw new TypeError('target must be an object'); }
  1832  	var objTarget = toObject(target);
  1833  	var s, source, i, props, syms, value, key;
  1834  	for (s = 1; s < arguments.length; ++s) {
  1835  		source = toObject(arguments[s]);
  1836  		props = keys(source);
  1837  		if (hasSymbols && Object.getOwnPropertySymbols) {
  1838  			syms = Object.getOwnPropertySymbols(source);
  1839  			for (i = 0; i < syms.length; ++i) {
  1840  				key = syms[i];
  1841  				if (propIsEnumerable(source, key)) {
  1842  					push(props, key);
  1843  				}
  1844  			}
  1845  		}
  1846  		for (i = 0; i < props.length; ++i) {
  1847  			key = props[i];
  1848  			value = source[key];
  1849  			if (propIsEnumerable(source, key)) {
  1850  				objTarget[key] = value;
  1851  			}
  1852  		}
  1853  	}
  1854  	return objTarget;
  1855  };
  1856  
  1857  },{"./hasSymbols":43,"function-bind":49,"object-keys":50}],45:[function(_dereq_,module,exports){
  1858  'use strict';
  1859  
  1860  var defineProperties = _dereq_('define-properties');
  1861  
  1862  var implementation = _dereq_('./implementation');
  1863  var getPolyfill = _dereq_('./polyfill');
  1864  var shim = _dereq_('./shim');
  1865  
  1866  defineProperties(implementation, {
  1867  	implementation: implementation,
  1868  	getPolyfill: getPolyfill,
  1869  	shim: shim
  1870  });
  1871  
  1872  module.exports = implementation;
  1873  
  1874  },{"./implementation":44,"./polyfill":52,"./shim":53,"define-properties":46}],46:[function(_dereq_,module,exports){
  1875  'use strict';
  1876  
  1877  var keys = _dereq_('object-keys');
  1878  var foreach = _dereq_('foreach');
  1879  var hasSymbols = typeof Symbol === 'function' && typeof Symbol() === 'symbol';
  1880  
  1881  var toStr = Object.prototype.toString;
  1882  
  1883  var isFunction = function (fn) {
  1884  	return typeof fn === 'function' && toStr.call(fn) === '[object Function]';
  1885  };
  1886  
  1887  var arePropertyDescriptorsSupported = function () {
  1888  	var obj = {};
  1889  	try {
  1890  		Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
  1891          /* eslint-disable no-unused-vars, no-restricted-syntax */
  1892          for (var _ in obj) { return false; }
  1893          /* eslint-enable no-unused-vars, no-restricted-syntax */
  1894  		return obj.x === obj;
  1895  	} catch (e) { /* this is IE 8. */
  1896  		return false;
  1897  	}
  1898  };
  1899  var supportsDescriptors = Object.defineProperty && arePropertyDescriptorsSupported();
  1900  
  1901  var defineProperty = function (object, name, value, predicate) {
  1902  	if (name in object && (!isFunction(predicate) || !predicate())) {
  1903  		return;
  1904  	}
  1905  	if (supportsDescriptors) {
  1906  		Object.defineProperty(object, name, {
  1907  			configurable: true,
  1908  			enumerable: false,
  1909  			value: value,
  1910  			writable: true
  1911  		});
  1912  	} else {
  1913  		object[name] = value;
  1914  	}
  1915  };
  1916  
  1917  var defineProperties = function (object, map) {
  1918  	var predicates = arguments.length > 2 ? arguments[2] : {};
  1919  	var props = keys(map);
  1920  	if (hasSymbols) {
  1921  		props = props.concat(Object.getOwnPropertySymbols(map));
  1922  	}
  1923  	foreach(props, function (name) {
  1924  		defineProperty(object, name, map[name], predicates[name]);
  1925  	});
  1926  };
  1927  
  1928  defineProperties.supportsDescriptors = !!supportsDescriptors;
  1929  
  1930  module.exports = defineProperties;
  1931  
  1932  },{"foreach":47,"object-keys":50}],47:[function(_dereq_,module,exports){
  1933  
  1934  var hasOwn = Object.prototype.hasOwnProperty;
  1935  var toString = Object.prototype.toString;
  1936  
  1937  module.exports = function forEach (obj, fn, ctx) {
  1938      if (toString.call(fn) !== '[object Function]') {
  1939          throw new TypeError('iterator must be a function');
  1940      }
  1941      var l = obj.length;
  1942      if (l === +l) {
  1943          for (var i = 0; i < l; i++) {
  1944              fn.call(ctx, obj[i], i, obj);
  1945          }
  1946      } else {
  1947          for (var k in obj) {
  1948              if (hasOwn.call(obj, k)) {
  1949                  fn.call(ctx, obj[k], k, obj);
  1950              }
  1951          }
  1952      }
  1953  };
  1954  
  1955  
  1956  },{}],48:[function(_dereq_,module,exports){
  1957  var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
  1958  var slice = Array.prototype.slice;
  1959  var toStr = Object.prototype.toString;
  1960  var funcType = '[object Function]';
  1961  
  1962  module.exports = function bind(that) {
  1963      var target = this;
  1964      if (typeof target !== 'function' || toStr.call(target) !== funcType) {
  1965          throw new TypeError(ERROR_MESSAGE + target);
  1966      }
  1967      var args = slice.call(arguments, 1);
  1968  
  1969      var bound;
  1970      var binder = function () {
  1971          if (this instanceof bound) {
  1972              var result = target.apply(
  1973                  this,
  1974                  args.concat(slice.call(arguments))
  1975              );
  1976              if (Object(result) === result) {
  1977                  return result;
  1978              }
  1979              return this;
  1980          } else {
  1981              return target.apply(
  1982                  that,
  1983                  args.concat(slice.call(arguments))
  1984              );
  1985          }
  1986      };
  1987  
  1988      var boundLength = Math.max(0, target.length - args.length);
  1989      var boundArgs = [];
  1990      for (var i = 0; i < boundLength; i++) {
  1991          boundArgs.push('$' + i);
  1992      }
  1993  
  1994      bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder);
  1995  
  1996      if (target.prototype) {
  1997          var Empty = function Empty() {};
  1998          Empty.prototype = target.prototype;
  1999          bound.prototype = new Empty();
  2000          Empty.prototype = null;
  2001      }
  2002  
  2003      return bound;
  2004  };
  2005  
  2006  },{}],49:[function(_dereq_,module,exports){
  2007  var implementation = _dereq_('./implementation');
  2008  
  2009  module.exports = Function.prototype.bind || implementation;
  2010  
  2011  },{"./implementation":48}],50:[function(_dereq_,module,exports){
  2012  'use strict';
  2013  
  2014  // modified from https://github.com/es-shims/es5-shim
  2015  var has = Object.prototype.hasOwnProperty;
  2016  var toStr = Object.prototype.toString;
  2017  var slice = Array.prototype.slice;
  2018  var isArgs = _dereq_('./isArguments');
  2019  var hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString');
  2020  var hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype');
  2021  var dontEnums = [
  2022  	'toString',
  2023  	'toLocaleString',
  2024  	'valueOf',
  2025  	'hasOwnProperty',
  2026  	'isPrototypeOf',
  2027  	'propertyIsEnumerable',
  2028  	'constructor'
  2029  ];
  2030  var equalsConstructorPrototype = function (o) {
  2031  	var ctor = o.constructor;
  2032  	return ctor && ctor.prototype === o;
  2033  };
  2034  var blacklistedKeys = {
  2035  	$console: true,
  2036  	$frame: true,
  2037  	$frameElement: true,
  2038  	$frames: true,
  2039  	$parent: true,
  2040  	$self: true,
  2041  	$webkitIndexedDB: true,
  2042  	$webkitStorageInfo: true,
  2043  	$window: true
  2044  };
  2045  var hasAutomationEqualityBug = (function () {
  2046  	/* global window */
  2047  	if (typeof window === 'undefined') { return false; }
  2048  	for (var k in window) {
  2049  		try {
  2050  			if (!blacklistedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
  2051  				try {
  2052  					equalsConstructorPrototype(window[k]);
  2053  				} catch (e) {
  2054  					return true;
  2055  				}
  2056  			}
  2057  		} catch (e) {
  2058  			return true;
  2059  		}
  2060  	}
  2061  	return false;
  2062  }());
  2063  var equalsConstructorPrototypeIfNotBuggy = function (o) {
  2064  	/* global window */
  2065  	if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
  2066  		return equalsConstructorPrototype(o);
  2067  	}
  2068  	try {
  2069  		return equalsConstructorPrototype(o);
  2070  	} catch (e) {
  2071  		return false;
  2072  	}
  2073  };
  2074  
  2075  var keysShim = function keys(object) {
  2076  	var isObject = object !== null && typeof object === 'object';
  2077  	var isFunction = toStr.call(object) === '[object Function]';
  2078  	var isArguments = isArgs(object);
  2079  	var isString = isObject && toStr.call(object) === '[object String]';
  2080  	var theKeys = [];
  2081  
  2082  	if (!isObject && !isFunction && !isArguments) {
  2083  		throw new TypeError('Object.keys called on a non-object');
  2084  	}
  2085  
  2086  	var skipProto = hasProtoEnumBug && isFunction;
  2087  	if (isString && object.length > 0 && !has.call(object, 0)) {
  2088  		for (var i = 0; i < object.length; ++i) {
  2089  			theKeys.push(String(i));
  2090  		}
  2091  	}
  2092  
  2093  	if (isArguments && object.length > 0) {
  2094  		for (var j = 0; j < object.length; ++j) {
  2095  			theKeys.push(String(j));
  2096  		}
  2097  	} else {
  2098  		for (var name in object) {
  2099  			if (!(skipProto && name === 'prototype') && has.call(object, name)) {
  2100  				theKeys.push(String(name));
  2101  			}
  2102  		}
  2103  	}
  2104  
  2105  	if (hasDontEnumBug) {
  2106  		var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
  2107  
  2108  		for (var k = 0; k < dontEnums.length; ++k) {
  2109  			if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
  2110  				theKeys.push(dontEnums[k]);
  2111  			}
  2112  		}
  2113  	}
  2114  	return theKeys;
  2115  };
  2116  
  2117  keysShim.shim = function shimObjectKeys() {
  2118  	if (Object.keys) {
  2119  		var keysWorksWithArguments = (function () {
  2120  			// Safari 5.0 bug
  2121  			return (Object.keys(arguments) || '').length === 2;
  2122  		}(1, 2));
  2123  		if (!keysWorksWithArguments) {
  2124  			var originalKeys = Object.keys;
  2125  			Object.keys = function keys(object) {
  2126  				if (isArgs(object)) {
  2127  					return originalKeys(slice.call(object));
  2128  				} else {
  2129  					return originalKeys(object);
  2130  				}
  2131  			};
  2132  		}
  2133  	} else {
  2134  		Object.keys = keysShim;
  2135  	}
  2136  	return Object.keys || keysShim;
  2137  };
  2138  
  2139  module.exports = keysShim;
  2140  
  2141  },{"./isArguments":51}],51:[function(_dereq_,module,exports){
  2142  'use strict';
  2143  
  2144  var toStr = Object.prototype.toString;
  2145  
  2146  module.exports = function isArguments(value) {
  2147  	var str = toStr.call(value);
  2148  	var isArgs = str === '[object Arguments]';
  2149  	if (!isArgs) {
  2150  		isArgs = str !== '[object Array]' &&
  2151  			value !== null &&
  2152  			typeof value === 'object' &&
  2153  			typeof value.length === 'number' &&
  2154  			value.length >= 0 &&
  2155  			toStr.call(value.callee) === '[object Function]';
  2156  	}
  2157  	return isArgs;
  2158  };
  2159  
  2160  },{}],52:[function(_dereq_,module,exports){
  2161  'use strict';
  2162  
  2163  var implementation = _dereq_('./implementation');
  2164  
  2165  var lacksProperEnumerationOrder = function () {
  2166  	if (!Object.assign) {
  2167  		return false;
  2168  	}
  2169  	// v8, specifically in node 4.x, has a bug with incorrect property enumeration order
  2170  	// note: this does not detect the bug unless there's 20 characters
  2171  	var str = 'abcdefghijklmnopqrst';
  2172  	var letters = str.split('');
  2173  	var map = {};
  2174  	for (var i = 0; i < letters.length; ++i) {
  2175  		map[letters[i]] = letters[i];
  2176  	}
  2177  	var obj = Object.assign({}, map);
  2178  	var actual = '';
  2179  	for (var k in obj) {
  2180  		actual += k;
  2181  	}
  2182  	return str !== actual;
  2183  };
  2184  
  2185  var assignHasPendingExceptions = function () {
  2186  	if (!Object.assign || !Object.preventExtensions) {
  2187  		return false;
  2188  	}
  2189  	// Firefox 37 still has "pending exception" logic in its Object.assign implementation,
  2190  	// which is 72% slower than our shim, and Firefox 40's native implementation.
  2191  	var thrower = Object.preventExtensions({ 1: 2 });
  2192  	try {
  2193  		Object.assign(thrower, 'xy');
  2194  	} catch (e) {
  2195  		return thrower[1] === 'y';
  2196  	}
  2197  };
  2198  
  2199  module.exports = function getPolyfill() {
  2200  	if (!Object.assign) {
  2201  		return implementation;
  2202  	}
  2203  	if (lacksProperEnumerationOrder()) {
  2204  		return implementation;
  2205  	}
  2206  	if (assignHasPendingExceptions()) {
  2207  		return implementation;
  2208  	}
  2209  	return Object.assign;
  2210  };
  2211  
  2212  },{"./implementation":44}],53:[function(_dereq_,module,exports){
  2213  'use strict';
  2214  
  2215  var define = _dereq_('define-properties');
  2216  var getPolyfill = _dereq_('./polyfill');
  2217  
  2218  module.exports = function shimAssign() {
  2219  	var polyfill = getPolyfill();
  2220  	define(
  2221  		Object,
  2222  		{ assign: polyfill },
  2223  		{ assign: function () { return Object.assign !== polyfill; } }
  2224  	);
  2225  	return polyfill;
  2226  };
  2227  
  2228  },{"./polyfill":52,"define-properties":46}],54:[function(_dereq_,module,exports){
  2229  module.exports = SafeParseTuple
  2230  
  2231  function SafeParseTuple(obj, reviver) {
  2232      var json
  2233      var error = null
  2234  
  2235      try {
  2236          json = JSON.parse(obj, reviver)
  2237      } catch (err) {
  2238          error = err
  2239      }
  2240  
  2241      return [error, json]
  2242  }
  2243  
  2244  },{}],55:[function(_dereq_,module,exports){
  2245  function clean (s) {
  2246    return s.replace(/\n\r?\s*/g, '')
  2247  }
  2248  
  2249  
  2250  module.exports = function tsml (sa) {
  2251    var s = ''
  2252      , i = 0
  2253  
  2254    for (; i < arguments.length; i++)
  2255      s += clean(sa[i]) + (arguments[i + 1] || '')
  2256  
  2257    return s
  2258  }
  2259  },{}],56:[function(_dereq_,module,exports){
  2260  "use strict";
  2261  var window = _dereq_("global/window")
  2262  var once = _dereq_("once")
  2263  var isFunction = _dereq_("is-function")
  2264  var parseHeaders = _dereq_("parse-headers")
  2265  var xtend = _dereq_("xtend")
  2266  
  2267  module.exports = createXHR
  2268  createXHR.XMLHttpRequest = window.XMLHttpRequest || noop
  2269  createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest
  2270  
  2271  forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) {
  2272      createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) {
  2273          options = initParams(uri, options, callback)
  2274          options.method = method.toUpperCase()
  2275          return _createXHR(options)
  2276      }
  2277  })
  2278  
  2279  function forEachArray(array, iterator) {
  2280      for (var i = 0; i < array.length; i++) {
  2281          iterator(array[i])
  2282      }
  2283  }
  2284  
  2285  function isEmpty(obj){
  2286      for(var i in obj){
  2287          if(obj.hasOwnProperty(i)) return false
  2288      }
  2289      return true
  2290  }
  2291  
  2292  function initParams(uri, options, callback) {
  2293      var params = uri
  2294  
  2295      if (isFunction(options)) {
  2296          callback = options
  2297          if (typeof uri === "string") {
  2298              params = {uri:uri}
  2299          }
  2300      } else {
  2301          params = xtend(options, {uri: uri})
  2302      }
  2303  
  2304      params.callback = callback
  2305      return params
  2306  }
  2307  
  2308  function createXHR(uri, options, callback) {
  2309      options = initParams(uri, options, callback)
  2310      return _createXHR(options)
  2311  }
  2312  
  2313  function _createXHR(options) {
  2314      var callback = options.callback
  2315      if(typeof callback === "undefined"){
  2316          throw new Error("callback argument missing")
  2317      }
  2318      callback = once(callback)
  2319  
  2320      function readystatechange() {
  2321          if (xhr.readyState === 4) {
  2322              loadFunc()
  2323          }
  2324      }
  2325  
  2326      function getBody() {
  2327          // Chrome with requestType=blob throws errors arround when even testing access to responseText
  2328          var body = undefined
  2329  
  2330          if (xhr.response) {
  2331              body = xhr.response
  2332          } else if (xhr.responseType === "text" || !xhr.responseType) {
  2333              body = xhr.responseText || xhr.responseXML
  2334          }
  2335  
  2336          if (isJson) {
  2337              try {
  2338                  body = JSON.parse(body)
  2339              } catch (e) {}
  2340          }
  2341  
  2342          return body
  2343      }
  2344  
  2345      var failureResponse = {
  2346                  body: undefined,
  2347                  headers: {},
  2348                  statusCode: 0,
  2349                  method: method,
  2350                  url: uri,
  2351                  rawRequest: xhr
  2352              }
  2353  
  2354      function errorFunc(evt) {
  2355          clearTimeout(timeoutTimer)
  2356          if(!(evt instanceof Error)){
  2357              evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") )
  2358          }
  2359          evt.statusCode = 0
  2360          callback(evt, failureResponse)
  2361      }
  2362  
  2363      // will load the data & process the response in a special response object
  2364      function loadFunc() {
  2365          if (aborted) return
  2366          var status
  2367          clearTimeout(timeoutTimer)
  2368          if(options.useXDR && xhr.status===undefined) {
  2369              //IE8 CORS GET successful response doesn't have a status field, but body is fine
  2370              status = 200
  2371          } else {
  2372              status = (xhr.status === 1223 ? 204 : xhr.status)
  2373          }
  2374          var response = failureResponse
  2375          var err = null
  2376  
  2377          if (status !== 0){
  2378              response = {
  2379                  body: getBody(),
  2380                  statusCode: status,
  2381                  method: method,
  2382                  headers: {},
  2383                  url: uri,
  2384                  rawRequest: xhr
  2385              }
  2386              if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
  2387                  response.headers = parseHeaders(xhr.getAllResponseHeaders())
  2388              }
  2389          } else {
  2390              err = new Error("Internal XMLHttpRequest Error")
  2391          }
  2392          callback(err, response, response.body)
  2393  
  2394      }
  2395  
  2396      var xhr = options.xhr || null
  2397  
  2398      if (!xhr) {
  2399          if (options.cors || options.useXDR) {
  2400              xhr = new createXHR.XDomainRequest()
  2401          }else{
  2402              xhr = new createXHR.XMLHttpRequest()
  2403          }
  2404      }
  2405  
  2406      var key
  2407      var aborted
  2408      var uri = xhr.url = options.uri || options.url
  2409      var method = xhr.method = options.method || "GET"
  2410      var body = options.body || options.data || null
  2411      var headers = xhr.headers = options.headers || {}
  2412      var sync = !!options.sync
  2413      var isJson = false
  2414      var timeoutTimer
  2415  
  2416      if ("json" in options) {
  2417          isJson = true
  2418          headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user
  2419          if (method !== "GET" && method !== "HEAD") {
  2420              headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user
  2421              body = JSON.stringify(options.json)
  2422          }
  2423      }
  2424  
  2425      xhr.onreadystatechange = readystatechange
  2426      xhr.onload = loadFunc
  2427      xhr.onerror = errorFunc
  2428      // IE9 must have onprogress be set to a unique function.
  2429      xhr.onprogress = function () {
  2430          // IE must die
  2431      }
  2432      xhr.ontimeout = errorFunc
  2433      xhr.open(method, uri, !sync, options.username, options.password)
  2434      //has to be after open
  2435      if(!sync) {
  2436          xhr.withCredentials = !!options.withCredentials
  2437      }
  2438      // Cannot set timeout with sync request
  2439      // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly
  2440      // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent
  2441      if (!sync && options.timeout > 0 ) {
  2442          timeoutTimer = setTimeout(function(){
  2443              aborted=true//IE9 may still call readystatechange
  2444              xhr.abort("timeout")
  2445              var e = new Error("XMLHttpRequest timeout")
  2446              e.code = "ETIMEDOUT"
  2447              errorFunc(e)
  2448          }, options.timeout )
  2449      }
  2450  
  2451      if (xhr.setRequestHeader) {
  2452          for(key in headers){
  2453              if(headers.hasOwnProperty(key)){
  2454                  xhr.setRequestHeader(key, headers[key])
  2455              }
  2456          }
  2457      } else if (options.headers && !isEmpty(options.headers)) {
  2458          throw new Error("Headers cannot be set on an XDomainRequest object")
  2459      }
  2460  
  2461      if ("responseType" in options) {
  2462          xhr.responseType = options.responseType
  2463      }
  2464  
  2465      if ("beforeSend" in options &&
  2466          typeof options.beforeSend === "function"
  2467      ) {
  2468          options.beforeSend(xhr)
  2469      }
  2470  
  2471      xhr.send(body)
  2472  
  2473      return xhr
  2474  
  2475  
  2476  }
  2477  
  2478  function noop() {}
  2479  
  2480  },{"global/window":2,"is-function":57,"once":58,"parse-headers":61,"xtend":62}],57:[function(_dereq_,module,exports){
  2481  module.exports = isFunction
  2482  
  2483  var toString = Object.prototype.toString
  2484  
  2485  function isFunction (fn) {
  2486    var string = toString.call(fn)
  2487    return string === '[object Function]' ||
  2488      (typeof fn === 'function' && string !== '[object RegExp]') ||
  2489      (typeof window !== 'undefined' &&
  2490       // IE8 and below
  2491       (fn === window.setTimeout ||
  2492        fn === window.alert ||
  2493        fn === window.confirm ||
  2494        fn === window.prompt))
  2495  };
  2496  
  2497  },{}],58:[function(_dereq_,module,exports){
  2498  module.exports = once
  2499  
  2500  once.proto = once(function () {
  2501    Object.defineProperty(Function.prototype, 'once', {
  2502      value: function () {
  2503        return once(this)
  2504      },
  2505      configurable: true
  2506    })
  2507  })
  2508  
  2509  function once (fn) {
  2510    var called = false
  2511    return function () {
  2512      if (called) return
  2513      called = true
  2514      return fn.apply(this, arguments)
  2515    }
  2516  }
  2517  
  2518  },{}],59:[function(_dereq_,module,exports){
  2519  var isFunction = _dereq_('is-function')
  2520  
  2521  module.exports = forEach
  2522  
  2523  var toString = Object.prototype.toString
  2524  var hasOwnProperty = Object.prototype.hasOwnProperty
  2525  
  2526  function forEach(list, iterator, context) {
  2527      if (!isFunction(iterator)) {
  2528          throw new TypeError('iterator must be a function')
  2529      }
  2530  
  2531      if (arguments.length < 3) {
  2532          context = this
  2533      }
  2534      
  2535      if (toString.call(list) === '[object Array]')
  2536          forEachArray(list, iterator, context)
  2537      else if (typeof list === 'string')
  2538          forEachString(list, iterator, context)
  2539      else
  2540          forEachObject(list, iterator, context)
  2541  }
  2542  
  2543  function forEachArray(array, iterator, context) {
  2544      for (var i = 0, len = array.length; i < len; i++) {
  2545          if (hasOwnProperty.call(array, i)) {
  2546              iterator.call(context, array[i], i, array)
  2547          }
  2548      }
  2549  }
  2550  
  2551  function forEachString(string, iterator, context) {
  2552      for (var i = 0, len = string.length; i < len; i++) {
  2553          // no such thing as a sparse string.
  2554          iterator.call(context, string.charAt(i), i, string)
  2555      }
  2556  }
  2557  
  2558  function forEachObject(object, iterator, context) {
  2559      for (var k in object) {
  2560          if (hasOwnProperty.call(object, k)) {
  2561              iterator.call(context, object[k], k, object)
  2562          }
  2563      }
  2564  }
  2565  
  2566  },{"is-function":57}],60:[function(_dereq_,module,exports){
  2567  
  2568  exports = module.exports = trim;
  2569  
  2570  function trim(str){
  2571    return str.replace(/^\s*|\s*$/g, '');
  2572  }
  2573  
  2574  exports.left = function(str){
  2575    return str.replace(/^\s*/, '');
  2576  };
  2577  
  2578  exports.right = function(str){
  2579    return str.replace(/\s*$/, '');
  2580  };
  2581  
  2582  },{}],61:[function(_dereq_,module,exports){
  2583  var trim = _dereq_('trim')
  2584    , forEach = _dereq_('for-each')
  2585    , isArray = function(arg) {
  2586        return Object.prototype.toString.call(arg) === '[object Array]';
  2587      }
  2588  
  2589  module.exports = function (headers) {
  2590    if (!headers)
  2591      return {}
  2592  
  2593    var result = {}
  2594  
  2595    forEach(
  2596        trim(headers).split('\n')
  2597      , function (row) {
  2598          var index = row.indexOf(':')
  2599            , key = trim(row.slice(0, index)).toLowerCase()
  2600            , value = trim(row.slice(index + 1))
  2601  
  2602          if (typeof(result[key]) === 'undefined') {
  2603            result[key] = value
  2604          } else if (isArray(result[key])) {
  2605            result[key].push(value)
  2606          } else {
  2607            result[key] = [ result[key], value ]
  2608          }
  2609        }
  2610    )
  2611  
  2612    return result
  2613  }
  2614  },{"for-each":59,"trim":60}],62:[function(_dereq_,module,exports){
  2615  module.exports = extend
  2616  
  2617  var hasOwnProperty = Object.prototype.hasOwnProperty;
  2618  
  2619  function extend() {
  2620      var target = {}
  2621  
  2622      for (var i = 0; i < arguments.length; i++) {
  2623          var source = arguments[i]
  2624  
  2625          for (var key in source) {
  2626              if (hasOwnProperty.call(source, key)) {
  2627                  target[key] = source[key]
  2628              }
  2629          }
  2630      }
  2631  
  2632      return target
  2633  }
  2634  
  2635  },{}],63:[function(_dereq_,module,exports){
  2636  /**
  2637   * @file big-play-button.js
  2638   */
  2639  'use strict';
  2640  
  2641  exports.__esModule = true;
  2642  
  2643  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2644  
  2645  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  2646  
  2647  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  2648  
  2649  var _buttonJs = _dereq_('./button.js');
  2650  
  2651  var _buttonJs2 = _interopRequireDefault(_buttonJs);
  2652  
  2653  var _componentJs = _dereq_('./component.js');
  2654  
  2655  var _componentJs2 = _interopRequireDefault(_componentJs);
  2656  
  2657  /**
  2658   * Initial play button. Shows before the video has played. The hiding of the
  2659   * big play button is done via CSS and player states.
  2660   *
  2661   * @param {Object} player  Main Player
  2662   * @param {Object=} options Object of option names and values
  2663   * @extends Button
  2664   * @class BigPlayButton
  2665   */
  2666  
  2667  var BigPlayButton = (function (_Button) {
  2668    _inherits(BigPlayButton, _Button);
  2669  
  2670    function BigPlayButton(player, options) {
  2671      _classCallCheck(this, BigPlayButton);
  2672  
  2673      _Button.call(this, player, options);
  2674    }
  2675  
  2676    /**
  2677     * Allow sub components to stack CSS class names
  2678     *
  2679     * @return {String} The constructed class name
  2680     * @method buildCSSClass
  2681     */
  2682  
  2683    BigPlayButton.prototype.buildCSSClass = function buildCSSClass() {
  2684      return 'vjs-big-play-button';
  2685    };
  2686  
  2687    /**
  2688     * Handles click for play
  2689     *
  2690     * @method handleClick
  2691     */
  2692  
  2693    BigPlayButton.prototype.handleClick = function handleClick() {
  2694      this.player_.play();
  2695    };
  2696  
  2697    return BigPlayButton;
  2698  })(_buttonJs2['default']);
  2699  
  2700  BigPlayButton.prototype.controlText_ = 'Play Video';
  2701  
  2702  _componentJs2['default'].registerComponent('BigPlayButton', BigPlayButton);
  2703  exports['default'] = BigPlayButton;
  2704  module.exports = exports['default'];
  2705  
  2706  },{"./button.js":64,"./component.js":67}],64:[function(_dereq_,module,exports){
  2707  /**
  2708   * @file button.js
  2709   */
  2710  'use strict';
  2711  
  2712  exports.__esModule = true;
  2713  
  2714  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  2715  
  2716  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2717  
  2718  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  2719  
  2720  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  2721  
  2722  var _clickableComponentJs = _dereq_('./clickable-component.js');
  2723  
  2724  var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
  2725  
  2726  var _component = _dereq_('./component');
  2727  
  2728  var _component2 = _interopRequireDefault(_component);
  2729  
  2730  var _utilsEventsJs = _dereq_('./utils/events.js');
  2731  
  2732  var Events = _interopRequireWildcard(_utilsEventsJs);
  2733  
  2734  var _utilsFnJs = _dereq_('./utils/fn.js');
  2735  
  2736  var Fn = _interopRequireWildcard(_utilsFnJs);
  2737  
  2738  var _utilsLogJs = _dereq_('./utils/log.js');
  2739  
  2740  var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
  2741  
  2742  var _globalDocument = _dereq_('global/document');
  2743  
  2744  var _globalDocument2 = _interopRequireDefault(_globalDocument);
  2745  
  2746  var _objectAssign = _dereq_('object.assign');
  2747  
  2748  var _objectAssign2 = _interopRequireDefault(_objectAssign);
  2749  
  2750  /**
  2751   * Base class for all buttons
  2752   *
  2753   * @param {Object} player  Main Player
  2754   * @param {Object=} options Object of option names and values
  2755   * @extends ClickableComponent
  2756   * @class Button
  2757   */
  2758  
  2759  var Button = (function (_ClickableComponent) {
  2760    _inherits(Button, _ClickableComponent);
  2761  
  2762    function Button(player, options) {
  2763      _classCallCheck(this, Button);
  2764  
  2765      _ClickableComponent.call(this, player, options);
  2766    }
  2767  
  2768    /**
  2769     * Create the component's DOM element
  2770     *
  2771     * @param {String=} type Element's node type. e.g. 'div'
  2772     * @param {Object=} props An object of properties that should be set on the element
  2773     * @param {Object=} attributes An object of attributes that should be set on the element
  2774     * @return {Element}
  2775     * @method createEl
  2776     */
  2777  
  2778    Button.prototype.createEl = function createEl() {
  2779      var tag = arguments.length <= 0 || arguments[0] === undefined ? 'button' : arguments[0];
  2780      var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
  2781      var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
  2782  
  2783      props = _objectAssign2['default']({
  2784        className: this.buildCSSClass()
  2785      }, props);
  2786  
  2787      if (tag !== 'button') {
  2788        _utilsLogJs2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.');
  2789  
  2790        // Add properties for clickable element which is not a native HTML button
  2791        props = _objectAssign2['default']({
  2792          tabIndex: 0
  2793        }, props);
  2794  
  2795        // Add ARIA attributes for clickable element which is not a native HTML button
  2796        attributes = _objectAssign2['default']({
  2797          role: 'button'
  2798        }, attributes);
  2799      }
  2800  
  2801      // Add attributes for button element
  2802      attributes = _objectAssign2['default']({
  2803        type: 'button', // Necessary since the default button type is "submit"
  2804        'aria-live': 'polite' // let the screen reader user know that the text of the button may change
  2805      }, attributes);
  2806  
  2807      var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes);
  2808  
  2809      this.createControlTextEl(el);
  2810  
  2811      return el;
  2812    };
  2813  
  2814    /**
  2815     * Adds a child component inside this button
  2816     *
  2817     * @param {String|Component} child The class name or instance of a child to add
  2818     * @param {Object=} options Options, including options to be passed to children of the child.
  2819     * @return {Component} The child component (created by this process if a string was used)
  2820     * @deprecated
  2821     * @method addChild
  2822     */
  2823  
  2824    Button.prototype.addChild = function addChild(child) {
  2825      var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
  2826  
  2827      var className = this.constructor.name;
  2828      _utilsLogJs2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.');
  2829  
  2830      // Avoid the error message generated by ClickableComponent's addChild method
  2831      return _component2['default'].prototype.addChild.call(this, child, options);
  2832    };
  2833  
  2834    /**
  2835     * Handle KeyPress (document level) - Extend with specific functionality for button
  2836     *
  2837     * @method handleKeyPress
  2838     */
  2839  
  2840    Button.prototype.handleKeyPress = function handleKeyPress(event) {
  2841      // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button.
  2842      if (event.which === 32 || event.which === 13) {} else {
  2843        _ClickableComponent.prototype.handleKeyPress.call(this, event); // Pass keypress handling up for unsupported keys
  2844      }
  2845    };
  2846  
  2847    return Button;
  2848  })(_clickableComponentJs2['default']);
  2849  
  2850  _component2['default'].registerComponent('Button', Button);
  2851  exports['default'] = Button;
  2852  module.exports = exports['default'];
  2853  
  2854  },{"./clickable-component.js":65,"./component":67,"./utils/events.js":135,"./utils/fn.js":136,"./utils/log.js":139,"global/document":1,"object.assign":45}],65:[function(_dereq_,module,exports){
  2855  /**
  2856   * @file button.js
  2857   */
  2858  'use strict';
  2859  
  2860  exports.__esModule = true;
  2861  
  2862  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  2863  
  2864  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2865  
  2866  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  2867  
  2868  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  2869  
  2870  var _component = _dereq_('./component');
  2871  
  2872  var _component2 = _interopRequireDefault(_component);
  2873  
  2874  var _utilsDomJs = _dereq_('./utils/dom.js');
  2875  
  2876  var Dom = _interopRequireWildcard(_utilsDomJs);
  2877  
  2878  var _utilsEventsJs = _dereq_('./utils/events.js');
  2879  
  2880  var Events = _interopRequireWildcard(_utilsEventsJs);
  2881  
  2882  var _utilsFnJs = _dereq_('./utils/fn.js');
  2883  
  2884  var Fn = _interopRequireWildcard(_utilsFnJs);
  2885  
  2886  var _utilsLogJs = _dereq_('./utils/log.js');
  2887  
  2888  var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
  2889  
  2890  var _globalDocument = _dereq_('global/document');
  2891  
  2892  var _globalDocument2 = _interopRequireDefault(_globalDocument);
  2893  
  2894  var _objectAssign = _dereq_('object.assign');
  2895  
  2896  var _objectAssign2 = _interopRequireDefault(_objectAssign);
  2897  
  2898  /**
  2899   * Clickable Component which is clickable or keyboard actionable, but is not a native HTML button
  2900   *
  2901   * @param {Object} player  Main Player
  2902   * @param {Object=} options Object of option names and values
  2903   * @extends Component
  2904   * @class ClickableComponent
  2905   */
  2906  
  2907  var ClickableComponent = (function (_Component) {
  2908    _inherits(ClickableComponent, _Component);
  2909  
  2910    function ClickableComponent(player, options) {
  2911      _classCallCheck(this, ClickableComponent);
  2912  
  2913      _Component.call(this, player, options);
  2914  
  2915      this.emitTapEvents();
  2916  
  2917      this.on('tap', this.handleClick);
  2918      this.on('click', this.handleClick);
  2919      this.on('focus', this.handleFocus);
  2920      this.on('blur', this.handleBlur);
  2921    }
  2922  
  2923    /**
  2924     * Create the component's DOM element
  2925     *
  2926     * @param {String=} type Element's node type. e.g. 'div'
  2927     * @param {Object=} props An object of properties that should be set on the element
  2928     * @param {Object=} attributes An object of attributes that should be set on the element
  2929     * @return {Element}
  2930     * @method createEl
  2931     */
  2932  
  2933    ClickableComponent.prototype.createEl = function createEl() {
  2934      var tag = arguments.length <= 0 || arguments[0] === undefined ? 'div' : arguments[0];
  2935      var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
  2936      var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
  2937  
  2938      props = _objectAssign2['default']({
  2939        className: this.buildCSSClass(),
  2940        tabIndex: 0
  2941      }, props);
  2942  
  2943      if (tag === 'button') {
  2944        _utilsLogJs2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.');
  2945      }
  2946  
  2947      // Add ARIA attributes for clickable element which is not a native HTML button
  2948      attributes = _objectAssign2['default']({
  2949        role: 'button',
  2950        'aria-live': 'polite' // let the screen reader user know that the text of the element may change
  2951      }, attributes);
  2952  
  2953      var el = _Component.prototype.createEl.call(this, tag, props, attributes);
  2954  
  2955      this.createControlTextEl(el);
  2956  
  2957      return el;
  2958    };
  2959  
  2960    /**
  2961     * create control text
  2962     *
  2963     * @param {Element} el Parent element for the control text
  2964     * @return {Element}
  2965     * @method controlText
  2966     */
  2967  
  2968    ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) {
  2969      this.controlTextEl_ = Dom.createEl('span', {
  2970        className: 'vjs-control-text'
  2971      });
  2972  
  2973      if (el) {
  2974        el.appendChild(this.controlTextEl_);
  2975      }
  2976  
  2977      this.controlText(this.controlText_);
  2978  
  2979      return this.controlTextEl_;
  2980    };
  2981  
  2982    /**
  2983     * Controls text - both request and localize
  2984     *
  2985     * @param {String} text Text for element
  2986     * @return {String}
  2987     * @method controlText
  2988     */
  2989  
  2990    ClickableComponent.prototype.controlText = function controlText(text) {
  2991      if (!text) return this.controlText_ || 'Need Text';
  2992  
  2993      this.controlText_ = text;
  2994      this.controlTextEl_.innerHTML = this.localize(this.controlText_);
  2995  
  2996      return this;
  2997    };
  2998  
  2999    /**
  3000     * Allows sub components to stack CSS class names
  3001     *
  3002     * @return {String}
  3003     * @method buildCSSClass
  3004     */
  3005  
  3006    ClickableComponent.prototype.buildCSSClass = function buildCSSClass() {
  3007      return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this);
  3008    };
  3009  
  3010    /**
  3011     * Adds a child component inside this clickable-component
  3012     *
  3013     * @param {String|Component} child The class name or instance of a child to add
  3014     * @param {Object=} options Options, including options to be passed to children of the child.
  3015     * @return {Component} The child component (created by this process if a string was used)
  3016     * @method addChild
  3017     */
  3018  
  3019    ClickableComponent.prototype.addChild = function addChild(child) {
  3020      var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
  3021  
  3022      // TODO: Fix adding an actionable child to a ClickableComponent; currently
  3023      // it will cause issues with assistive technology (e.g. screen readers)
  3024      // which support ARIA, since an element with role="button" cannot have
  3025      // actionable child elements.
  3026  
  3027      //let className = this.constructor.name;
  3028      //log.warn(`Adding a child to a ClickableComponent (${className}) can cause issues with assistive technology which supports ARIA, since an element with role="button" cannot have actionable child elements.`);
  3029  
  3030      return _Component.prototype.addChild.call(this, child, options);
  3031    };
  3032  
  3033    /**
  3034     * Enable the component element
  3035     *
  3036     * @return {Component}
  3037     * @method enable
  3038     */
  3039  
  3040    ClickableComponent.prototype.enable = function enable() {
  3041      this.removeClass('vjs-disabled');
  3042      this.el_.setAttribute('aria-disabled', 'false');
  3043      return this;
  3044    };
  3045  
  3046    /**
  3047     * Disable the component element
  3048     *
  3049     * @return {Component}
  3050     * @method disable
  3051     */
  3052  
  3053    ClickableComponent.prototype.disable = function disable() {
  3054      this.addClass('vjs-disabled');
  3055      this.el_.setAttribute('aria-disabled', 'true');
  3056      return this;
  3057    };
  3058  
  3059    /**
  3060     * Handle Click - Override with specific functionality for component
  3061     *
  3062     * @method handleClick
  3063     */
  3064  
  3065    ClickableComponent.prototype.handleClick = function handleClick() {};
  3066  
  3067    /**
  3068     * Handle Focus - Add keyboard functionality to element
  3069     *
  3070     * @method handleFocus
  3071     */
  3072  
  3073    ClickableComponent.prototype.handleFocus = function handleFocus() {
  3074      Events.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
  3075    };
  3076  
  3077    /**
  3078     * Handle KeyPress (document level) - Trigger click when Space or Enter key is pressed
  3079     *
  3080     * @method handleKeyPress
  3081     */
  3082  
  3083    ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) {
  3084      // Support Space (32) or Enter (13) key operation to fire a click event
  3085      if (event.which === 32 || event.which === 13) {
  3086        event.preventDefault();
  3087        this.handleClick(event);
  3088      } else if (_Component.prototype.handleKeyPress) {
  3089        _Component.prototype.handleKeyPress.call(this, event); // Pass keypress handling up for unsupported keys
  3090      }
  3091    };
  3092  
  3093    /**
  3094     * Handle Blur - Remove keyboard triggers
  3095     *
  3096     * @method handleBlur
  3097     */
  3098  
  3099    ClickableComponent.prototype.handleBlur = function handleBlur() {
  3100      Events.off(_globalDocument2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
  3101    };
  3102  
  3103    return ClickableComponent;
  3104  })(_component2['default']);
  3105  
  3106  _component2['default'].registerComponent('ClickableComponent', ClickableComponent);
  3107  exports['default'] = ClickableComponent;
  3108  module.exports = exports['default'];
  3109  
  3110  },{"./component":67,"./utils/dom.js":134,"./utils/events.js":135,"./utils/fn.js":136,"./utils/log.js":139,"global/document":1,"object.assign":45}],66:[function(_dereq_,module,exports){
  3111  'use strict';
  3112  
  3113  exports.__esModule = true;
  3114  
  3115  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3116  
  3117  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  3118  
  3119  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  3120  
  3121  var _button = _dereq_('./button');
  3122  
  3123  var _button2 = _interopRequireDefault(_button);
  3124  
  3125  var _component = _dereq_('./component');
  3126  
  3127  var _component2 = _interopRequireDefault(_component);
  3128  
  3129  /**
  3130   * The `CloseButton` component is a button which fires a "close" event
  3131   * when it is activated.
  3132   *
  3133   * @extends Button
  3134   * @class CloseButton
  3135   */
  3136  
  3137  var CloseButton = (function (_Button) {
  3138    _inherits(CloseButton, _Button);
  3139  
  3140    function CloseButton(player, options) {
  3141      _classCallCheck(this, CloseButton);
  3142  
  3143      _Button.call(this, player, options);
  3144      this.controlText(options && options.controlText || this.localize('Close'));
  3145    }
  3146  
  3147    CloseButton.prototype.buildCSSClass = function buildCSSClass() {
  3148      return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this);
  3149    };
  3150  
  3151    CloseButton.prototype.handleClick = function handleClick() {
  3152      this.trigger({ type: 'close', bubbles: false });
  3153    };
  3154  
  3155    return CloseButton;
  3156  })(_button2['default']);
  3157  
  3158  _component2['default'].registerComponent('CloseButton', CloseButton);
  3159  exports['default'] = CloseButton;
  3160  module.exports = exports['default'];
  3161  
  3162  },{"./button":64,"./component":67}],67:[function(_dereq_,module,exports){
  3163  /**
  3164   * @file component.js
  3165   *
  3166   * Player Component - Base class for all UI objects
  3167   */
  3168  
  3169  'use strict';
  3170  
  3171  exports.__esModule = true;
  3172  
  3173  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  3174  
  3175  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3176  
  3177  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  3178  
  3179  var _globalWindow = _dereq_('global/window');
  3180  
  3181  var _globalWindow2 = _interopRequireDefault(_globalWindow);
  3182  
  3183  var _utilsDomJs = _dereq_('./utils/dom.js');
  3184  
  3185  var Dom = _interopRequireWildcard(_utilsDomJs);
  3186  
  3187  var _utilsFnJs = _dereq_('./utils/fn.js');
  3188  
  3189  var Fn = _interopRequireWildcard(_utilsFnJs);
  3190  
  3191  var _utilsGuidJs = _dereq_('./utils/guid.js');
  3192  
  3193  var Guid = _interopRequireWildcard(_utilsGuidJs);
  3194  
  3195  var _utilsEventsJs = _dereq_('./utils/events.js');
  3196  
  3197  var Events = _interopRequireWildcard(_utilsEventsJs);
  3198  
  3199  var _utilsLogJs = _dereq_('./utils/log.js');
  3200  
  3201  var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
  3202  
  3203  var _utilsToTitleCaseJs = _dereq_('./utils/to-title-case.js');
  3204  
  3205  var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
  3206  
  3207  var _objectAssign = _dereq_('object.assign');
  3208  
  3209  var _objectAssign2 = _interopRequireDefault(_objectAssign);
  3210  
  3211  var _utilsMergeOptionsJs = _dereq_('./utils/merge-options.js');
  3212  
  3213  var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);
  3214  
  3215  /**
  3216   * Base UI Component class
  3217   * Components are embeddable UI objects that are represented by both a
  3218   * javascript object and an element in the DOM. They can be children of other
  3219   * components, and can have many children themselves.
  3220   * ```js
  3221   *     // adding a button to the player
  3222   *     var button = player.addChild('button');
  3223   *     button.el(); // -> button element
  3224   * ```
  3225   * ```html
  3226   *     <div class="video-js">
  3227   *       <div class="vjs-button">Button</div>
  3228   *     </div>
  3229   * ```
  3230   * Components are also event targets.
  3231   * ```js
  3232   *     button.on('click', function(){
  3233   *       console.log('Button Clicked!');
  3234   *     });
  3235   *     button.trigger('customevent');
  3236   * ```
  3237   *
  3238   * @param {Object} player  Main Player
  3239   * @param {Object=} options Object of option names and values
  3240   * @param {Function=} ready    Ready callback function
  3241   * @class Component
  3242   */
  3243  
  3244  var Component = (function () {
  3245    function Component(player, options, ready) {
  3246      _classCallCheck(this, Component);
  3247  
  3248      // The component might be the player itself and we can't pass `this` to super
  3249      if (!player && this.play) {
  3250        this.player_ = player = this; // eslint-disable-line
  3251      } else {
  3252          this.player_ = player;
  3253        }
  3254  
  3255      // Make a copy of prototype.options_ to protect against overriding defaults
  3256      this.options_ = _utilsMergeOptionsJs2['default']({}, this.options_);
  3257  
  3258      // Updated options with supplied options
  3259      options = this.options_ = _utilsMergeOptionsJs2['default'](this.options_, options);
  3260  
  3261      // Get ID from options or options element if one is supplied
  3262      this.id_ = options.id || options.el && options.el.id;
  3263  
  3264      // If there was no ID from the options, generate one
  3265      if (!this.id_) {
  3266        // Don't require the player ID function in the case of mock players
  3267        var id = player && player.id && player.id() || 'no_player';
  3268  
  3269        this.id_ = id + '_component_' + Guid.newGUID();
  3270      }
  3271  
  3272      this.name_ = options.name || null;
  3273  
  3274      // Create element if one wasn't provided in options
  3275      if (options.el) {
  3276        this.el_ = options.el;
  3277      } else if (options.createEl !== false) {
  3278        this.el_ = this.createEl();
  3279      }
  3280  
  3281      this.children_ = [];
  3282      this.childIndex_ = {};
  3283      this.childNameIndex_ = {};
  3284  
  3285      // Add any child components in options
  3286      if (options.initChildren !== false) {
  3287        this.initChildren();
  3288      }
  3289  
  3290      this.ready(ready);
  3291      // Don't want to trigger ready here or it will before init is actually
  3292      // finished for all children that run this constructor
  3293  
  3294      if (options.reportTouchActivity !== false) {
  3295        this.enableTouchActivity();
  3296      }
  3297    }
  3298  
  3299    /**
  3300     * Dispose of the component and all child components
  3301     *
  3302     * @method dispose
  3303     */
  3304  
  3305    Component.prototype.dispose = function dispose() {
  3306      this.trigger({ type: 'dispose', bubbles: false });
  3307  
  3308      // Dispose all children.
  3309      if (this.children_) {
  3310        for (var i = this.children_.length - 1; i >= 0; i--) {
  3311          if (this.children_[i].dispose) {
  3312            this.children_[i].dispose();
  3313          }
  3314        }
  3315      }
  3316  
  3317      // Delete child references
  3318      this.children_ = null;
  3319      this.childIndex_ = null;
  3320      this.childNameIndex_ = null;
  3321  
  3322      // Remove all event listeners.
  3323      this.off();
  3324  
  3325      // Remove element from DOM
  3326      if (this.el_.parentNode) {
  3327        this.el_.parentNode.removeChild(this.el_);
  3328      }
  3329  
  3330      Dom.removeElData(this.el_);
  3331      this.el_ = null;
  3332    };
  3333  
  3334    /**
  3335     * Return the component's player
  3336     *
  3337     * @return {Player}
  3338     * @method player
  3339     */
  3340  
  3341    Component.prototype.player = function player() {
  3342      return this.player_;
  3343    };
  3344  
  3345    /**
  3346     * Deep merge of options objects
  3347     * Whenever a property is an object on both options objects
  3348     * the two properties will be merged using mergeOptions.
  3349     *
  3350     * ```js
  3351     *     Parent.prototype.options_ = {
  3352     *       optionSet: {
  3353     *         'childOne': { 'foo': 'bar', 'asdf': 'fdsa' },
  3354     *         'childTwo': {},
  3355     *         'childThree': {}
  3356     *       }
  3357     *     }
  3358     *     newOptions = {
  3359     *       optionSet: {
  3360     *         'childOne': { 'foo': 'baz', 'abc': '123' }
  3361     *         'childTwo': null,
  3362     *         'childFour': {}
  3363     *       }
  3364     *     }
  3365     *
  3366     *     this.options(newOptions);
  3367     * ```
  3368     * RESULT
  3369     * ```js
  3370     *     {
  3371     *       optionSet: {
  3372     *         'childOne': { 'foo': 'baz', 'asdf': 'fdsa', 'abc': '123' },
  3373     *         'childTwo': null, // Disabled. Won't be initialized.
  3374     *         'childThree': {},
  3375     *         'childFour': {}
  3376     *       }
  3377     *     }
  3378     * ```
  3379     *
  3380     * @param  {Object} obj Object of new option values
  3381     * @return {Object}     A NEW object of this.options_ and obj merged
  3382     * @method options
  3383     */
  3384  
  3385    Component.prototype.options = function options(obj) {
  3386      _utilsLogJs2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0');
  3387  
  3388      if (!obj) {
  3389        return this.options_;
  3390      }
  3391  
  3392      this.options_ = _utilsMergeOptionsJs2['default'](this.options_, obj);
  3393      return this.options_;
  3394    };
  3395  
  3396    /**
  3397     * Get the component's DOM element
  3398     * ```js
  3399     *     var domEl = myComponent.el();
  3400     * ```
  3401     *
  3402     * @return {Element}
  3403     * @method el
  3404     */
  3405  
  3406    Component.prototype.el = function el() {
  3407      return this.el_;
  3408    };
  3409  
  3410    /**
  3411     * Create the component's DOM element
  3412     *
  3413     * @param  {String=} tagName  Element's node type. e.g. 'div'
  3414     * @param  {Object=} properties An object of properties that should be set
  3415     * @param  {Object=} attributes An object of attributes that should be set
  3416     * @return {Element}
  3417     * @method createEl
  3418     */
  3419  
  3420    Component.prototype.createEl = function createEl(tagName, properties, attributes) {
  3421      return Dom.createEl(tagName, properties, attributes);
  3422    };
  3423  
  3424    Component.prototype.localize = function localize(string) {
  3425      var code = this.player_.language && this.player_.language();
  3426      var languages = this.player_.languages && this.player_.languages();
  3427  
  3428      if (!code || !languages) {
  3429        return string;
  3430      }
  3431  
  3432      var language = languages[code];
  3433  
  3434      if (language && language[string]) {
  3435        return language[string];
  3436      }
  3437  
  3438      var primaryCode = code.split('-')[0];
  3439      var primaryLang = languages[primaryCode];
  3440  
  3441      if (primaryLang && primaryLang[string]) {
  3442        return primaryLang[string];
  3443      }
  3444  
  3445      return string;
  3446    };
  3447  
  3448    /**
  3449     * Return the component's DOM element where children are inserted.
  3450     * Will either be the same as el() or a new element defined in createEl().
  3451     *
  3452     * @return {Element}
  3453     * @method contentEl
  3454     */
  3455  
  3456    Component.prototype.contentEl = function contentEl() {
  3457      return this.contentEl_ || this.el_;
  3458    };
  3459  
  3460    /**
  3461     * Get the component's ID
  3462     * ```js
  3463     *     var id = myComponent.id();
  3464     * ```
  3465     *
  3466     * @return {String}
  3467     * @method id
  3468     */
  3469  
  3470    Component.prototype.id = function id() {
  3471      return this.id_;
  3472    };
  3473  
  3474    /**
  3475     * Get the component's name. The name is often used to reference the component.
  3476     * ```js
  3477     *     var name = myComponent.name();
  3478     * ```
  3479     *
  3480     * @return {String}
  3481     * @method name
  3482     */
  3483  
  3484    Component.prototype.name = function name() {
  3485      return this.name_;
  3486    };
  3487  
  3488    /**
  3489     * Get an array of all child components
  3490     * ```js
  3491     *     var kids = myComponent.children();
  3492     * ```
  3493     *
  3494     * @return {Array} The children
  3495     * @method children
  3496     */
  3497  
  3498    Component.prototype.children = function children() {
  3499      return this.children_;
  3500    };
  3501  
  3502    /**
  3503     * Returns a child component with the provided ID
  3504     *
  3505     * @return {Component}
  3506     * @method getChildById
  3507     */
  3508  
  3509    Component.prototype.getChildById = function getChildById(id) {
  3510      return this.childIndex_[id];
  3511    };
  3512  
  3513    /**
  3514     * Returns a child component with the provided name
  3515     *
  3516     * @return {Component}
  3517     * @method getChild
  3518     */
  3519  
  3520    Component.prototype.getChild = function getChild(name) {
  3521      return this.childNameIndex_[name];
  3522    };
  3523  
  3524    /**
  3525     * Adds a child component inside this component
  3526     * ```js
  3527     *     myComponent.el();
  3528     *     // -> <div class='my-component'></div>
  3529     *     myComponent.children();
  3530     *     // [empty array]
  3531     *
  3532     *     var myButton = myComponent.addChild('MyButton');
  3533     *     // -> <div class='my-component'><div class="my-button">myButton<div></div>
  3534     *     // -> myButton === myComponent.children()[0];
  3535     * ```
  3536     * Pass in options for child constructors and options for children of the child
  3537     * ```js
  3538     *     var myButton = myComponent.addChild('MyButton', {
  3539     *       text: 'Press Me',
  3540     *       buttonChildExample: {
  3541     *         buttonChildOption: true
  3542     *       }
  3543     *     });
  3544     * ```
  3545     *
  3546     * @param {String|Component} child The class name or instance of a child to add
  3547     * @param {Object=} options Options, including options to be passed to children of the child.
  3548     * @param {Number} index into our children array to attempt to add the child
  3549     * @return {Component} The child component (created by this process if a string was used)
  3550     * @method addChild
  3551     */
  3552  
  3553    Component.prototype.addChild = function addChild(child) {
  3554      var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
  3555      var index = arguments.length <= 2 || arguments[2] === undefined ? this.children_.length : arguments[2];
  3556  
  3557      var component = undefined;
  3558      var componentName = undefined;
  3559  
  3560      // If child is a string, create nt with options
  3561      if (typeof child === 'string') {
  3562        componentName = child;
  3563  
  3564        // Options can also be specified as a boolean, so convert to an empty object if false.
  3565        if (!options) {
  3566          options = {};
  3567        }
  3568  
  3569        // Same as above, but true is deprecated so show a warning.
  3570        if (options === true) {
  3571          _utilsLogJs2['default'].warn('Initializing a child component with `true` is deprecated. Children should be defined in an array when possible, but if necessary use an object instead of `true`.');
  3572          options = {};
  3573        }
  3574  
  3575        // If no componentClass in options, assume componentClass is the name lowercased
  3576        // (e.g. playButton)
  3577        var componentClassName = options.componentClass || _utilsToTitleCaseJs2['default'](componentName);
  3578  
  3579        // Set name through options
  3580        options.name = componentName;
  3581  
  3582        // Create a new object & element for this controls set
  3583        // If there's no .player_, this is a player
  3584        var ComponentClass = Component.getComponent(componentClassName);
  3585  
  3586        if (!ComponentClass) {
  3587          throw new Error('Component ' + componentClassName + ' does not exist');
  3588        }
  3589  
  3590        // data stored directly on the videojs object may be
  3591        // misidentified as a component to retain
  3592        // backwards-compatibility with 4.x. check to make sure the
  3593        // component class can be instantiated.
  3594        if (typeof ComponentClass !== 'function') {
  3595          return null;
  3596        }
  3597  
  3598        component = new ComponentClass(this.player_ || this, options);
  3599  
  3600        // child is a component instance
  3601      } else {
  3602          component = child;
  3603        }
  3604  
  3605      this.children_.splice(index, 0, component);
  3606  
  3607      if (typeof component.id === 'function') {
  3608        this.childIndex_[component.id()] = component;
  3609      }
  3610  
  3611      // If a name wasn't used to create the component, check if we can use the
  3612      // name function of the component
  3613      componentName = componentName || component.name && component.name();
  3614  
  3615      if (componentName) {
  3616        this.childNameIndex_[componentName] = component;
  3617      }
  3618  
  3619      // Add the UI object's element to the container div (box)
  3620      // Having an element is not required
  3621      if (typeof component.el === 'function' && component.el()) {
  3622        var childNodes = this.contentEl().children;
  3623        var refNode = childNodes[index] || null;
  3624        this.contentEl().insertBefore(component.el(), refNode);
  3625      }
  3626  
  3627      // Return so it can stored on parent object if desired.
  3628      return component;
  3629    };
  3630  
  3631    /**
  3632     * Remove a child component from this component's list of children, and the
  3633     * child component's element from this component's element
  3634     *
  3635     * @param  {Component} component Component to remove
  3636     * @method removeChild
  3637     */
  3638  
  3639    Component.prototype.removeChild = function removeChild(component) {
  3640      if (typeof component === 'string') {
  3641        component = this.getChild(component);
  3642      }
  3643  
  3644      if (!component || !this.children_) {
  3645        return;
  3646      }
  3647  
  3648      var childFound = false;
  3649  
  3650      for (var i = this.children_.length - 1; i >= 0; i--) {
  3651        if (this.children_[i] === component) {
  3652          childFound = true;
  3653          this.children_.splice(i, 1);
  3654          break;
  3655        }
  3656      }
  3657  
  3658      if (!childFound) {
  3659        return;
  3660      }
  3661  
  3662      this.childIndex_[component.id()] = null;
  3663      this.childNameIndex_[component.name()] = null;
  3664  
  3665      var compEl = component.el();
  3666  
  3667      if (compEl && compEl.parentNode === this.contentEl()) {
  3668        this.contentEl().removeChild(component.el());
  3669      }
  3670    };
  3671  
  3672    /**
  3673     * Add and initialize default child components from options
  3674     * ```js
  3675     *     // when an instance of MyComponent is created, all children in options
  3676     *     // will be added to the instance by their name strings and options
  3677     *     MyComponent.prototype.options_ = {
  3678     *       children: [
  3679     *         'myChildComponent'
  3680     *       ],
  3681     *       myChildComponent: {
  3682     *         myChildOption: true
  3683     *       }
  3684     *     };
  3685     *
  3686     *     // Or when creating the component
  3687     *     var myComp = new MyComponent(player, {
  3688     *       children: [
  3689     *         'myChildComponent'
  3690     *       ],
  3691     *       myChildComponent: {
  3692     *         myChildOption: true
  3693     *       }
  3694     *     });
  3695     * ```
  3696     * The children option can also be an array of
  3697     * child options objects (that also include a 'name' key).
  3698     * This can be used if you have two child components of the
  3699     * same type that need different options.
  3700     * ```js
  3701     *     var myComp = new MyComponent(player, {
  3702     *       children: [
  3703     *         'button',
  3704     *         {
  3705     *           name: 'button',
  3706     *           someOtherOption: true
  3707     *         },
  3708     *         {
  3709     *           name: 'button',
  3710     *           someOtherOption: false
  3711     *         }
  3712     *       ]
  3713     *     });
  3714     * ```
  3715     *
  3716     * @method initChildren
  3717     */
  3718  
  3719    Component.prototype.initChildren = function initChildren() {
  3720      var _this = this;
  3721  
  3722      var children = this.options_.children;
  3723  
  3724      if (children) {
  3725        (function () {
  3726          // `this` is `parent`
  3727          var parentOptions = _this.options_;
  3728  
  3729          var handleAdd = function handleAdd(child) {
  3730            var name = child.name;
  3731            var opts = child.opts;
  3732  
  3733            // Allow options for children to be set at the parent options
  3734            // e.g. videojs(id, { controlBar: false });
  3735            // instead of videojs(id, { children: { controlBar: false });
  3736            if (parentOptions[name] !== undefined) {
  3737              opts = parentOptions[name];
  3738            }
  3739  
  3740            // Allow for disabling default components
  3741            // e.g. options['children']['posterImage'] = false
  3742            if (opts === false) {
  3743              return;
  3744            }
  3745  
  3746            // Allow options to be passed as a simple boolean if no configuration
  3747            // is necessary.
  3748            if (opts === true) {
  3749              opts = {};
  3750            }
  3751  
  3752            // We also want to pass the original player options to each component as well so they don't need to
  3753            // reach back into the player for options later.
  3754            opts.playerOptions = _this.options_.playerOptions;
  3755  
  3756            // Create and add the child component.
  3757            // Add a direct reference to the child by name on the parent instance.
  3758            // If two of the same component are used, different names should be supplied
  3759            // for each
  3760            var newChild = _this.addChild(name, opts);
  3761            if (newChild) {
  3762              _this[name] = newChild;
  3763            }
  3764          };
  3765  
  3766          // Allow for an array of children details to passed in the options
  3767          var workingChildren = undefined;
  3768          var Tech = Component.getComponent('Tech');
  3769  
  3770          if (Array.isArray(children)) {
  3771            workingChildren = children;
  3772          } else {
  3773            workingChildren = Object.keys(children);
  3774          }
  3775  
  3776          workingChildren
  3777          // children that are in this.options_ but also in workingChildren  would
  3778          // give us extra children we do not want. So, we want to filter them out.
  3779          .concat(Object.keys(_this.options_).filter(function (child) {
  3780            return !workingChildren.some(function (wchild) {
  3781              if (typeof wchild === 'string') {
  3782                return child === wchild;
  3783              } else {
  3784                return child === wchild.name;
  3785              }
  3786            });
  3787          })).map(function (child) {
  3788            var name = undefined,
  3789                opts = undefined;
  3790  
  3791            if (typeof child === 'string') {
  3792              name = child;
  3793              opts = children[name] || _this.options_[name] || {};
  3794            } else {
  3795              name = child.name;
  3796              opts = child;
  3797            }
  3798  
  3799            return { name: name, opts: opts };
  3800          }).filter(function (child) {
  3801            // we have to make sure that child.name isn't in the techOrder since
  3802            // techs are registerd as Components but can't aren't compatible
  3803            // See https://github.com/videojs/video.js/issues/2772
  3804            var c = Component.getComponent(child.opts.componentClass || _utilsToTitleCaseJs2['default'](child.name));
  3805            return c && !Tech.isTech(c);
  3806          }).forEach(handleAdd);
  3807        })();
  3808      }
  3809    };
  3810  
  3811    /**
  3812     * Allows sub components to stack CSS class names
  3813     *
  3814     * @return {String} The constructed class name
  3815     * @method buildCSSClass
  3816     */
  3817  
  3818    Component.prototype.buildCSSClass = function buildCSSClass() {
  3819      // Child classes can include a function that does:
  3820      // return 'CLASS NAME' + this._super();
  3821      return '';
  3822    };
  3823  
  3824    /**
  3825     * Add an event listener to this component's element
  3826     * ```js
  3827     *     var myFunc = function(){
  3828     *       var myComponent = this;
  3829     *       // Do something when the event is fired
  3830     *     };
  3831     *
  3832     *     myComponent.on('eventType', myFunc);
  3833     * ```
  3834     * The context of myFunc will be myComponent unless previously bound.
  3835     * Alternatively, you can add a listener to another element or component.
  3836     * ```js
  3837     *     myComponent.on(otherElement, 'eventName', myFunc);
  3838     *     myComponent.on(otherComponent, 'eventName', myFunc);
  3839     * ```
  3840     * The benefit of using this over `VjsEvents.on(otherElement, 'eventName', myFunc)`
  3841     * and `otherComponent.on('eventName', myFunc)` is that this way the listeners
  3842     * will be automatically cleaned up when either component is disposed.
  3843     * It will also bind myComponent as the context of myFunc.
  3844     * **NOTE**: When using this on elements in the page other than window
  3845     * and document (both permanent), if you remove the element from the DOM
  3846     * you need to call `myComponent.trigger(el, 'dispose')` on it to clean up
  3847     * references to it and allow the browser to garbage collect it.
  3848     *
  3849     * @param  {String|Component} first   The event type or other component
  3850     * @param  {Function|String}      second  The event handler or event type
  3851     * @param  {Function}             third   The event handler
  3852     * @return {Component}
  3853     * @method on
  3854     */
  3855  
  3856    Component.prototype.on = function on(first, second, third) {
  3857      var _this2 = this;
  3858  
  3859      if (typeof first === 'string' || Array.isArray(first)) {
  3860        Events.on(this.el_, first, Fn.bind(this, second));
  3861  
  3862        // Targeting another component or element
  3863      } else {
  3864          (function () {
  3865            var target = first;
  3866            var type = second;
  3867            var fn = Fn.bind(_this2, third);
  3868  
  3869            // When this component is disposed, remove the listener from the other component
  3870            var removeOnDispose = function removeOnDispose() {
  3871              return _this2.off(target, type, fn);
  3872            };
  3873  
  3874            // Use the same function ID so we can remove it later it using the ID
  3875            // of the original listener
  3876            removeOnDispose.guid = fn.guid;
  3877            _this2.on('dispose', removeOnDispose);
  3878  
  3879            // If the other component is disposed first we need to clean the reference
  3880            // to the other component in this component's removeOnDispose listener
  3881            // Otherwise we create a memory leak.
  3882            var cleanRemover = function cleanRemover() {
  3883              return _this2.off('dispose', removeOnDispose);
  3884            };
  3885  
  3886            // Add the same function ID so we can easily remove it later
  3887            cleanRemover.guid = fn.guid;
  3888  
  3889            // Check if this is a DOM node
  3890            if (first.nodeName) {
  3891              // Add the listener to the other element
  3892              Events.on(target, type, fn);
  3893              Events.on(target, 'dispose', cleanRemover);
  3894  
  3895              // Should be a component
  3896              // Not using `instanceof Component` because it makes mock players difficult
  3897            } else if (typeof first.on === 'function') {
  3898                // Add the listener to the other component
  3899                target.on(type, fn);
  3900                target.on('dispose', cleanRemover);
  3901              }
  3902          })();
  3903        }
  3904  
  3905      return this;
  3906    };
  3907  
  3908    /**
  3909     * Remove an event listener from this component's element
  3910     * ```js
  3911     *     myComponent.off('eventType', myFunc);
  3912     * ```
  3913     * If myFunc is excluded, ALL listeners for the event type will be removed.
  3914     * If eventType is excluded, ALL listeners will be removed from the component.
  3915     * Alternatively you can use `off` to remove listeners that were added to other
  3916     * elements or components using `myComponent.on(otherComponent...`.
  3917     * In this case both the event type and listener function are REQUIRED.
  3918     * ```js
  3919     *     myComponent.off(otherElement, 'eventType', myFunc);
  3920     *     myComponent.off(otherComponent, 'eventType', myFunc);
  3921     * ```
  3922     *
  3923     * @param  {String=|Component}  first  The event type or other component
  3924     * @param  {Function=|String}       second The listener function or event type
  3925     * @param  {Function=}              third  The listener for other component
  3926     * @return {Component}
  3927     * @method off
  3928     */
  3929  
  3930    Component.prototype.off = function off(first, second, third) {
  3931      if (!first || typeof first === 'string' || Array.isArray(first)) {
  3932        Events.off(this.el_, first, second);
  3933      } else {
  3934        var target = first;
  3935        var type = second;
  3936        // Ensure there's at least a guid, even if the function hasn't been used
  3937        var fn = Fn.bind(this, third);
  3938  
  3939        // Remove the dispose listener on this component,
  3940        // which was given the same guid as the event listener
  3941        this.off('dispose', fn);
  3942  
  3943        if (first.nodeName) {
  3944          // Remove the listener
  3945          Events.off(target, type, fn);
  3946          // Remove the listener for cleaning the dispose listener
  3947          Events.off(target, 'dispose', fn);
  3948        } else {
  3949          target.off(type, fn);
  3950          target.off('dispose', fn);
  3951        }
  3952      }
  3953  
  3954      return this;
  3955    };
  3956  
  3957    /**
  3958     * Add an event listener to be triggered only once and then removed
  3959     * ```js
  3960     *     myComponent.one('eventName', myFunc);
  3961     * ```
  3962     * Alternatively you can add a listener to another element or component
  3963     * that will be triggered only once.
  3964     * ```js
  3965     *     myComponent.one(otherElement, 'eventName', myFunc);
  3966     *     myComponent.one(otherComponent, 'eventName', myFunc);
  3967     * ```
  3968     *
  3969     * @param  {String|Component}  first   The event type or other component
  3970     * @param  {Function|String}       second  The listener function or event type
  3971     * @param  {Function=}             third   The listener function for other component
  3972     * @return {Component}
  3973     * @method one
  3974     */
  3975  
  3976    Component.prototype.one = function one(first, second, third) {
  3977      var _this3 = this,
  3978          _arguments = arguments;
  3979  
  3980      if (typeof first === 'string' || Array.isArray(first)) {
  3981        Events.one(this.el_, first, Fn.bind(this, second));
  3982      } else {
  3983        (function () {
  3984          var target = first;
  3985          var type = second;
  3986          var fn = Fn.bind(_this3, third);
  3987  
  3988          var newFunc = function newFunc() {
  3989            _this3.off(target, type, newFunc);
  3990            fn.apply(null, _arguments);
  3991          };
  3992  
  3993          // Keep the same function ID so we can remove it later
  3994          newFunc.guid = fn.guid;
  3995  
  3996          _this3.on(target, type, newFunc);
  3997        })();
  3998      }
  3999  
  4000      return this;
  4001    };
  4002  
  4003    /**
  4004     * Trigger an event on an element
  4005     * ```js
  4006     *     myComponent.trigger('eventName');
  4007     *     myComponent.trigger({'type':'eventName'});
  4008     *     myComponent.trigger('eventName', {data: 'some data'});
  4009     *     myComponent.trigger({'type':'eventName'}, {data: 'some data'});
  4010     * ```
  4011     *
  4012     * @param  {Event|Object|String} event  A string (the type) or an event object with a type attribute
  4013     * @param  {Object} [hash] data hash to pass along with the event
  4014     * @return {Component}       self
  4015     * @method trigger
  4016     */
  4017  
  4018    Component.prototype.trigger = function trigger(event, hash) {
  4019      Events.trigger(this.el_, event, hash);
  4020      return this;
  4021    };
  4022  
  4023    /**
  4024     * Bind a listener to the component's ready state.
  4025     * Different from event listeners in that if the ready event has already happened
  4026     * it will trigger the function immediately.
  4027     *
  4028     * @param  {Function} fn Ready listener
  4029     * @param  {Boolean} sync Exec the listener synchronously if component is ready
  4030     * @return {Component}
  4031     * @method ready
  4032     */
  4033  
  4034    Component.prototype.ready = function ready(fn) {
  4035      var sync = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
  4036  
  4037      if (fn) {
  4038        if (this.isReady_) {
  4039          if (sync) {
  4040            fn.call(this);
  4041          } else {
  4042            // Call the function asynchronously by default for consistency
  4043            this.setTimeout(fn, 1);
  4044          }
  4045        } else {
  4046          this.readyQueue_ = this.readyQueue_ || [];
  4047          this.readyQueue_.push(fn);
  4048        }
  4049      }
  4050      return this;
  4051    };
  4052  
  4053    /**
  4054     * Trigger the ready listeners
  4055     *
  4056     * @return {Component}
  4057     * @method triggerReady
  4058     */
  4059  
  4060    Component.prototype.triggerReady = function triggerReady() {
  4061      this.isReady_ = true;
  4062  
  4063      // Ensure ready is triggerd asynchronously
  4064      this.setTimeout(function () {
  4065        var readyQueue = this.readyQueue_;
  4066  
  4067        // Reset Ready Queue
  4068        this.readyQueue_ = [];
  4069  
  4070        if (readyQueue && readyQueue.length > 0) {
  4071          readyQueue.forEach(function (fn) {
  4072            fn.call(this);
  4073          }, this);
  4074        }
  4075  
  4076        // Allow for using event listeners also
  4077        this.trigger('ready');
  4078      }, 1);
  4079    };
  4080  
  4081    /**
  4082     * Finds a single DOM element matching `selector` within the component's
  4083     * `contentEl` or another custom context.
  4084     *
  4085     * @method $
  4086     * @param  {String} selector
  4087     *         A valid CSS selector, which will be passed to `querySelector`.
  4088     *
  4089     * @param  {Element|String} [context=document]
  4090     *         A DOM element within which to query. Can also be a selector
  4091     *         string in which case the first matching element will be used
  4092     *         as context. If missing (or no element matches selector), falls
  4093     *         back to `document`.
  4094     *
  4095     * @return {Element|null}
  4096     */
  4097  
  4098    Component.prototype.$ = function $(selector, context) {
  4099      return Dom.$(selector, context || this.contentEl());
  4100    };
  4101  
  4102    /**
  4103     * Finds a all DOM elements matching `selector` within the component's
  4104     * `contentEl` or another custom context.
  4105     *
  4106     * @method $$
  4107     * @param  {String} selector
  4108     *         A valid CSS selector, which will be passed to `querySelectorAll`.
  4109     *
  4110     * @param  {Element|String} [context=document]
  4111     *         A DOM element within which to query. Can also be a selector
  4112     *         string in which case the first matching element will be used
  4113     *         as context. If missing (or no element matches selector), falls
  4114     *         back to `document`.
  4115     *
  4116     * @return {NodeList}
  4117     */
  4118  
  4119    Component.prototype.$$ = function $$(selector, context) {
  4120      return Dom.$$(selector, context || this.contentEl());
  4121    };
  4122  
  4123    /**
  4124     * Check if a component's element has a CSS class name
  4125     *
  4126     * @param {String} classToCheck Classname to check
  4127     * @return {Component}
  4128     * @method hasClass
  4129     */
  4130  
  4131    Component.prototype.hasClass = function hasClass(classToCheck) {
  4132      return Dom.hasElClass(this.el_, classToCheck);
  4133    };
  4134  
  4135    /**
  4136     * Add a CSS class name to the component's element
  4137     *
  4138     * @param {String} classToAdd Classname to add
  4139     * @return {Component}
  4140     * @method addClass
  4141     */
  4142  
  4143    Component.prototype.addClass = function addClass(classToAdd) {
  4144      Dom.addElClass(this.el_, classToAdd);
  4145      return this;
  4146    };
  4147  
  4148    /**
  4149     * Remove a CSS class name from the component's element
  4150     *
  4151     * @param {String} classToRemove Classname to remove
  4152     * @return {Component}
  4153     * @method removeClass
  4154     */
  4155  
  4156    Component.prototype.removeClass = function removeClass(classToRemove) {
  4157      Dom.removeElClass(this.el_, classToRemove);
  4158      return this;
  4159    };
  4160  
  4161    /**
  4162     * Add or remove a CSS class name from the component's element
  4163     *
  4164     * @param  {String} classToToggle
  4165     * @param  {Boolean|Function} [predicate]
  4166     *         Can be a function that returns a Boolean. If `true`, the class
  4167     *         will be added; if `false`, the class will be removed. If not
  4168     *         given, the class will be added if not present and vice versa.
  4169     *
  4170     * @return {Component}
  4171     * @method toggleClass
  4172     */
  4173  
  4174    Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) {
  4175      Dom.toggleElClass(this.el_, classToToggle, predicate);
  4176      return this;
  4177    };
  4178  
  4179    /**
  4180     * Show the component element if hidden
  4181     *
  4182     * @return {Component}
  4183     * @method show
  4184     */
  4185  
  4186    Component.prototype.show = function show() {
  4187      this.removeClass('vjs-hidden');
  4188      return this;
  4189    };
  4190  
  4191    /**
  4192     * Hide the component element if currently showing
  4193     *
  4194     * @return {Component}
  4195     * @method hide
  4196     */
  4197  
  4198    Component.prototype.hide = function hide() {
  4199      this.addClass('vjs-hidden');
  4200      return this;
  4201    };
  4202  
  4203    /**
  4204     * Lock an item in its visible state
  4205     * To be used with fadeIn/fadeOut.
  4206     *
  4207     * @return {Component}
  4208     * @private
  4209     * @method lockShowing
  4210     */
  4211  
  4212    Component.prototype.lockShowing = function lockShowing() {
  4213      this.addClass('vjs-lock-showing');
  4214      return this;
  4215    };
  4216  
  4217    /**
  4218     * Unlock an item to be hidden
  4219     * To be used with fadeIn/fadeOut.
  4220     *
  4221     * @return {Component}
  4222     * @private
  4223     * @method unlockShowing
  4224     */
  4225  
  4226    Component.prototype.unlockShowing = function unlockShowing() {
  4227      this.removeClass('vjs-lock-showing');
  4228      return this;
  4229    };
  4230  
  4231    /**
  4232     * Set or get the width of the component (CSS values)
  4233     * Setting the video tag dimension values only works with values in pixels.
  4234     * Percent values will not work.
  4235     * Some percents can be used, but width()/height() will return the number + %,
  4236     * not the actual computed width/height.
  4237     *
  4238     * @param  {Number|String=} num   Optional width number
  4239     * @param  {Boolean} skipListeners Skip the 'resize' event trigger
  4240     * @return {Component} This component, when setting the width
  4241     * @return {Number|String} The width, when getting
  4242     * @method width
  4243     */
  4244  
  4245    Component.prototype.width = function width(num, skipListeners) {
  4246      return this.dimension('width', num, skipListeners);
  4247    };
  4248  
  4249    /**
  4250     * Get or set the height of the component (CSS values)
  4251     * Setting the video tag dimension values only works with values in pixels.
  4252     * Percent values will not work.
  4253     * Some percents can be used, but width()/height() will return the number + %,
  4254     * not the actual computed width/height.
  4255     *
  4256     * @param  {Number|String=} num     New component height
  4257     * @param  {Boolean=} skipListeners Skip the resize event trigger
  4258     * @return {Component} This component, when setting the height
  4259     * @return {Number|String} The height, when getting
  4260     * @method height
  4261     */
  4262  
  4263    Component.prototype.height = function height(num, skipListeners) {
  4264      return this.dimension('height', num, skipListeners);
  4265    };
  4266  
  4267    /**
  4268     * Set both width and height at the same time
  4269     *
  4270     * @param  {Number|String} width Width of player
  4271     * @param  {Number|String} height Height of player
  4272     * @return {Component} The component
  4273     * @method dimensions
  4274     */
  4275  
  4276    Component.prototype.dimensions = function dimensions(width, height) {
  4277      // Skip resize listeners on width for optimization
  4278      return this.width(width, true).height(height);
  4279    };
  4280  
  4281    /**
  4282     * Get or set width or height
  4283     * This is the shared code for the width() and height() methods.
  4284     * All for an integer, integer + 'px' or integer + '%';
  4285     * Known issue: Hidden elements officially have a width of 0. We're defaulting
  4286     * to the style.width value and falling back to computedStyle which has the
  4287     * hidden element issue. Info, but probably not an efficient fix:
  4288     * http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/
  4289     *
  4290     * @param  {String} widthOrHeight  'width' or 'height'
  4291     * @param  {Number|String=} num     New dimension
  4292     * @param  {Boolean=} skipListeners Skip resize event trigger
  4293     * @return {Component} The component if a dimension was set
  4294     * @return {Number|String} The dimension if nothing was set
  4295     * @private
  4296     * @method dimension
  4297     */
  4298  
  4299    Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) {
  4300      if (num !== undefined) {
  4301        // Set to zero if null or literally NaN (NaN !== NaN)
  4302        if (num === null || num !== num) {
  4303          num = 0;
  4304        }
  4305  
  4306        // Check if using css width/height (% or px) and adjust
  4307        if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) {
  4308          this.el_.style[widthOrHeight] = num;
  4309        } else if (num === 'auto') {
  4310          this.el_.style[widthOrHeight] = '';
  4311        } else {
  4312          this.el_.style[widthOrHeight] = num + 'px';
  4313        }
  4314  
  4315        // skipListeners allows us to avoid triggering the resize event when setting both width and height
  4316        if (!skipListeners) {
  4317          this.trigger('resize');
  4318        }
  4319  
  4320        // Return component
  4321        return this;
  4322      }
  4323  
  4324      // Not setting a value, so getting it
  4325      // Make sure element exists
  4326      if (!this.el_) {
  4327        return 0;
  4328      }
  4329  
  4330      // Get dimension value from style
  4331      var val = this.el_.style[widthOrHeight];
  4332      var pxIndex = val.indexOf('px');
  4333  
  4334      if (pxIndex !== -1) {
  4335        // Return the pixel value with no 'px'
  4336        return parseInt(val.slice(0, pxIndex), 10);
  4337      }
  4338  
  4339      // No px so using % or no style was set, so falling back to offsetWidth/height
  4340      // If component has display:none, offset will return 0
  4341      // TODO: handle display:none and no dimension style using px
  4342      return parseInt(this.el_['offset' + _utilsToTitleCaseJs2['default'](widthOrHeight)], 10);
  4343    };
  4344  
  4345    /**
  4346     * Get width or height of computed style
  4347     * @param  {String} widthOrHeight  'width' or 'height'
  4348     * @return {Number|Boolean} The bolean false if nothing was set
  4349     * @method currentDimension
  4350     */
  4351  
  4352    Component.prototype.currentDimension = function currentDimension(widthOrHeight) {
  4353      var computedWidthOrHeight = 0;
  4354  
  4355      if (widthOrHeight !== 'width' && widthOrHeight !== 'height') {
  4356        throw new Error('currentDimension only accepts width or height value');
  4357      }
  4358  
  4359      if (typeof _globalWindow2['default'].getComputedStyle === 'function') {
  4360        var computedStyle = _globalWindow2['default'].getComputedStyle(this.el_);
  4361        computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight];
  4362      } else if (this.el_.currentStyle) {
  4363        // ie 8 doesn't support computed style, shim it
  4364        // return clientWidth or clientHeight instead for better accuracy
  4365        var rule = 'offset' + _utilsToTitleCaseJs2['default'](widthOrHeight);
  4366        computedWidthOrHeight = this.el_[rule];
  4367      }
  4368  
  4369      // remove 'px' from variable and parse as integer
  4370      computedWidthOrHeight = parseFloat(computedWidthOrHeight);
  4371      return computedWidthOrHeight;
  4372    };
  4373  
  4374    /**
  4375     * Get an object which contains width and height values of computed style
  4376     * @return {Object} The dimensions of element
  4377     * @method currentDimensions
  4378     */
  4379  
  4380    Component.prototype.currentDimensions = function currentDimensions() {
  4381      return {
  4382        width: this.currentDimension('width'),
  4383        height: this.currentDimension('height')
  4384      };
  4385    };
  4386  
  4387    /**
  4388     * Get width of computed style
  4389     * @return {Integer}
  4390     * @method currentWidth
  4391     */
  4392  
  4393    Component.prototype.currentWidth = function currentWidth() {
  4394      return this.currentDimension('width');
  4395    };
  4396  
  4397    /**
  4398     * Get height of computed style
  4399     * @return {Integer}
  4400     * @method currentHeight
  4401     */
  4402  
  4403    Component.prototype.currentHeight = function currentHeight() {
  4404      return this.currentDimension('height');
  4405    };
  4406  
  4407    /**
  4408     * Emit 'tap' events when touch events are supported
  4409     * This is used to support toggling the controls through a tap on the video.
  4410     * We're requiring them to be enabled because otherwise every component would
  4411     * have this extra overhead unnecessarily, on mobile devices where extra
  4412     * overhead is especially bad.
  4413     *
  4414     * @private
  4415     * @method emitTapEvents
  4416     */
  4417  
  4418    Component.prototype.emitTapEvents = function emitTapEvents() {
  4419      // Track the start time so we can determine how long the touch lasted
  4420      var touchStart = 0;
  4421      var firstTouch = null;
  4422  
  4423      // Maximum movement allowed during a touch event to still be considered a tap
  4424      // Other popular libs use anywhere from 2 (hammer.js) to 15, so 10 seems like a nice, round number.
  4425      var tapMovementThreshold = 10;
  4426  
  4427      // The maximum length a touch can be while still being considered a tap
  4428      var touchTimeThreshold = 200;
  4429  
  4430      var couldBeTap = undefined;
  4431  
  4432      this.on('touchstart', function (event) {
  4433        // If more than one finger, don't consider treating this as a click
  4434        if (event.touches.length === 1) {
  4435          // Copy the touches object to prevent modifying the original
  4436          firstTouch = _objectAssign2['default']({}, event.touches[0]);
  4437          // Record start time so we can detect a tap vs. "touch and hold"
  4438          touchStart = new Date().getTime();
  4439          // Reset couldBeTap tracking
  4440          couldBeTap = true;
  4441        }
  4442      });
  4443  
  4444      this.on('touchmove', function (event) {
  4445        // If more than one finger, don't consider treating this as a click
  4446        if (event.touches.length > 1) {
  4447          couldBeTap = false;
  4448        } else if (firstTouch) {
  4449          // Some devices will throw touchmoves for all but the slightest of taps.
  4450          // So, if we moved only a small distance, this could still be a tap
  4451          var xdiff = event.touches[0].pageX - firstTouch.pageX;
  4452          var ydiff = event.touches[0].pageY - firstTouch.pageY;
  4453          var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
  4454  
  4455          if (touchDistance > tapMovementThreshold) {
  4456            couldBeTap = false;
  4457          }
  4458        }
  4459      });
  4460  
  4461      var noTap = function noTap() {
  4462        couldBeTap = false;
  4463      };
  4464  
  4465      // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s
  4466      this.on('touchleave', noTap);
  4467      this.on('touchcancel', noTap);
  4468  
  4469      // When the touch ends, measure how long it took and trigger the appropriate
  4470      // event
  4471      this.on('touchend', function (event) {
  4472        firstTouch = null;
  4473        // Proceed only if the touchmove/leave/cancel event didn't happen
  4474        if (couldBeTap === true) {
  4475          // Measure how long the touch lasted
  4476          var touchTime = new Date().getTime() - touchStart;
  4477  
  4478          // Make sure the touch was less than the threshold to be considered a tap
  4479          if (touchTime < touchTimeThreshold) {
  4480            // Don't let browser turn this into a click
  4481            event.preventDefault();
  4482            this.trigger('tap');
  4483            // It may be good to copy the touchend event object and change the
  4484            // type to tap, if the other event properties aren't exact after
  4485            // Events.fixEvent runs (e.g. event.target)
  4486          }
  4487        }
  4488      });
  4489    };
  4490  
  4491    /**
  4492     * Report user touch activity when touch events occur
  4493     * User activity is used to determine when controls should show/hide. It's
  4494     * relatively simple when it comes to mouse events, because any mouse event
  4495     * should show the controls. So we capture mouse events that bubble up to the
  4496     * player and report activity when that happens.
  4497     * With touch events it isn't as easy. We can't rely on touch events at the
  4498     * player level, because a tap (touchstart + touchend) on the video itself on
  4499     * mobile devices is meant to turn controls off (and on). User activity is
  4500     * checked asynchronously, so what could happen is a tap event on the video
  4501     * turns the controls off, then the touchend event bubbles up to the player,
  4502     * which if it reported user activity, would turn the controls right back on.
  4503     * (We also don't want to completely block touch events from bubbling up)
  4504     * Also a touchmove, touch+hold, and anything other than a tap is not supposed
  4505     * to turn the controls back on on a mobile device.
  4506     * Here we're setting the default component behavior to report user activity
  4507     * whenever touch events happen, and this can be turned off by components that
  4508     * want touch events to act differently.
  4509     *
  4510     * @method enableTouchActivity
  4511     */
  4512  
  4513    Component.prototype.enableTouchActivity = function enableTouchActivity() {
  4514      // Don't continue if the root player doesn't support reporting user activity
  4515      if (!this.player() || !this.player().reportUserActivity) {
  4516        return;
  4517      }
  4518  
  4519      // listener for reporting that the user is active
  4520      var report = Fn.bind(this.player(), this.player().reportUserActivity);
  4521  
  4522      var touchHolding = undefined;
  4523  
  4524      this.on('touchstart', function () {
  4525        report();
  4526        // For as long as the they are touching the device or have their mouse down,
  4527        // we consider them active even if they're not moving their finger or mouse.
  4528        // So we want to continue to update that they are active
  4529        this.clearInterval(touchHolding);
  4530        // report at the same interval as activityCheck
  4531        touchHolding = this.setInterval(report, 250);
  4532      });
  4533  
  4534      var touchEnd = function touchEnd(event) {
  4535        report();
  4536        // stop the interval that maintains activity if the touch is holding
  4537        this.clearInterval(touchHolding);
  4538      };
  4539  
  4540      this.on('touchmove', report);
  4541      this.on('touchend', touchEnd);
  4542      this.on('touchcancel', touchEnd);
  4543    };
  4544  
  4545    /**
  4546     * Creates timeout and sets up disposal automatically.
  4547     *
  4548     * @param {Function} fn The function to run after the timeout.
  4549     * @param {Number} timeout Number of ms to delay before executing specified function.
  4550     * @return {Number} Returns the timeout ID
  4551     * @method setTimeout
  4552     */
  4553  
  4554    Component.prototype.setTimeout = function setTimeout(fn, timeout) {
  4555      fn = Fn.bind(this, fn);
  4556  
  4557      // window.setTimeout would be preferable here, but due to some bizarre issue with Sinon and/or Phantomjs, we can't.
  4558      var timeoutId = _globalWindow2['default'].setTimeout(fn, timeout);
  4559  
  4560      var disposeFn = function disposeFn() {
  4561        this.clearTimeout(timeoutId);
  4562      };
  4563  
  4564      disposeFn.guid = 'vjs-timeout-' + timeoutId;
  4565  
  4566      this.on('dispose', disposeFn);
  4567  
  4568      return timeoutId;
  4569    };
  4570  
  4571    /**
  4572     * Clears a timeout and removes the associated dispose listener
  4573     *
  4574     * @param {Number} timeoutId The id of the timeout to clear
  4575     * @return {Number} Returns the timeout ID
  4576     * @method clearTimeout
  4577     */
  4578  
  4579    Component.prototype.clearTimeout = function clearTimeout(timeoutId) {
  4580      _globalWindow2['default'].clearTimeout(timeoutId);
  4581  
  4582      var disposeFn = function disposeFn() {};
  4583  
  4584      disposeFn.guid = 'vjs-timeout-' + timeoutId;
  4585  
  4586      this.off('dispose', disposeFn);
  4587  
  4588      return timeoutId;
  4589    };
  4590  
  4591    /**
  4592     * Creates an interval and sets up disposal automatically.
  4593     *
  4594     * @param {Function} fn The function to run every N seconds.
  4595     * @param {Number} interval Number of ms to delay before executing specified function.
  4596     * @return {Number} Returns the interval ID
  4597     * @method setInterval
  4598     */
  4599  
  4600    Component.prototype.setInterval = function setInterval(fn, interval) {
  4601      fn = Fn.bind(this, fn);
  4602  
  4603      var intervalId = _globalWindow2['default'].setInterval(fn, interval);
  4604  
  4605      var disposeFn = function disposeFn() {
  4606        this.clearInterval(intervalId);
  4607      };
  4608  
  4609      disposeFn.guid = 'vjs-interval-' + intervalId;
  4610  
  4611      this.on('dispose', disposeFn);
  4612  
  4613      return intervalId;
  4614    };
  4615  
  4616    /**
  4617     * Clears an interval and removes the associated dispose listener
  4618     *
  4619     * @param {Number} intervalId The id of the interval to clear
  4620     * @return {Number} Returns the interval ID
  4621     * @method clearInterval
  4622     */
  4623  
  4624    Component.prototype.clearInterval = function clearInterval(intervalId) {
  4625      _globalWindow2['default'].clearInterval(intervalId);
  4626  
  4627      var disposeFn = function disposeFn() {};
  4628  
  4629      disposeFn.guid = 'vjs-interval-' + intervalId;
  4630  
  4631      this.off('dispose', disposeFn);
  4632  
  4633      return intervalId;
  4634    };
  4635  
  4636    /**
  4637     * Registers a component
  4638     *
  4639     * @param {String} name Name of the component to register
  4640     * @param {Object} comp The component to register
  4641     * @static
  4642     * @method registerComponent
  4643     */
  4644  
  4645    Component.registerComponent = function registerComponent(name, comp) {
  4646      if (!Component.components_) {
  4647        Component.components_ = {};
  4648      }
  4649  
  4650      Component.components_[name] = comp;
  4651      return comp;
  4652    };
  4653  
  4654    /**
  4655     * Gets a component by name
  4656     *
  4657     * @param {String} name Name of the component to get
  4658     * @return {Component}
  4659     * @static
  4660     * @method getComponent
  4661     */
  4662  
  4663    Component.getComponent = function getComponent(name) {
  4664      if (Component.components_ && Component.components_[name]) {
  4665        return Component.components_[name];
  4666      }
  4667  
  4668      if (_globalWindow2['default'] && _globalWindow2['default'].videojs && _globalWindow2['default'].videojs[name]) {
  4669        _utilsLogJs2['default'].warn('The ' + name + ' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)');
  4670        return _globalWindow2['default'].videojs[name];
  4671      }
  4672    };
  4673  
  4674    /**
  4675     * Sets up the constructor using the supplied init method
  4676     * or uses the init of the parent object
  4677     *
  4678     * @param {Object} props An object of properties
  4679     * @static
  4680     * @deprecated
  4681     * @method extend
  4682     */
  4683  
  4684    Component.extend = function extend(props) {
  4685      props = props || {};
  4686  
  4687      _utilsLogJs2['default'].warn('Component.extend({}) has been deprecated, use videojs.extend(Component, {}) instead');
  4688  
  4689      // Set up the constructor using the supplied init method
  4690      // or using the init of the parent object
  4691      // Make sure to check the unobfuscated version for external libs
  4692      var init = props.init || props.init || this.prototype.init || this.prototype.init || function () {};
  4693      // In Resig's simple class inheritance (previously used) the constructor
  4694      //  is a function that calls `this.init.apply(arguments)`
  4695      // However that would prevent us from using `ParentObject.call(this);`
  4696      //  in a Child constructor because the `this` in `this.init`
  4697      //  would still refer to the Child and cause an infinite loop.
  4698      // We would instead have to do
  4699      //    `ParentObject.prototype.init.apply(this, arguments);`
  4700      //  Bleh. We're not creating a _super() function, so it's good to keep
  4701      //  the parent constructor reference simple.
  4702      var subObj = function subObj() {
  4703        init.apply(this, arguments);
  4704      };
  4705  
  4706      // Inherit from this object's prototype
  4707      subObj.prototype = Object.create(this.prototype);
  4708      // Reset the constructor property for subObj otherwise
  4709      // instances of subObj would have the constructor of the parent Object
  4710      subObj.prototype.constructor = subObj;
  4711  
  4712      // Make the class extendable
  4713      subObj.extend = Component.extend;
  4714  
  4715      // Extend subObj's prototype with functions and other properties from props
  4716      for (var _name in props) {
  4717        if (props.hasOwnProperty(_name)) {
  4718          subObj.prototype[_name] = props[_name];
  4719        }
  4720      }
  4721  
  4722      return subObj;
  4723    };
  4724  
  4725    return Component;
  4726  })();
  4727  
  4728  Component.registerComponent('Component', Component);
  4729  exports['default'] = Component;
  4730  module.exports = exports['default'];
  4731  
  4732  },{"./utils/dom.js":134,"./utils/events.js":135,"./utils/fn.js":136,"./utils/guid.js":138,"./utils/log.js":139,"./utils/merge-options.js":140,"./utils/to-title-case.js":143,"global/window":2,"object.assign":45}],68:[function(_dereq_,module,exports){
  4733  /**
  4734   * @file control-bar.js
  4735   */
  4736  'use strict';
  4737  
  4738  exports.__esModule = true;
  4739  
  4740  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4741  
  4742  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  4743  
  4744  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  4745  
  4746  var _componentJs = _dereq_('../component.js');
  4747  
  4748  var _componentJs2 = _interopRequireDefault(_componentJs);
  4749  
  4750  // Required children
  4751  
  4752  var _playToggleJs = _dereq_('./play-toggle.js');
  4753  
  4754  var _playToggleJs2 = _interopRequireDefault(_playToggleJs);
  4755  
  4756  var _timeControlsCurrentTimeDisplayJs = _dereq_('./time-controls/current-time-display.js');
  4757  
  4758  var _timeControlsCurrentTimeDisplayJs2 = _interopRequireDefault(_timeControlsCurrentTimeDisplayJs);
  4759  
  4760  var _timeControlsDurationDisplayJs = _dereq_('./time-controls/duration-display.js');
  4761  
  4762  var _timeControlsDurationDisplayJs2 = _interopRequireDefault(_timeControlsDurationDisplayJs);
  4763  
  4764  var _timeControlsTimeDividerJs = _dereq_('./time-controls/time-divider.js');
  4765  
  4766  var _timeControlsTimeDividerJs2 = _interopRequireDefault(_timeControlsTimeDividerJs);
  4767  
  4768  var _timeControlsRemainingTimeDisplayJs = _dereq_('./time-controls/remaining-time-display.js');
  4769  
  4770  var _timeControlsRemainingTimeDisplayJs2 = _interopRequireDefault(_timeControlsRemainingTimeDisplayJs);
  4771  
  4772  var _liveDisplayJs = _dereq_('./live-display.js');
  4773  
  4774  var _liveDisplayJs2 = _interopRequireDefault(_liveDisplayJs);
  4775  
  4776  var _progressControlProgressControlJs = _dereq_('./progress-control/progress-control.js');
  4777  
  4778  var _progressControlProgressControlJs2 = _interopRequireDefault(_progressControlProgressControlJs);
  4779  
  4780  var _fullscreenToggleJs = _dereq_('./fullscreen-toggle.js');
  4781  
  4782  var _fullscreenToggleJs2 = _interopRequireDefault(_fullscreenToggleJs);
  4783  
  4784  var _volumeControlVolumeControlJs = _dereq_('./volume-control/volume-control.js');
  4785  
  4786  var _volumeControlVolumeControlJs2 = _interopRequireDefault(_volumeControlVolumeControlJs);
  4787  
  4788  var _volumeMenuButtonJs = _dereq_('./volume-menu-button.js');
  4789  
  4790  var _volumeMenuButtonJs2 = _interopRequireDefault(_volumeMenuButtonJs);
  4791  
  4792  var _muteToggleJs = _dereq_('./mute-toggle.js');
  4793  
  4794  var _muteToggleJs2 = _interopRequireDefault(_muteToggleJs);
  4795  
  4796  var _textTrackControlsChaptersButtonJs = _dereq_('./text-track-controls/chapters-button.js');
  4797  
  4798  var _textTrackControlsChaptersButtonJs2 = _interopRequireDefault(_textTrackControlsChaptersButtonJs);
  4799  
  4800  var _textTrackControlsDescriptionsButtonJs = _dereq_('./text-track-controls/descriptions-button.js');
  4801  
  4802  var _textTrackControlsDescriptionsButtonJs2 = _interopRequireDefault(_textTrackControlsDescriptionsButtonJs);
  4803  
  4804  var _textTrackControlsSubtitlesButtonJs = _dereq_('./text-track-controls/subtitles-button.js');
  4805  
  4806  var _textTrackControlsSubtitlesButtonJs2 = _interopRequireDefault(_textTrackControlsSubtitlesButtonJs);
  4807  
  4808  var _textTrackControlsCaptionsButtonJs = _dereq_('./text-track-controls/captions-button.js');
  4809  
  4810  var _textTrackControlsCaptionsButtonJs2 = _interopRequireDefault(_textTrackControlsCaptionsButtonJs);
  4811  
  4812  var _playbackRateMenuPlaybackRateMenuButtonJs = _dereq_('./playback-rate-menu/playback-rate-menu-button.js');
  4813  
  4814  var _playbackRateMenuPlaybackRateMenuButtonJs2 = _interopRequireDefault(_playbackRateMenuPlaybackRateMenuButtonJs);
  4815  
  4816  var _spacerControlsCustomControlSpacerJs = _dereq_('./spacer-controls/custom-control-spacer.js');
  4817  
  4818  var _spacerControlsCustomControlSpacerJs2 = _interopRequireDefault(_spacerControlsCustomControlSpacerJs);
  4819  
  4820  /**
  4821   * Container of main controls
  4822   *
  4823   * @extends Component
  4824   * @class ControlBar
  4825   */
  4826  
  4827  var ControlBar = (function (_Component) {
  4828    _inherits(ControlBar, _Component);
  4829  
  4830    function ControlBar() {
  4831      _classCallCheck(this, ControlBar);
  4832  
  4833      _Component.apply(this, arguments);
  4834    }
  4835  
  4836    /**
  4837     * Create the component's DOM element
  4838     *
  4839     * @return {Element}
  4840     * @method createEl
  4841     */
  4842  
  4843    ControlBar.prototype.createEl = function createEl() {
  4844      return _Component.prototype.createEl.call(this, 'div', {
  4845        className: 'vjs-control-bar',
  4846        dir: 'ltr'
  4847      }, {
  4848        'role': 'group' // The control bar is a group, so it can contain menuitems
  4849      });
  4850    };
  4851  
  4852    return ControlBar;
  4853  })(_componentJs2['default']);
  4854  
  4855  ControlBar.prototype.options_ = {
  4856    loadEvent: 'play',
  4857    children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subtitlesButton', 'captionsButton', 'fullscreenToggle']
  4858  };
  4859  
  4860  _componentJs2['default'].registerComponent('ControlBar', ControlBar);
  4861  exports['default'] = ControlBar;
  4862  module.exports = exports['default'];
  4863  
  4864  },{"../component.js":67,"./fullscreen-toggle.js":69,"./live-display.js":70,"./mute-toggle.js":71,"./play-toggle.js":72,"./playback-rate-menu/playback-rate-menu-button.js":73,"./progress-control/progress-control.js":78,"./spacer-controls/custom-control-spacer.js":81,"./text-track-controls/captions-button.js":84,"./text-track-controls/chapters-button.js":85,"./text-track-controls/descriptions-button.js":87,"./text-track-controls/subtitles-button.js":89,"./time-controls/current-time-display.js":92,"./time-controls/duration-display.js":93,"./time-controls/remaining-time-display.js":94,"./time-controls/time-divider.js":95,"./volume-control/volume-control.js":97,"./volume-menu-button.js":99}],69:[function(_dereq_,module,exports){
  4865  /**
  4866   * @file fullscreen-toggle.js
  4867   */
  4868  'use strict';
  4869  
  4870  exports.__esModule = true;
  4871  
  4872  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4873  
  4874  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  4875  
  4876  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  4877  
  4878  var _buttonJs = _dereq_('../button.js');
  4879  
  4880  var _buttonJs2 = _interopRequireDefault(_buttonJs);
  4881  
  4882  var _componentJs = _dereq_('../component.js');
  4883  
  4884  var _componentJs2 = _interopRequireDefault(_componentJs);
  4885  
  4886  /**
  4887   * Toggle fullscreen video
  4888   *
  4889   * @extends Button
  4890   * @class FullscreenToggle
  4891   */
  4892  
  4893  var FullscreenToggle = (function (_Button) {
  4894    _inherits(FullscreenToggle, _Button);
  4895  
  4896    function FullscreenToggle() {
  4897      _classCallCheck(this, FullscreenToggle);
  4898  
  4899      _Button.apply(this, arguments);
  4900    }
  4901  
  4902    /**
  4903     * Allow sub components to stack CSS class names
  4904     *
  4905     * @return {String} The constructed class name
  4906     * @method buildCSSClass
  4907     */
  4908  
  4909    FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() {
  4910      return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this);
  4911    };
  4912  
  4913    /**
  4914     * Handles click for full screen
  4915     *
  4916     * @method handleClick
  4917     */
  4918  
  4919    FullscreenToggle.prototype.handleClick = function handleClick() {
  4920      if (!this.player_.isFullscreen()) {
  4921        this.player_.requestFullscreen();
  4922        this.controlText('Non-Fullscreen');
  4923      } else {
  4924        this.player_.exitFullscreen();
  4925        this.controlText('Fullscreen');
  4926      }
  4927    };
  4928  
  4929    return FullscreenToggle;
  4930  })(_buttonJs2['default']);
  4931  
  4932  FullscreenToggle.prototype.controlText_ = 'Fullscreen';
  4933  
  4934  _componentJs2['default'].registerComponent('FullscreenToggle', FullscreenToggle);
  4935  exports['default'] = FullscreenToggle;
  4936  module.exports = exports['default'];
  4937  
  4938  },{"../button.js":64,"../component.js":67}],70:[function(_dereq_,module,exports){
  4939  /**
  4940   * @file live-display.js
  4941   */
  4942  'use strict';
  4943  
  4944  exports.__esModule = true;
  4945  
  4946  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  4947  
  4948  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4949  
  4950  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  4951  
  4952  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  4953  
  4954  var _component = _dereq_('../component');
  4955  
  4956  var _component2 = _interopRequireDefault(_component);
  4957  
  4958  var _utilsDomJs = _dereq_('../utils/dom.js');
  4959  
  4960  var Dom = _interopRequireWildcard(_utilsDomJs);
  4961  
  4962  /**
  4963   * Displays the live indicator
  4964   * TODO - Future make it click to snap to live
  4965   *
  4966   * @extends Component
  4967   * @class LiveDisplay
  4968   */
  4969  
  4970  var LiveDisplay = (function (_Component) {
  4971    _inherits(LiveDisplay, _Component);
  4972  
  4973    function LiveDisplay(player, options) {
  4974      _classCallCheck(this, LiveDisplay);
  4975  
  4976      _Component.call(this, player, options);
  4977  
  4978      this.updateShowing();
  4979      this.on(this.player(), 'durationchange', this.updateShowing);
  4980    }
  4981  
  4982    /**
  4983     * Create the component's DOM element
  4984     *
  4985     * @return {Element}
  4986     * @method createEl
  4987     */
  4988  
  4989    LiveDisplay.prototype.createEl = function createEl() {
  4990      var el = _Component.prototype.createEl.call(this, 'div', {
  4991        className: 'vjs-live-control vjs-control'
  4992      });
  4993  
  4994      this.contentEl_ = Dom.createEl('div', {
  4995        className: 'vjs-live-display',
  4996        innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE')
  4997      }, {
  4998        'aria-live': 'off'
  4999      });
  5000  
  5001      el.appendChild(this.contentEl_);
  5002      return el;
  5003    };
  5004  
  5005    LiveDisplay.prototype.updateShowing = function updateShowing() {
  5006      if (this.player().duration() === Infinity) {
  5007        this.show();
  5008      } else {
  5009        this.hide();
  5010      }
  5011    };
  5012  
  5013    return LiveDisplay;
  5014  })(_component2['default']);
  5015  
  5016  _component2['default'].registerComponent('LiveDisplay', LiveDisplay);
  5017  exports['default'] = LiveDisplay;
  5018  module.exports = exports['default'];
  5019  
  5020  },{"../component":67,"../utils/dom.js":134}],71:[function(_dereq_,module,exports){
  5021  /**
  5022   * @file mute-toggle.js
  5023   */
  5024  'use strict';
  5025  
  5026  exports.__esModule = true;
  5027  
  5028  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  5029  
  5030  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5031  
  5032  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  5033  
  5034  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  5035  
  5036  var _button = _dereq_('../button');
  5037  
  5038  var _button2 = _interopRequireDefault(_button);
  5039  
  5040  var _component = _dereq_('../component');
  5041  
  5042  var _component2 = _interopRequireDefault(_component);
  5043  
  5044  var _utilsDomJs = _dereq_('../utils/dom.js');
  5045  
  5046  var Dom = _interopRequireWildcard(_utilsDomJs);
  5047  
  5048  /**
  5049   * A button component for muting the audio
  5050   *
  5051   * @param {Player|Object} player
  5052   * @param {Object=} options
  5053   * @extends Button
  5054   * @class MuteToggle
  5055   */
  5056  
  5057  var MuteToggle = (function (_Button) {
  5058    _inherits(MuteToggle, _Button);
  5059  
  5060    function MuteToggle(player, options) {
  5061      _classCallCheck(this, MuteToggle);
  5062  
  5063      _Button.call(this, player, options);
  5064  
  5065      this.on(player, 'volumechange', this.update);
  5066  
  5067      // hide mute toggle if the current tech doesn't support volume control
  5068      if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
  5069        this.addClass('vjs-hidden');
  5070      }
  5071  
  5072      this.on(player, 'loadstart', function () {
  5073        this.update(); // We need to update the button to account for a default muted state.
  5074  
  5075        if (player.tech_['featuresVolumeControl'] === false) {
  5076          this.addClass('vjs-hidden');
  5077        } else {
  5078          this.removeClass('vjs-hidden');
  5079        }
  5080      });
  5081    }
  5082  
  5083    /**
  5084     * Allow sub components to stack CSS class names
  5085     *
  5086     * @return {String} The constructed class name
  5087     * @method buildCSSClass
  5088     */
  5089  
  5090    MuteToggle.prototype.buildCSSClass = function buildCSSClass() {
  5091      return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this);
  5092    };
  5093  
  5094    /**
  5095     * Handle click on mute
  5096     *
  5097     * @method handleClick
  5098     */
  5099  
  5100    MuteToggle.prototype.handleClick = function handleClick() {
  5101      this.player_.muted(this.player_.muted() ? false : true);
  5102    };
  5103  
  5104    /**
  5105     * Update volume
  5106     *
  5107     * @method update
  5108     */
  5109  
  5110    MuteToggle.prototype.update = function update() {
  5111      var vol = this.player_.volume(),
  5112          level = 3;
  5113  
  5114      if (vol === 0 || this.player_.muted()) {
  5115        level = 0;
  5116      } else if (vol < 0.33) {
  5117        level = 1;
  5118      } else if (vol < 0.67) {
  5119        level = 2;
  5120      }
  5121  
  5122      // Don't rewrite the button text if the actual text doesn't change.
  5123      // This causes unnecessary and confusing information for screen reader users.
  5124      // This check is needed because this function gets called every time the volume level is changed.
  5125      var toMute = this.player_.muted() ? 'Unmute' : 'Mute';
  5126      if (this.controlText() !== toMute) {
  5127        this.controlText(toMute);
  5128      }
  5129  
  5130      /* TODO improve muted icon classes */
  5131      for (var i = 0; i < 4; i++) {
  5132        Dom.removeElClass(this.el_, 'vjs-vol-' + i);
  5133      }
  5134      Dom.addElClass(this.el_, 'vjs-vol-' + level);
  5135    };
  5136  
  5137    return MuteToggle;
  5138  })(_button2['default']);
  5139  
  5140  MuteToggle.prototype.controlText_ = 'Mute';
  5141  
  5142  _component2['default'].registerComponent('MuteToggle', MuteToggle);
  5143  exports['default'] = MuteToggle;
  5144  module.exports = exports['default'];
  5145  
  5146  },{"../button":64,"../component":67,"../utils/dom.js":134}],72:[function(_dereq_,module,exports){
  5147  /**
  5148   * @file play-toggle.js
  5149   */
  5150  'use strict';
  5151  
  5152  exports.__esModule = true;
  5153  
  5154  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5155  
  5156  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  5157  
  5158  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  5159  
  5160  var _buttonJs = _dereq_('../button.js');
  5161  
  5162  var _buttonJs2 = _interopRequireDefault(_buttonJs);
  5163  
  5164  var _componentJs = _dereq_('../component.js');
  5165  
  5166  var _componentJs2 = _interopRequireDefault(_componentJs);
  5167  
  5168  /**
  5169   * Button to toggle between play and pause
  5170   *
  5171   * @param {Player|Object} player
  5172   * @param {Object=} options
  5173   * @extends Button
  5174   * @class PlayToggle
  5175   */
  5176  
  5177  var PlayToggle = (function (_Button) {
  5178    _inherits(PlayToggle, _Button);
  5179  
  5180    function PlayToggle(player, options) {
  5181      _classCallCheck(this, PlayToggle);
  5182  
  5183      _Button.call(this, player, options);
  5184  
  5185      this.on(player, 'play', this.handlePlay);
  5186      this.on(player, 'pause', this.handlePause);
  5187    }
  5188  
  5189    /**
  5190     * Allow sub components to stack CSS class names
  5191     *
  5192     * @return {String} The constructed class name
  5193     * @method buildCSSClass
  5194     */
  5195  
  5196    PlayToggle.prototype.buildCSSClass = function buildCSSClass() {
  5197      return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this);
  5198    };
  5199  
  5200    /**
  5201     * Handle click to toggle between play and pause
  5202     *
  5203     * @method handleClick
  5204     */
  5205  
  5206    PlayToggle.prototype.handleClick = function handleClick() {
  5207      if (this.player_.paused()) {
  5208        this.player_.play();
  5209      } else {
  5210        this.player_.pause();
  5211      }
  5212    };
  5213  
  5214    /**
  5215     * Add the vjs-playing class to the element so it can change appearance
  5216     *
  5217     * @method handlePlay
  5218     */
  5219  
  5220    PlayToggle.prototype.handlePlay = function handlePlay() {
  5221      this.removeClass('vjs-paused');
  5222      this.addClass('vjs-playing');
  5223      this.controlText('Pause'); // change the button text to "Pause"
  5224    };
  5225  
  5226    /**
  5227     * Add the vjs-paused class to the element so it can change appearance
  5228     *
  5229     * @method handlePause
  5230     */
  5231  
  5232    PlayToggle.prototype.handlePause = function handlePause() {
  5233      this.removeClass('vjs-playing');
  5234      this.addClass('vjs-paused');
  5235      this.controlText('Play'); // change the button text to "Play"
  5236    };
  5237  
  5238    return PlayToggle;
  5239  })(_buttonJs2['default']);
  5240  
  5241  PlayToggle.prototype.controlText_ = 'Play';
  5242  
  5243  _componentJs2['default'].registerComponent('PlayToggle', PlayToggle);
  5244  exports['default'] = PlayToggle;
  5245  module.exports = exports['default'];
  5246  
  5247  },{"../button.js":64,"../component.js":67}],73:[function(_dereq_,module,exports){
  5248  /**
  5249   * @file playback-rate-menu-button.js
  5250   */
  5251  'use strict';
  5252  
  5253  exports.__esModule = true;
  5254  
  5255  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  5256  
  5257  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5258  
  5259  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  5260  
  5261  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  5262  
  5263  var _menuMenuButtonJs = _dereq_('../../menu/menu-button.js');
  5264  
  5265  var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs);
  5266  
  5267  var _menuMenuJs = _dereq_('../../menu/menu.js');
  5268  
  5269  var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs);
  5270  
  5271  var _playbackRateMenuItemJs = _dereq_('./playback-rate-menu-item.js');
  5272  
  5273  var _playbackRateMenuItemJs2 = _interopRequireDefault(_playbackRateMenuItemJs);
  5274  
  5275  var _componentJs = _dereq_('../../component.js');
  5276  
  5277  var _componentJs2 = _interopRequireDefault(_componentJs);
  5278  
  5279  var _utilsDomJs = _dereq_('../../utils/dom.js');
  5280  
  5281  var Dom = _interopRequireWildcard(_utilsDomJs);
  5282  
  5283  /**
  5284   * The component for controlling the playback rate
  5285   *
  5286   * @param {Player|Object} player
  5287   * @param {Object=} options
  5288   * @extends MenuButton
  5289   * @class PlaybackRateMenuButton
  5290   */
  5291  
  5292  var PlaybackRateMenuButton = (function (_MenuButton) {
  5293    _inherits(PlaybackRateMenuButton, _MenuButton);
  5294  
  5295    function PlaybackRateMenuButton(player, options) {
  5296      _classCallCheck(this, PlaybackRateMenuButton);
  5297  
  5298      _MenuButton.call(this, player, options);
  5299  
  5300      this.updateVisibility();
  5301      this.updateLabel();
  5302  
  5303      this.on(player, 'loadstart', this.updateVisibility);
  5304      this.on(player, 'ratechange', this.updateLabel);
  5305    }
  5306  
  5307    /**
  5308     * Create the component's DOM element
  5309     *
  5310     * @return {Element}
  5311     * @method createEl
  5312     */
  5313  
  5314    PlaybackRateMenuButton.prototype.createEl = function createEl() {
  5315      var el = _MenuButton.prototype.createEl.call(this);
  5316  
  5317      this.labelEl_ = Dom.createEl('div', {
  5318        className: 'vjs-playback-rate-value',
  5319        innerHTML: 1.0
  5320      });
  5321  
  5322      el.appendChild(this.labelEl_);
  5323  
  5324      return el;
  5325    };
  5326  
  5327    /**
  5328     * Allow sub components to stack CSS class names
  5329     *
  5330     * @return {String} The constructed class name
  5331     * @method buildCSSClass
  5332     */
  5333  
  5334    PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() {
  5335      return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this);
  5336    };
  5337  
  5338    /**
  5339     * Create the playback rate menu
  5340     *
  5341     * @return {Menu} Menu object populated with items
  5342     * @method createMenu
  5343     */
  5344  
  5345    PlaybackRateMenuButton.prototype.createMenu = function createMenu() {
  5346      var menu = new _menuMenuJs2['default'](this.player());
  5347      var rates = this.playbackRates();
  5348  
  5349      if (rates) {
  5350        for (var i = rates.length - 1; i >= 0; i--) {
  5351          menu.addChild(new _playbackRateMenuItemJs2['default'](this.player(), { 'rate': rates[i] + 'x' }));
  5352        }
  5353      }
  5354  
  5355      return menu;
  5356    };
  5357  
  5358    /**
  5359     * Updates ARIA accessibility attributes
  5360     *
  5361     * @method updateARIAAttributes
  5362     */
  5363  
  5364    PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() {
  5365      // Current playback rate
  5366      this.el().setAttribute('aria-valuenow', this.player().playbackRate());
  5367    };
  5368  
  5369    /**
  5370     * Handle menu item click
  5371     *
  5372     * @method handleClick
  5373     */
  5374  
  5375    PlaybackRateMenuButton.prototype.handleClick = function handleClick() {
  5376      // select next rate option
  5377      var currentRate = this.player().playbackRate();
  5378      var rates = this.playbackRates();
  5379  
  5380      // this will select first one if the last one currently selected
  5381      var newRate = rates[0];
  5382      for (var i = 0; i < rates.length; i++) {
  5383        if (rates[i] > currentRate) {
  5384          newRate = rates[i];
  5385          break;
  5386        }
  5387      }
  5388      this.player().playbackRate(newRate);
  5389    };
  5390  
  5391    /**
  5392     * Get possible playback rates
  5393     *
  5394     * @return {Array} Possible playback rates
  5395     * @method playbackRates
  5396     */
  5397  
  5398    PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() {
  5399      return this.options_['playbackRates'] || this.options_.playerOptions && this.options_.playerOptions['playbackRates'];
  5400    };
  5401  
  5402    /**
  5403     * Get supported playback rates
  5404     *
  5405     * @return {Array} Supported playback rates
  5406     * @method playbackRateSupported
  5407     */
  5408  
  5409    PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() {
  5410      return this.player().tech_ && this.player().tech_['featuresPlaybackRate'] && this.playbackRates() && this.playbackRates().length > 0;
  5411    };
  5412  
  5413    /**
  5414     * Hide playback rate controls when they're no playback rate options to select
  5415     *
  5416     * @method updateVisibility
  5417     */
  5418  
  5419    PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility() {
  5420      if (this.playbackRateSupported()) {
  5421        this.removeClass('vjs-hidden');
  5422      } else {
  5423        this.addClass('vjs-hidden');
  5424      }
  5425    };
  5426  
  5427    /**
  5428     * Update button label when rate changed
  5429     *
  5430     * @method updateLabel
  5431     */
  5432  
  5433    PlaybackRateMenuButton.prototype.updateLabel = function updateLabel() {
  5434      if (this.playbackRateSupported()) {
  5435        this.labelEl_.innerHTML = this.player().playbackRate() + 'x';
  5436      }
  5437    };
  5438  
  5439    return PlaybackRateMenuButton;
  5440  })(_menuMenuButtonJs2['default']);
  5441  
  5442  PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate';
  5443  
  5444  _componentJs2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton);
  5445  exports['default'] = PlaybackRateMenuButton;
  5446  module.exports = exports['default'];
  5447  
  5448  },{"../../component.js":67,"../../menu/menu-button.js":106,"../../menu/menu.js":108,"../../utils/dom.js":134,"./playback-rate-menu-item.js":74}],74:[function(_dereq_,module,exports){
  5449  /**
  5450   * @file playback-rate-menu-item.js
  5451   */
  5452  'use strict';
  5453  
  5454  exports.__esModule = true;
  5455  
  5456  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5457  
  5458  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  5459  
  5460  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  5461  
  5462  var _menuMenuItemJs = _dereq_('../../menu/menu-item.js');
  5463  
  5464  var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);
  5465  
  5466  var _componentJs = _dereq_('../../component.js');
  5467  
  5468  var _componentJs2 = _interopRequireDefault(_componentJs);
  5469  
  5470  /**
  5471   * The specific menu item type for selecting a playback rate
  5472   *
  5473   * @param {Player|Object} player
  5474   * @param {Object=} options
  5475   * @extends MenuItem
  5476   * @class PlaybackRateMenuItem
  5477   */
  5478  
  5479  var PlaybackRateMenuItem = (function (_MenuItem) {
  5480    _inherits(PlaybackRateMenuItem, _MenuItem);
  5481  
  5482    function PlaybackRateMenuItem(player, options) {
  5483      _classCallCheck(this, PlaybackRateMenuItem);
  5484  
  5485      var label = options['rate'];
  5486      var rate = parseFloat(label, 10);
  5487  
  5488      // Modify options for parent MenuItem class's init.
  5489      options['label'] = label;
  5490      options['selected'] = rate === 1;
  5491      _MenuItem.call(this, player, options);
  5492  
  5493      this.label = label;
  5494      this.rate = rate;
  5495  
  5496      this.on(player, 'ratechange', this.update);
  5497    }
  5498  
  5499    /**
  5500     * Handle click on menu item
  5501     *
  5502     * @method handleClick
  5503     */
  5504  
  5505    PlaybackRateMenuItem.prototype.handleClick = function handleClick() {
  5506      _MenuItem.prototype.handleClick.call(this);
  5507      this.player().playbackRate(this.rate);
  5508    };
  5509  
  5510    /**
  5511     * Update playback rate with selected rate
  5512     *
  5513     * @method update
  5514     */
  5515  
  5516    PlaybackRateMenuItem.prototype.update = function update() {
  5517      this.selected(this.player().playbackRate() === this.rate);
  5518    };
  5519  
  5520    return PlaybackRateMenuItem;
  5521  })(_menuMenuItemJs2['default']);
  5522  
  5523  PlaybackRateMenuItem.prototype.contentElType = 'button';
  5524  
  5525  _componentJs2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem);
  5526  exports['default'] = PlaybackRateMenuItem;
  5527  module.exports = exports['default'];
  5528  
  5529  },{"../../component.js":67,"../../menu/menu-item.js":107}],75:[function(_dereq_,module,exports){
  5530  /**
  5531   * @file load-progress-bar.js
  5532   */
  5533  'use strict';
  5534  
  5535  exports.__esModule = true;
  5536  
  5537  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  5538  
  5539  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5540  
  5541  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  5542  
  5543  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  5544  
  5545  var _componentJs = _dereq_('../../component.js');
  5546  
  5547  var _componentJs2 = _interopRequireDefault(_componentJs);
  5548  
  5549  var _utilsDomJs = _dereq_('../../utils/dom.js');
  5550  
  5551  var Dom = _interopRequireWildcard(_utilsDomJs);
  5552  
  5553  /**
  5554   * Shows load progress
  5555   *
  5556   * @param {Player|Object} player
  5557   * @param {Object=} options
  5558   * @extends Component
  5559   * @class LoadProgressBar
  5560   */
  5561  
  5562  var LoadProgressBar = (function (_Component) {
  5563    _inherits(LoadProgressBar, _Component);
  5564  
  5565    function LoadProgressBar(player, options) {
  5566      _classCallCheck(this, LoadProgressBar);
  5567  
  5568      _Component.call(this, player, options);
  5569      this.on(player, 'progress', this.update);
  5570    }
  5571  
  5572    /**
  5573     * Create the component's DOM element
  5574     *
  5575     * @return {Element}
  5576     * @method createEl
  5577     */
  5578  
  5579    LoadProgressBar.prototype.createEl = function createEl() {
  5580      return _Component.prototype.createEl.call(this, 'div', {
  5581        className: 'vjs-load-progress',
  5582        innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>'
  5583      });
  5584    };
  5585  
  5586    /**
  5587     * Update progress bar
  5588     *
  5589     * @method update
  5590     */
  5591  
  5592    LoadProgressBar.prototype.update = function update() {
  5593      var buffered = this.player_.buffered();
  5594      var duration = this.player_.duration();
  5595      var bufferedEnd = this.player_.bufferedEnd();
  5596      var children = this.el_.children;
  5597  
  5598      // get the percent width of a time compared to the total end
  5599      var percentify = function percentify(time, end) {
  5600        var percent = time / end || 0; // no NaN
  5601        return (percent >= 1 ? 1 : percent) * 100 + '%';
  5602      };
  5603  
  5604      // update the width of the progress bar
  5605      this.el_.style.width = percentify(bufferedEnd, duration);
  5606  
  5607      // add child elements to represent the individual buffered time ranges
  5608      for (var i = 0; i < buffered.length; i++) {
  5609        var start = buffered.start(i);
  5610        var end = buffered.end(i);
  5611        var part = children[i];
  5612  
  5613        if (!part) {
  5614          part = this.el_.appendChild(Dom.createEl());
  5615        }
  5616  
  5617        // set the percent based on the width of the progress bar (bufferedEnd)
  5618        part.style.left = percentify(start, bufferedEnd);
  5619        part.style.width = percentify(end - start, bufferedEnd);
  5620      }
  5621  
  5622      // remove unused buffered range elements
  5623      for (var i = children.length; i > buffered.length; i--) {
  5624        this.el_.removeChild(children[i - 1]);
  5625      }
  5626    };
  5627  
  5628    return LoadProgressBar;
  5629  })(_componentJs2['default']);
  5630  
  5631  _componentJs2['default'].registerComponent('LoadProgressBar', LoadProgressBar);
  5632  exports['default'] = LoadProgressBar;
  5633  module.exports = exports['default'];
  5634  
  5635  },{"../../component.js":67,"../../utils/dom.js":134}],76:[function(_dereq_,module,exports){
  5636  /**
  5637   * @file mouse-time-display.js
  5638   */
  5639  'use strict';
  5640  
  5641  exports.__esModule = true;
  5642  
  5643  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  5644  
  5645  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5646  
  5647  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  5648  
  5649  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  5650  
  5651  var _globalWindow = _dereq_('global/window');
  5652  
  5653  var _globalWindow2 = _interopRequireDefault(_globalWindow);
  5654  
  5655  var _componentJs = _dereq_('../../component.js');
  5656  
  5657  var _componentJs2 = _interopRequireDefault(_componentJs);
  5658  
  5659  var _utilsDomJs = _dereq_('../../utils/dom.js');
  5660  
  5661  var Dom = _interopRequireWildcard(_utilsDomJs);
  5662  
  5663  var _utilsFnJs = _dereq_('../../utils/fn.js');
  5664  
  5665  var Fn = _interopRequireWildcard(_utilsFnJs);
  5666  
  5667  var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
  5668  
  5669  var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
  5670  
  5671  var _lodashCompatFunctionThrottle = _dereq_('lodash-compat/function/throttle');
  5672  
  5673  var _lodashCompatFunctionThrottle2 = _interopRequireDefault(_lodashCompatFunctionThrottle);
  5674  
  5675  /**
  5676   * The Mouse Time Display component shows the time you will seek to
  5677   * when hovering over the progress bar
  5678   *
  5679   * @param {Player|Object} player
  5680   * @param {Object=} options
  5681   * @extends Component
  5682   * @class MouseTimeDisplay
  5683   */
  5684  
  5685  var MouseTimeDisplay = (function (_Component) {
  5686    _inherits(MouseTimeDisplay, _Component);
  5687  
  5688    function MouseTimeDisplay(player, options) {
  5689      var _this = this;
  5690  
  5691      _classCallCheck(this, MouseTimeDisplay);
  5692  
  5693      _Component.call(this, player, options);
  5694  
  5695      if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
  5696        this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
  5697      }
  5698  
  5699      if (this.keepTooltipsInside) {
  5700        this.tooltip = Dom.createEl('div', { className: 'vjs-time-tooltip' });
  5701        this.el().appendChild(this.tooltip);
  5702        this.addClass('vjs-keep-tooltips-inside');
  5703      }
  5704  
  5705      this.update(0, 0);
  5706  
  5707      player.on('ready', function () {
  5708        _this.on(player.controlBar.progressControl.el(), 'mousemove', _lodashCompatFunctionThrottle2['default'](Fn.bind(_this, _this.handleMouseMove), 25));
  5709      });
  5710    }
  5711  
  5712    /**
  5713     * Create the component's DOM element
  5714     *
  5715     * @return {Element}
  5716     * @method createEl
  5717     */
  5718  
  5719    MouseTimeDisplay.prototype.createEl = function createEl() {
  5720      return _Component.prototype.createEl.call(this, 'div', {
  5721        className: 'vjs-mouse-display'
  5722      });
  5723    };
  5724  
  5725    MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) {
  5726      var duration = this.player_.duration();
  5727      var newTime = this.calculateDistance(event) * duration;
  5728      var position = event.pageX - Dom.findElPosition(this.el().parentNode).left;
  5729  
  5730      this.update(newTime, position);
  5731    };
  5732  
  5733    MouseTimeDisplay.prototype.update = function update(newTime, position) {
  5734      var time = _utilsFormatTimeJs2['default'](newTime, this.player_.duration());
  5735  
  5736      this.el().style.left = position + 'px';
  5737      this.el().setAttribute('data-current-time', time);
  5738  
  5739      if (this.keepTooltipsInside) {
  5740        var clampedPosition = this.clampPosition_(position);
  5741        var difference = position - clampedPosition + 1;
  5742        var tooltipWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.tooltip).width);
  5743        var tooltipWidthHalf = tooltipWidth / 2;
  5744  
  5745        this.tooltip.innerHTML = time;
  5746        this.tooltip.style.right = '-' + (tooltipWidthHalf - difference) + 'px';
  5747      }
  5748    };
  5749  
  5750    MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) {
  5751      return Dom.getPointerPosition(this.el().parentNode, event).x;
  5752    };
  5753  
  5754    /**
  5755     * This takes in a horizontal position for the bar and returns a clamped position.
  5756     * Clamped position means that it will keep the position greater than half the width
  5757     * of the tooltip and smaller than the player width minus half the width o the tooltip.
  5758     * It will only clamp the position if `keepTooltipsInside` option is set.
  5759     *
  5760     * @param {Number} position the position the bar wants to be
  5761     * @return {Number} newPosition the (potentially) clamped position
  5762     * @method clampPosition_
  5763     */
  5764  
  5765    MouseTimeDisplay.prototype.clampPosition_ = function clampPosition_(position) {
  5766      if (!this.keepTooltipsInside) {
  5767        return position;
  5768      }
  5769  
  5770      var playerWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.player().el()).width);
  5771      var tooltipWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.tooltip).width);
  5772      var tooltipWidthHalf = tooltipWidth / 2;
  5773      var actualPosition = position;
  5774  
  5775      if (position < tooltipWidthHalf) {
  5776        actualPosition = Math.ceil(tooltipWidthHalf);
  5777      } else if (position > playerWidth - tooltipWidthHalf) {
  5778        actualPosition = Math.floor(playerWidth - tooltipWidthHalf);
  5779      }
  5780  
  5781      return actualPosition;
  5782    };
  5783  
  5784    return MouseTimeDisplay;
  5785  })(_componentJs2['default']);
  5786  
  5787  _componentJs2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay);
  5788  exports['default'] = MouseTimeDisplay;
  5789  module.exports = exports['default'];
  5790  
  5791  },{"../../component.js":67,"../../utils/dom.js":134,"../../utils/fn.js":136,"../../utils/format-time.js":137,"global/window":2,"lodash-compat/function/throttle":7}],77:[function(_dereq_,module,exports){
  5792  /**
  5793   * @file play-progress-bar.js
  5794   */
  5795  'use strict';
  5796  
  5797  exports.__esModule = true;
  5798  
  5799  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  5800  
  5801  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5802  
  5803  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  5804  
  5805  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  5806  
  5807  var _componentJs = _dereq_('../../component.js');
  5808  
  5809  var _componentJs2 = _interopRequireDefault(_componentJs);
  5810  
  5811  var _utilsFnJs = _dereq_('../../utils/fn.js');
  5812  
  5813  var Fn = _interopRequireWildcard(_utilsFnJs);
  5814  
  5815  var _utilsDomJs = _dereq_('../../utils/dom.js');
  5816  
  5817  var Dom = _interopRequireWildcard(_utilsDomJs);
  5818  
  5819  var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
  5820  
  5821  var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
  5822  
  5823  /**
  5824   * Shows play progress
  5825   *
  5826   * @param {Player|Object} player
  5827   * @param {Object=} options
  5828   * @extends Component
  5829   * @class PlayProgressBar
  5830   */
  5831  
  5832  var PlayProgressBar = (function (_Component) {
  5833    _inherits(PlayProgressBar, _Component);
  5834  
  5835    function PlayProgressBar(player, options) {
  5836      _classCallCheck(this, PlayProgressBar);
  5837  
  5838      _Component.call(this, player, options);
  5839      this.updateDataAttr();
  5840      this.on(player, 'timeupdate', this.updateDataAttr);
  5841      player.ready(Fn.bind(this, this.updateDataAttr));
  5842  
  5843      if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
  5844        this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
  5845      }
  5846  
  5847      if (this.keepTooltipsInside) {
  5848        this.addClass('vjs-keep-tooltips-inside');
  5849      }
  5850    }
  5851  
  5852    /**
  5853     * Create the component's DOM element
  5854     *
  5855     * @return {Element}
  5856     * @method createEl
  5857     */
  5858  
  5859    PlayProgressBar.prototype.createEl = function createEl() {
  5860      return _Component.prototype.createEl.call(this, 'div', {
  5861        className: 'vjs-play-progress vjs-slider-bar',
  5862        innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
  5863      });
  5864    };
  5865  
  5866    PlayProgressBar.prototype.updateDataAttr = function updateDataAttr() {
  5867      var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
  5868      this.el_.setAttribute('data-current-time', _utilsFormatTimeJs2['default'](time, this.player_.duration()));
  5869    };
  5870  
  5871    return PlayProgressBar;
  5872  })(_componentJs2['default']);
  5873  
  5874  _componentJs2['default'].registerComponent('PlayProgressBar', PlayProgressBar);
  5875  exports['default'] = PlayProgressBar;
  5876  module.exports = exports['default'];
  5877  
  5878  },{"../../component.js":67,"../../utils/dom.js":134,"../../utils/fn.js":136,"../../utils/format-time.js":137}],78:[function(_dereq_,module,exports){
  5879  /**
  5880   * @file progress-control.js
  5881   */
  5882  'use strict';
  5883  
  5884  exports.__esModule = true;
  5885  
  5886  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5887  
  5888  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  5889  
  5890  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  5891  
  5892  var _componentJs = _dereq_('../../component.js');
  5893  
  5894  var _componentJs2 = _interopRequireDefault(_componentJs);
  5895  
  5896  var _seekBarJs = _dereq_('./seek-bar.js');
  5897  
  5898  var _seekBarJs2 = _interopRequireDefault(_seekBarJs);
  5899  
  5900  var _mouseTimeDisplayJs = _dereq_('./mouse-time-display.js');
  5901  
  5902  var _mouseTimeDisplayJs2 = _interopRequireDefault(_mouseTimeDisplayJs);
  5903  
  5904  /**
  5905   * The Progress Control component contains the seek bar, load progress,
  5906   * and play progress
  5907   *
  5908   * @param {Player|Object} player
  5909   * @param {Object=} options
  5910   * @extends Component
  5911   * @class ProgressControl
  5912   */
  5913  
  5914  var ProgressControl = (function (_Component) {
  5915    _inherits(ProgressControl, _Component);
  5916  
  5917    function ProgressControl() {
  5918      _classCallCheck(this, ProgressControl);
  5919  
  5920      _Component.apply(this, arguments);
  5921    }
  5922  
  5923    /**
  5924     * Create the component's DOM element
  5925     *
  5926     * @return {Element}
  5927     * @method createEl
  5928     */
  5929  
  5930    ProgressControl.prototype.createEl = function createEl() {
  5931      return _Component.prototype.createEl.call(this, 'div', {
  5932        className: 'vjs-progress-control vjs-control'
  5933      });
  5934    };
  5935  
  5936    return ProgressControl;
  5937  })(_componentJs2['default']);
  5938  
  5939  ProgressControl.prototype.options_ = {
  5940    children: ['seekBar']
  5941  };
  5942  
  5943  _componentJs2['default'].registerComponent('ProgressControl', ProgressControl);
  5944  exports['default'] = ProgressControl;
  5945  module.exports = exports['default'];
  5946  
  5947  },{"../../component.js":67,"./mouse-time-display.js":76,"./seek-bar.js":79}],79:[function(_dereq_,module,exports){
  5948  /**
  5949   * @file seek-bar.js
  5950   */
  5951  'use strict';
  5952  
  5953  exports.__esModule = true;
  5954  
  5955  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  5956  
  5957  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5958  
  5959  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  5960  
  5961  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  5962  
  5963  var _globalWindow = _dereq_('global/window');
  5964  
  5965  var _globalWindow2 = _interopRequireDefault(_globalWindow);
  5966  
  5967  var _sliderSliderJs = _dereq_('../../slider/slider.js');
  5968  
  5969  var _sliderSliderJs2 = _interopRequireDefault(_sliderSliderJs);
  5970  
  5971  var _componentJs = _dereq_('../../component.js');
  5972  
  5973  var _componentJs2 = _interopRequireDefault(_componentJs);
  5974  
  5975  var _loadProgressBarJs = _dereq_('./load-progress-bar.js');
  5976  
  5977  var _loadProgressBarJs2 = _interopRequireDefault(_loadProgressBarJs);
  5978  
  5979  var _playProgressBarJs = _dereq_('./play-progress-bar.js');
  5980  
  5981  var _playProgressBarJs2 = _interopRequireDefault(_playProgressBarJs);
  5982  
  5983  var _tooltipProgressBarJs = _dereq_('./tooltip-progress-bar.js');
  5984  
  5985  var _tooltipProgressBarJs2 = _interopRequireDefault(_tooltipProgressBarJs);
  5986  
  5987  var _utilsFnJs = _dereq_('../../utils/fn.js');
  5988  
  5989  var Fn = _interopRequireWildcard(_utilsFnJs);
  5990  
  5991  var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
  5992  
  5993  var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
  5994  
  5995  var _objectAssign = _dereq_('object.assign');
  5996  
  5997  var _objectAssign2 = _interopRequireDefault(_objectAssign);
  5998  
  5999  /**
  6000   * Seek Bar and holder for the progress bars
  6001   *
  6002   * @param {Player|Object} player
  6003   * @param {Object=} options
  6004   * @extends Slider
  6005   * @class SeekBar
  6006   */
  6007  
  6008  var SeekBar = (function (_Slider) {
  6009    _inherits(SeekBar, _Slider);
  6010  
  6011    function SeekBar(player, options) {
  6012      _classCallCheck(this, SeekBar);
  6013  
  6014      _Slider.call(this, player, options);
  6015      this.on(player, 'timeupdate', this.updateProgress);
  6016      this.on(player, 'ended', this.updateProgress);
  6017      player.ready(Fn.bind(this, this.updateProgress));
  6018  
  6019      if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
  6020        this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
  6021      }
  6022  
  6023      if (this.keepTooltipsInside) {
  6024        this.tooltipProgressBar = this.addChild('TooltipProgressBar');
  6025      }
  6026    }
  6027  
  6028    /**
  6029     * Create the component's DOM element
  6030     *
  6031     * @return {Element}
  6032     * @method createEl
  6033     */
  6034  
  6035    SeekBar.prototype.createEl = function createEl() {
  6036      return _Slider.prototype.createEl.call(this, 'div', {
  6037        className: 'vjs-progress-holder'
  6038      }, {
  6039        'aria-label': 'progress bar'
  6040      });
  6041    };
  6042  
  6043    /**
  6044     * Update ARIA accessibility attributes
  6045     *
  6046     * @method updateARIAAttributes
  6047     */
  6048  
  6049    SeekBar.prototype.updateProgress = function updateProgress() {
  6050      this.updateAriaAttributes(this.el_);
  6051  
  6052      if (this.keepTooltipsInside) {
  6053        this.updateAriaAttributes(this.tooltipProgressBar.el_);
  6054        this.tooltipProgressBar.el_.style.width = this.bar.el_.style.width;
  6055  
  6056        var playerWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.player().el()).width);
  6057        var tooltipWidth = parseFloat(_globalWindow2['default'].getComputedStyle(this.tooltipProgressBar.tooltip).width);
  6058        var tooltipStyle = this.tooltipProgressBar.el().style;
  6059        tooltipStyle.maxWidth = Math.floor(playerWidth - tooltipWidth / 2) + 'px';
  6060        tooltipStyle.minWidth = Math.ceil(tooltipWidth / 2) + 'px';
  6061        tooltipStyle.right = '-' + tooltipWidth / 2 + 'px';
  6062      }
  6063    };
  6064  
  6065    SeekBar.prototype.updateAriaAttributes = function updateAriaAttributes(el) {
  6066      // Allows for smooth scrubbing, when player can't keep up.
  6067      var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
  6068      el.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2)); // machine readable value of progress bar (percentage complete)
  6069      el.setAttribute('aria-valuetext', _utilsFormatTimeJs2['default'](time, this.player_.duration())); // human readable value of progress bar (time complete)
  6070    };
  6071  
  6072    /**
  6073     * Get percentage of video played
  6074     *
  6075     * @return {Number} Percentage played
  6076     * @method getPercent
  6077     */
  6078  
  6079    SeekBar.prototype.getPercent = function getPercent() {
  6080      var percent = this.player_.currentTime() / this.player_.duration();
  6081      return percent >= 1 ? 1 : percent;
  6082    };
  6083  
  6084    /**
  6085     * Handle mouse down on seek bar
  6086     *
  6087     * @method handleMouseDown
  6088     */
  6089  
  6090    SeekBar.prototype.handleMouseDown = function handleMouseDown(event) {
  6091      _Slider.prototype.handleMouseDown.call(this, event);
  6092  
  6093      this.player_.scrubbing(true);
  6094  
  6095      this.videoWasPlaying = !this.player_.paused();
  6096      this.player_.pause();
  6097    };
  6098  
  6099    /**
  6100     * Handle mouse move on seek bar
  6101     *
  6102     * @method handleMouseMove
  6103     */
  6104  
  6105    SeekBar.prototype.handleMouseMove = function handleMouseMove(event) {
  6106      var newTime = this.calculateDistance(event) * this.player_.duration();
  6107  
  6108      // Don't let video end while scrubbing.
  6109      if (newTime === this.player_.duration()) {
  6110        newTime = newTime - 0.1;
  6111      }
  6112  
  6113      // Set new time (tell player to seek to new time)
  6114      this.player_.currentTime(newTime);
  6115    };
  6116  
  6117    /**
  6118     * Handle mouse up on seek bar
  6119     *
  6120     * @method handleMouseUp
  6121     */
  6122  
  6123    SeekBar.prototype.handleMouseUp = function handleMouseUp(event) {
  6124      _Slider.prototype.handleMouseUp.call(this, event);
  6125  
  6126      this.player_.scrubbing(false);
  6127      if (this.videoWasPlaying) {
  6128        this.player_.play();
  6129      }
  6130    };
  6131  
  6132    /**
  6133     * Move more quickly fast forward for keyboard-only users
  6134     *
  6135     * @method stepForward
  6136     */
  6137  
  6138    SeekBar.prototype.stepForward = function stepForward() {
  6139      this.player_.currentTime(this.player_.currentTime() + 5); // more quickly fast forward for keyboard-only users
  6140    };
  6141  
  6142    /**
  6143     * Move more quickly rewind for keyboard-only users
  6144     *
  6145     * @method stepBack
  6146     */
  6147  
  6148    SeekBar.prototype.stepBack = function stepBack() {
  6149      this.player_.currentTime(this.player_.currentTime() - 5); // more quickly rewind for keyboard-only users
  6150    };
  6151  
  6152    return SeekBar;
  6153  })(_sliderSliderJs2['default']);
  6154  
  6155  SeekBar.prototype.options_ = {
  6156    children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'],
  6157    'barName': 'playProgressBar'
  6158  };
  6159  
  6160  SeekBar.prototype.playerEvent = 'timeupdate';
  6161  
  6162  _componentJs2['default'].registerComponent('SeekBar', SeekBar);
  6163  exports['default'] = SeekBar;
  6164  module.exports = exports['default'];
  6165  
  6166  },{"../../component.js":67,"../../slider/slider.js":116,"../../utils/fn.js":136,"../../utils/format-time.js":137,"./load-progress-bar.js":75,"./play-progress-bar.js":77,"./tooltip-progress-bar.js":80,"global/window":2,"object.assign":45}],80:[function(_dereq_,module,exports){
  6167  /**
  6168   * @file play-progress-bar.js
  6169   */
  6170  'use strict';
  6171  
  6172  exports.__esModule = true;
  6173  
  6174  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  6175  
  6176  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6177  
  6178  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  6179  
  6180  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  6181  
  6182  var _componentJs = _dereq_('../../component.js');
  6183  
  6184  var _componentJs2 = _interopRequireDefault(_componentJs);
  6185  
  6186  var _utilsFnJs = _dereq_('../../utils/fn.js');
  6187  
  6188  var Fn = _interopRequireWildcard(_utilsFnJs);
  6189  
  6190  var _utilsDomJs = _dereq_('../../utils/dom.js');
  6191  
  6192  var Dom = _interopRequireWildcard(_utilsDomJs);
  6193  
  6194  var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
  6195  
  6196  var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
  6197  
  6198  /**
  6199   * Shows play progress
  6200   *
  6201   * @param {Player|Object} player
  6202   * @param {Object=} options
  6203   * @extends Component
  6204   * @class PlayProgressBar
  6205   */
  6206  
  6207  var TooltipProgressBar = (function (_Component) {
  6208    _inherits(TooltipProgressBar, _Component);
  6209  
  6210    function TooltipProgressBar(player, options) {
  6211      _classCallCheck(this, TooltipProgressBar);
  6212  
  6213      _Component.call(this, player, options);
  6214      this.updateDataAttr();
  6215      this.on(player, 'timeupdate', this.updateDataAttr);
  6216      player.ready(Fn.bind(this, this.updateDataAttr));
  6217    }
  6218  
  6219    /**
  6220     * Create the component's DOM element
  6221     *
  6222     * @return {Element}
  6223     * @method createEl
  6224     */
  6225  
  6226    TooltipProgressBar.prototype.createEl = function createEl() {
  6227      var el = _Component.prototype.createEl.call(this, 'div', {
  6228        className: 'vjs-tooltip-progress-bar vjs-slider-bar',
  6229        innerHTML: '<div class="vjs-time-tooltip"></div>\n        <span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
  6230      });
  6231  
  6232      this.tooltip = el.querySelector('.vjs-time-tooltip');
  6233  
  6234      return el;
  6235    };
  6236  
  6237    TooltipProgressBar.prototype.updateDataAttr = function updateDataAttr() {
  6238      var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
  6239      var formattedTime = _utilsFormatTimeJs2['default'](time, this.player_.duration());
  6240      this.el_.setAttribute('data-current-time', formattedTime);
  6241      this.tooltip.innerHTML = formattedTime;
  6242    };
  6243  
  6244    return TooltipProgressBar;
  6245  })(_componentJs2['default']);
  6246  
  6247  _componentJs2['default'].registerComponent('TooltipProgressBar', TooltipProgressBar);
  6248  exports['default'] = TooltipProgressBar;
  6249  module.exports = exports['default'];
  6250  
  6251  },{"../../component.js":67,"../../utils/dom.js":134,"../../utils/fn.js":136,"../../utils/format-time.js":137}],81:[function(_dereq_,module,exports){
  6252  /**
  6253   * @file custom-control-spacer.js
  6254   */
  6255  'use strict';
  6256  
  6257  exports.__esModule = true;
  6258  
  6259  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6260  
  6261  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  6262  
  6263  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  6264  
  6265  var _spacerJs = _dereq_('./spacer.js');
  6266  
  6267  var _spacerJs2 = _interopRequireDefault(_spacerJs);
  6268  
  6269  var _componentJs = _dereq_('../../component.js');
  6270  
  6271  var _componentJs2 = _interopRequireDefault(_componentJs);
  6272  
  6273  /**
  6274   * Spacer specifically meant to be used as an insertion point for new plugins, etc.
  6275   *
  6276   * @extends Spacer
  6277   * @class CustomControlSpacer
  6278   */
  6279  
  6280  var CustomControlSpacer = (function (_Spacer) {
  6281    _inherits(CustomControlSpacer, _Spacer);
  6282  
  6283    function CustomControlSpacer() {
  6284      _classCallCheck(this, CustomControlSpacer);
  6285  
  6286      _Spacer.apply(this, arguments);
  6287    }
  6288  
  6289    /**
  6290     * Allow sub components to stack CSS class names
  6291     *
  6292     * @return {String} The constructed class name
  6293     * @method buildCSSClass
  6294     */
  6295  
  6296    CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() {
  6297      return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this);
  6298    };
  6299  
  6300    /**
  6301     * Create the component's DOM element
  6302     *
  6303     * @return {Element}
  6304     * @method createEl
  6305     */
  6306  
  6307    CustomControlSpacer.prototype.createEl = function createEl() {
  6308      var el = _Spacer.prototype.createEl.call(this, {
  6309        className: this.buildCSSClass()
  6310      });
  6311  
  6312      // No-flex/table-cell mode requires there be some content
  6313      // in the cell to fill the remaining space of the table.
  6314      el.innerHTML = '&nbsp;';
  6315      return el;
  6316    };
  6317  
  6318    return CustomControlSpacer;
  6319  })(_spacerJs2['default']);
  6320  
  6321  _componentJs2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer);
  6322  exports['default'] = CustomControlSpacer;
  6323  module.exports = exports['default'];
  6324  
  6325  },{"../../component.js":67,"./spacer.js":82}],82:[function(_dereq_,module,exports){
  6326  /**
  6327   * @file spacer.js
  6328   */
  6329  'use strict';
  6330  
  6331  exports.__esModule = true;
  6332  
  6333  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6334  
  6335  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  6336  
  6337  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  6338  
  6339  var _componentJs = _dereq_('../../component.js');
  6340  
  6341  var _componentJs2 = _interopRequireDefault(_componentJs);
  6342  
  6343  /**
  6344   * Just an empty spacer element that can be used as an append point for plugins, etc.
  6345   * Also can be used to create space between elements when necessary.
  6346   *
  6347   * @extends Component
  6348   * @class Spacer
  6349   */
  6350  
  6351  var Spacer = (function (_Component) {
  6352    _inherits(Spacer, _Component);
  6353  
  6354    function Spacer() {
  6355      _classCallCheck(this, Spacer);
  6356  
  6357      _Component.apply(this, arguments);
  6358    }
  6359  
  6360    /**
  6361     * Allow sub components to stack CSS class names
  6362     *
  6363     * @return {String} The constructed class name
  6364     * @method buildCSSClass
  6365     */
  6366  
  6367    Spacer.prototype.buildCSSClass = function buildCSSClass() {
  6368      return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this);
  6369    };
  6370  
  6371    /**
  6372     * Create the component's DOM element
  6373     *
  6374     * @return {Element}
  6375     * @method createEl
  6376     */
  6377  
  6378    Spacer.prototype.createEl = function createEl() {
  6379      return _Component.prototype.createEl.call(this, 'div', {
  6380        className: this.buildCSSClass()
  6381      });
  6382    };
  6383  
  6384    return Spacer;
  6385  })(_componentJs2['default']);
  6386  
  6387  _componentJs2['default'].registerComponent('Spacer', Spacer);
  6388  
  6389  exports['default'] = Spacer;
  6390  module.exports = exports['default'];
  6391  
  6392  },{"../../component.js":67}],83:[function(_dereq_,module,exports){
  6393  /**
  6394   * @file caption-settings-menu-item.js
  6395   */
  6396  'use strict';
  6397  
  6398  exports.__esModule = true;
  6399  
  6400  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6401  
  6402  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  6403  
  6404  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  6405  
  6406  var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');
  6407  
  6408  var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);
  6409  
  6410  var _componentJs = _dereq_('../../component.js');
  6411  
  6412  var _componentJs2 = _interopRequireDefault(_componentJs);
  6413  
  6414  /**
  6415   * The menu item for caption track settings menu
  6416   *
  6417   * @param {Player|Object} player
  6418   * @param {Object=} options
  6419   * @extends TextTrackMenuItem
  6420   * @class CaptionSettingsMenuItem
  6421   */
  6422  
  6423  var CaptionSettingsMenuItem = (function (_TextTrackMenuItem) {
  6424    _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem);
  6425  
  6426    function CaptionSettingsMenuItem(player, options) {
  6427      _classCallCheck(this, CaptionSettingsMenuItem);
  6428  
  6429      options['track'] = {
  6430        'kind': options['kind'],
  6431        'player': player,
  6432        'label': options['kind'] + ' settings',
  6433        'selectable': false,
  6434        'default': false,
  6435        mode: 'disabled'
  6436      };
  6437  
  6438      // CaptionSettingsMenuItem has no concept of 'selected'
  6439      options['selectable'] = false;
  6440  
  6441      _TextTrackMenuItem.call(this, player, options);
  6442      this.addClass('vjs-texttrack-settings');
  6443      this.controlText(', opens ' + options['kind'] + ' settings dialog');
  6444    }
  6445  
  6446    /**
  6447     * Handle click on menu item
  6448     *
  6449     * @method handleClick
  6450     */
  6451  
  6452    CaptionSettingsMenuItem.prototype.handleClick = function handleClick() {
  6453      this.player().getChild('textTrackSettings').show();
  6454      this.player().getChild('textTrackSettings').el_.focus();
  6455    };
  6456  
  6457    return CaptionSettingsMenuItem;
  6458  })(_textTrackMenuItemJs2['default']);
  6459  
  6460  _componentJs2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem);
  6461  exports['default'] = CaptionSettingsMenuItem;
  6462  module.exports = exports['default'];
  6463  
  6464  },{"../../component.js":67,"./text-track-menu-item.js":91}],84:[function(_dereq_,module,exports){
  6465  /**
  6466   * @file captions-button.js
  6467   */
  6468  'use strict';
  6469  
  6470  exports.__esModule = true;
  6471  
  6472  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6473  
  6474  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  6475  
  6476  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  6477  
  6478  var _textTrackButtonJs = _dereq_('./text-track-button.js');
  6479  
  6480  var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs);
  6481  
  6482  var _componentJs = _dereq_('../../component.js');
  6483  
  6484  var _componentJs2 = _interopRequireDefault(_componentJs);
  6485  
  6486  var _captionSettingsMenuItemJs = _dereq_('./caption-settings-menu-item.js');
  6487  
  6488  var _captionSettingsMenuItemJs2 = _interopRequireDefault(_captionSettingsMenuItemJs);
  6489  
  6490  /**
  6491   * The button component for toggling and selecting captions
  6492   *
  6493   * @param {Object} player  Player object
  6494   * @param {Object=} options Object of option names and values
  6495   * @param {Function=} ready    Ready callback function
  6496   * @extends TextTrackButton
  6497   * @class CaptionsButton
  6498   */
  6499  
  6500  var CaptionsButton = (function (_TextTrackButton) {
  6501    _inherits(CaptionsButton, _TextTrackButton);
  6502  
  6503    function CaptionsButton(player, options, ready) {
  6504      _classCallCheck(this, CaptionsButton);
  6505  
  6506      _TextTrackButton.call(this, player, options, ready);
  6507      this.el_.setAttribute('aria-label', 'Captions Menu');
  6508    }
  6509  
  6510    /**
  6511     * Allow sub components to stack CSS class names
  6512     *
  6513     * @return {String} The constructed class name
  6514     * @method buildCSSClass
  6515     */
  6516  
  6517    CaptionsButton.prototype.buildCSSClass = function buildCSSClass() {
  6518      return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  6519    };
  6520  
  6521    /**
  6522     * Update caption menu items
  6523     *
  6524     * @method update
  6525     */
  6526  
  6527    CaptionsButton.prototype.update = function update() {
  6528      var threshold = 2;
  6529      _TextTrackButton.prototype.update.call(this);
  6530  
  6531      // if native, then threshold is 1 because no settings button
  6532      if (this.player().tech_ && this.player().tech_['featuresNativeTextTracks']) {
  6533        threshold = 1;
  6534      }
  6535  
  6536      if (this.items && this.items.length > threshold) {
  6537        this.show();
  6538      } else {
  6539        this.hide();
  6540      }
  6541    };
  6542  
  6543    /**
  6544     * Create caption menu items
  6545     *
  6546     * @return {Array} Array of menu items
  6547     * @method createItems
  6548     */
  6549  
  6550    CaptionsButton.prototype.createItems = function createItems() {
  6551      var items = [];
  6552  
  6553      if (!(this.player().tech_ && this.player().tech_['featuresNativeTextTracks'])) {
  6554        items.push(new _captionSettingsMenuItemJs2['default'](this.player_, { 'kind': this.kind_ }));
  6555      }
  6556  
  6557      return _TextTrackButton.prototype.createItems.call(this, items);
  6558    };
  6559  
  6560    return CaptionsButton;
  6561  })(_textTrackButtonJs2['default']);
  6562  
  6563  CaptionsButton.prototype.kind_ = 'captions';
  6564  CaptionsButton.prototype.controlText_ = 'Captions';
  6565  
  6566  _componentJs2['default'].registerComponent('CaptionsButton', CaptionsButton);
  6567  exports['default'] = CaptionsButton;
  6568  module.exports = exports['default'];
  6569  
  6570  },{"../../component.js":67,"./caption-settings-menu-item.js":83,"./text-track-button.js":90}],85:[function(_dereq_,module,exports){
  6571  /**
  6572   * @file chapters-button.js
  6573   */
  6574  'use strict';
  6575  
  6576  exports.__esModule = true;
  6577  
  6578  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  6579  
  6580  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6581  
  6582  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  6583  
  6584  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  6585  
  6586  var _textTrackButtonJs = _dereq_('./text-track-button.js');
  6587  
  6588  var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs);
  6589  
  6590  var _componentJs = _dereq_('../../component.js');
  6591  
  6592  var _componentJs2 = _interopRequireDefault(_componentJs);
  6593  
  6594  var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');
  6595  
  6596  var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);
  6597  
  6598  var _chaptersTrackMenuItemJs = _dereq_('./chapters-track-menu-item.js');
  6599  
  6600  var _chaptersTrackMenuItemJs2 = _interopRequireDefault(_chaptersTrackMenuItemJs);
  6601  
  6602  var _menuMenuJs = _dereq_('../../menu/menu.js');
  6603  
  6604  var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs);
  6605  
  6606  var _utilsDomJs = _dereq_('../../utils/dom.js');
  6607  
  6608  var Dom = _interopRequireWildcard(_utilsDomJs);
  6609  
  6610  var _utilsFnJs = _dereq_('../../utils/fn.js');
  6611  
  6612  var Fn = _interopRequireWildcard(_utilsFnJs);
  6613  
  6614  var _utilsToTitleCaseJs = _dereq_('../../utils/to-title-case.js');
  6615  
  6616  var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
  6617  
  6618  var _globalWindow = _dereq_('global/window');
  6619  
  6620  var _globalWindow2 = _interopRequireDefault(_globalWindow);
  6621  
  6622  /**
  6623   * The button component for toggling and selecting chapters
  6624   * Chapters act much differently than other text tracks
  6625   * Cues are navigation vs. other tracks of alternative languages
  6626   *
  6627   * @param {Object} player  Player object
  6628   * @param {Object=} options Object of option names and values
  6629   * @param {Function=} ready    Ready callback function
  6630   * @extends TextTrackButton
  6631   * @class ChaptersButton
  6632   */
  6633  
  6634  var ChaptersButton = (function (_TextTrackButton) {
  6635    _inherits(ChaptersButton, _TextTrackButton);
  6636  
  6637    function ChaptersButton(player, options, ready) {
  6638      _classCallCheck(this, ChaptersButton);
  6639  
  6640      _TextTrackButton.call(this, player, options, ready);
  6641      this.el_.setAttribute('aria-label', 'Chapters Menu');
  6642    }
  6643  
  6644    /**
  6645     * Allow sub components to stack CSS class names
  6646     *
  6647     * @return {String} The constructed class name
  6648     * @method buildCSSClass
  6649     */
  6650  
  6651    ChaptersButton.prototype.buildCSSClass = function buildCSSClass() {
  6652      return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  6653    };
  6654  
  6655    /**
  6656     * Create a menu item for each text track
  6657     *
  6658     * @return {Array} Array of menu items
  6659     * @method createItems
  6660     */
  6661  
  6662    ChaptersButton.prototype.createItems = function createItems() {
  6663      var items = [];
  6664  
  6665      var tracks = this.player_.textTracks();
  6666  
  6667      if (!tracks) {
  6668        return items;
  6669      }
  6670  
  6671      for (var i = 0; i < tracks.length; i++) {
  6672        var track = tracks[i];
  6673        if (track['kind'] === this.kind_) {
  6674          items.push(new _textTrackMenuItemJs2['default'](this.player_, {
  6675            'track': track
  6676          }));
  6677        }
  6678      }
  6679  
  6680      return items;
  6681    };
  6682  
  6683    /**
  6684     * Create menu from chapter buttons
  6685     *
  6686     * @return {Menu} Menu of chapter buttons
  6687     * @method createMenu
  6688     */
  6689  
  6690    ChaptersButton.prototype.createMenu = function createMenu() {
  6691      var _this = this;
  6692  
  6693      var tracks = this.player_.textTracks() || [];
  6694      var chaptersTrack = undefined;
  6695      var items = this.items = [];
  6696  
  6697      for (var i = 0, _length = tracks.length; i < _length; i++) {
  6698        var track = tracks[i];
  6699  
  6700        if (track['kind'] === this.kind_) {
  6701          chaptersTrack = track;
  6702  
  6703          break;
  6704        }
  6705      }
  6706  
  6707      var menu = this.menu;
  6708      if (menu === undefined) {
  6709        menu = new _menuMenuJs2['default'](this.player_);
  6710        var title = Dom.createEl('li', {
  6711          className: 'vjs-menu-title',
  6712          innerHTML: _utilsToTitleCaseJs2['default'](this.kind_),
  6713          tabIndex: -1
  6714        });
  6715        menu.children_.unshift(title);
  6716        Dom.insertElFirst(title, menu.contentEl());
  6717      }
  6718  
  6719      if (chaptersTrack && chaptersTrack.cues == null) {
  6720        chaptersTrack['mode'] = 'hidden';
  6721  
  6722        var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(chaptersTrack);
  6723  
  6724        if (remoteTextTrackEl) {
  6725          remoteTextTrackEl.addEventListener('load', function (event) {
  6726            return _this.update();
  6727          });
  6728        }
  6729      }
  6730  
  6731      if (chaptersTrack && chaptersTrack.cues && chaptersTrack.cues.length > 0) {
  6732        var cues = chaptersTrack['cues'],
  6733            cue = undefined;
  6734  
  6735        for (var i = 0, l = cues.length; i < l; i++) {
  6736          cue = cues[i];
  6737  
  6738          var mi = new _chaptersTrackMenuItemJs2['default'](this.player_, {
  6739            'track': chaptersTrack,
  6740            'cue': cue
  6741          });
  6742  
  6743          items.push(mi);
  6744  
  6745          menu.addChild(mi);
  6746        }
  6747  
  6748        this.addChild(menu);
  6749      }
  6750  
  6751      if (this.items.length > 0) {
  6752        this.show();
  6753      }
  6754  
  6755      return menu;
  6756    };
  6757  
  6758    return ChaptersButton;
  6759  })(_textTrackButtonJs2['default']);
  6760  
  6761  ChaptersButton.prototype.kind_ = 'chapters';
  6762  ChaptersButton.prototype.controlText_ = 'Chapters';
  6763  
  6764  _componentJs2['default'].registerComponent('ChaptersButton', ChaptersButton);
  6765  exports['default'] = ChaptersButton;
  6766  module.exports = exports['default'];
  6767  
  6768  },{"../../component.js":67,"../../menu/menu.js":108,"../../utils/dom.js":134,"../../utils/fn.js":136,"../../utils/to-title-case.js":143,"./chapters-track-menu-item.js":86,"./text-track-button.js":90,"./text-track-menu-item.js":91,"global/window":2}],86:[function(_dereq_,module,exports){
  6769  /**
  6770   * @file chapters-track-menu-item.js
  6771   */
  6772  'use strict';
  6773  
  6774  exports.__esModule = true;
  6775  
  6776  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  6777  
  6778  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6779  
  6780  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  6781  
  6782  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  6783  
  6784  var _menuMenuItemJs = _dereq_('../../menu/menu-item.js');
  6785  
  6786  var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);
  6787  
  6788  var _componentJs = _dereq_('../../component.js');
  6789  
  6790  var _componentJs2 = _interopRequireDefault(_componentJs);
  6791  
  6792  var _utilsFnJs = _dereq_('../../utils/fn.js');
  6793  
  6794  var Fn = _interopRequireWildcard(_utilsFnJs);
  6795  
  6796  /**
  6797   * The chapter track menu item
  6798   *
  6799   * @param {Player|Object} player
  6800   * @param {Object=} options
  6801   * @extends MenuItem
  6802   * @class ChaptersTrackMenuItem
  6803   */
  6804  
  6805  var ChaptersTrackMenuItem = (function (_MenuItem) {
  6806    _inherits(ChaptersTrackMenuItem, _MenuItem);
  6807  
  6808    function ChaptersTrackMenuItem(player, options) {
  6809      _classCallCheck(this, ChaptersTrackMenuItem);
  6810  
  6811      var track = options['track'];
  6812      var cue = options['cue'];
  6813      var currentTime = player.currentTime();
  6814  
  6815      // Modify options for parent MenuItem class's init.
  6816      options['label'] = cue.text;
  6817      options['selected'] = cue['startTime'] <= currentTime && currentTime < cue['endTime'];
  6818      _MenuItem.call(this, player, options);
  6819  
  6820      this.track = track;
  6821      this.cue = cue;
  6822      track.addEventListener('cuechange', Fn.bind(this, this.update));
  6823    }
  6824  
  6825    /**
  6826     * Handle click on menu item
  6827     *
  6828     * @method handleClick
  6829     */
  6830  
  6831    ChaptersTrackMenuItem.prototype.handleClick = function handleClick() {
  6832      _MenuItem.prototype.handleClick.call(this);
  6833      this.player_.currentTime(this.cue.startTime);
  6834      this.update(this.cue.startTime);
  6835    };
  6836  
  6837    /**
  6838     * Update chapter menu item
  6839     *
  6840     * @method update
  6841     */
  6842  
  6843    ChaptersTrackMenuItem.prototype.update = function update() {
  6844      var cue = this.cue;
  6845      var currentTime = this.player_.currentTime();
  6846  
  6847      // vjs.log(currentTime, cue.startTime);
  6848      this.selected(cue['startTime'] <= currentTime && currentTime < cue['endTime']);
  6849    };
  6850  
  6851    return ChaptersTrackMenuItem;
  6852  })(_menuMenuItemJs2['default']);
  6853  
  6854  _componentJs2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem);
  6855  exports['default'] = ChaptersTrackMenuItem;
  6856  module.exports = exports['default'];
  6857  
  6858  },{"../../component.js":67,"../../menu/menu-item.js":107,"../../utils/fn.js":136}],87:[function(_dereq_,module,exports){
  6859  /**
  6860   * @file descriptions-button.js
  6861   */
  6862  'use strict';
  6863  
  6864  exports.__esModule = true;
  6865  
  6866  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  6867  
  6868  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6869  
  6870  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  6871  
  6872  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  6873  
  6874  var _textTrackButtonJs = _dereq_('./text-track-button.js');
  6875  
  6876  var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs);
  6877  
  6878  var _componentJs = _dereq_('../../component.js');
  6879  
  6880  var _componentJs2 = _interopRequireDefault(_componentJs);
  6881  
  6882  var _utilsFnJs = _dereq_('../../utils/fn.js');
  6883  
  6884  var Fn = _interopRequireWildcard(_utilsFnJs);
  6885  
  6886  /**
  6887   * The button component for toggling and selecting descriptions
  6888   *
  6889   * @param {Object} player  Player object
  6890   * @param {Object=} options Object of option names and values
  6891   * @param {Function=} ready    Ready callback function
  6892   * @extends TextTrackButton
  6893   * @class DescriptionsButton
  6894   */
  6895  
  6896  var DescriptionsButton = (function (_TextTrackButton) {
  6897    _inherits(DescriptionsButton, _TextTrackButton);
  6898  
  6899    function DescriptionsButton(player, options, ready) {
  6900      var _this = this;
  6901  
  6902      _classCallCheck(this, DescriptionsButton);
  6903  
  6904      _TextTrackButton.call(this, player, options, ready);
  6905      this.el_.setAttribute('aria-label', 'Descriptions Menu');
  6906  
  6907      var tracks = player.textTracks();
  6908  
  6909      if (tracks) {
  6910        (function () {
  6911          var changeHandler = Fn.bind(_this, _this.handleTracksChange);
  6912  
  6913          tracks.addEventListener('change', changeHandler);
  6914          _this.on('dispose', function () {
  6915            tracks.removeEventListener('change', changeHandler);
  6916          });
  6917        })();
  6918      }
  6919    }
  6920  
  6921    /**
  6922     * Handle text track change
  6923     *
  6924     * @method handleTracksChange
  6925     */
  6926  
  6927    DescriptionsButton.prototype.handleTracksChange = function handleTracksChange(event) {
  6928      var tracks = this.player().textTracks();
  6929      var disabled = false;
  6930  
  6931      // Check whether a track of a different kind is showing
  6932      for (var i = 0, l = tracks.length; i < l; i++) {
  6933        var track = tracks[i];
  6934        if (track['kind'] !== this.kind_ && track['mode'] === 'showing') {
  6935          disabled = true;
  6936          break;
  6937        }
  6938      }
  6939  
  6940      // If another track is showing, disable this menu button
  6941      if (disabled) {
  6942        this.disable();
  6943      } else {
  6944        this.enable();
  6945      }
  6946    };
  6947  
  6948    /**
  6949     * Allow sub components to stack CSS class names
  6950     *
  6951     * @return {String} The constructed class name
  6952     * @method buildCSSClass
  6953     */
  6954  
  6955    DescriptionsButton.prototype.buildCSSClass = function buildCSSClass() {
  6956      return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  6957    };
  6958  
  6959    return DescriptionsButton;
  6960  })(_textTrackButtonJs2['default']);
  6961  
  6962  DescriptionsButton.prototype.kind_ = 'descriptions';
  6963  DescriptionsButton.prototype.controlText_ = 'Descriptions';
  6964  
  6965  _componentJs2['default'].registerComponent('DescriptionsButton', DescriptionsButton);
  6966  exports['default'] = DescriptionsButton;
  6967  module.exports = exports['default'];
  6968  
  6969  },{"../../component.js":67,"../../utils/fn.js":136,"./text-track-button.js":90}],88:[function(_dereq_,module,exports){
  6970  /**
  6971   * @file off-text-track-menu-item.js
  6972   */
  6973  'use strict';
  6974  
  6975  exports.__esModule = true;
  6976  
  6977  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6978  
  6979  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  6980  
  6981  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  6982  
  6983  var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');
  6984  
  6985  var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);
  6986  
  6987  var _componentJs = _dereq_('../../component.js');
  6988  
  6989  var _componentJs2 = _interopRequireDefault(_componentJs);
  6990  
  6991  /**
  6992   * A special menu item for turning of a specific type of text track
  6993   *
  6994   * @param {Player|Object} player
  6995   * @param {Object=} options
  6996   * @extends TextTrackMenuItem
  6997   * @class OffTextTrackMenuItem
  6998   */
  6999  
  7000  var OffTextTrackMenuItem = (function (_TextTrackMenuItem) {
  7001    _inherits(OffTextTrackMenuItem, _TextTrackMenuItem);
  7002  
  7003    function OffTextTrackMenuItem(player, options) {
  7004      _classCallCheck(this, OffTextTrackMenuItem);
  7005  
  7006      // Create pseudo track info
  7007      // Requires options['kind']
  7008      options['track'] = {
  7009        'kind': options['kind'],
  7010        'player': player,
  7011        'label': options['kind'] + ' off',
  7012        'default': false,
  7013        'mode': 'disabled'
  7014      };
  7015  
  7016      // MenuItem is selectable
  7017      options['selectable'] = true;
  7018  
  7019      _TextTrackMenuItem.call(this, player, options);
  7020      this.selected(true);
  7021    }
  7022  
  7023    /**
  7024     * Handle text track change
  7025     *
  7026     * @param {Object} event Event object
  7027     * @method handleTracksChange
  7028     */
  7029  
  7030    OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
  7031      var tracks = this.player().textTracks();
  7032      var selected = true;
  7033  
  7034      for (var i = 0, l = tracks.length; i < l; i++) {
  7035        var track = tracks[i];
  7036        if (track['kind'] === this.track['kind'] && track['mode'] === 'showing') {
  7037          selected = false;
  7038          break;
  7039        }
  7040      }
  7041  
  7042      this.selected(selected);
  7043    };
  7044  
  7045    return OffTextTrackMenuItem;
  7046  })(_textTrackMenuItemJs2['default']);
  7047  
  7048  _componentJs2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem);
  7049  exports['default'] = OffTextTrackMenuItem;
  7050  module.exports = exports['default'];
  7051  
  7052  },{"../../component.js":67,"./text-track-menu-item.js":91}],89:[function(_dereq_,module,exports){
  7053  /**
  7054   * @file subtitles-button.js
  7055   */
  7056  'use strict';
  7057  
  7058  exports.__esModule = true;
  7059  
  7060  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  7061  
  7062  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  7063  
  7064  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  7065  
  7066  var _textTrackButtonJs = _dereq_('./text-track-button.js');
  7067  
  7068  var _textTrackButtonJs2 = _interopRequireDefault(_textTrackButtonJs);
  7069  
  7070  var _componentJs = _dereq_('../../component.js');
  7071  
  7072  var _componentJs2 = _interopRequireDefault(_componentJs);
  7073  
  7074  /**
  7075   * The button component for toggling and selecting subtitles
  7076   *
  7077   * @param {Object} player  Player object
  7078   * @param {Object=} options Object of option names and values
  7079   * @param {Function=} ready    Ready callback function
  7080   * @extends TextTrackButton
  7081   * @class SubtitlesButton
  7082   */
  7083  
  7084  var SubtitlesButton = (function (_TextTrackButton) {
  7085    _inherits(SubtitlesButton, _TextTrackButton);
  7086  
  7087    function SubtitlesButton(player, options, ready) {
  7088      _classCallCheck(this, SubtitlesButton);
  7089  
  7090      _TextTrackButton.call(this, player, options, ready);
  7091      this.el_.setAttribute('aria-label', 'Subtitles Menu');
  7092    }
  7093  
  7094    /**
  7095     * Allow sub components to stack CSS class names
  7096     *
  7097     * @return {String} The constructed class name
  7098     * @method buildCSSClass
  7099     */
  7100  
  7101    SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() {
  7102      return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  7103    };
  7104  
  7105    return SubtitlesButton;
  7106  })(_textTrackButtonJs2['default']);
  7107  
  7108  SubtitlesButton.prototype.kind_ = 'subtitles';
  7109  SubtitlesButton.prototype.controlText_ = 'Subtitles';
  7110  
  7111  _componentJs2['default'].registerComponent('SubtitlesButton', SubtitlesButton);
  7112  exports['default'] = SubtitlesButton;
  7113  module.exports = exports['default'];
  7114  
  7115  },{"../../component.js":67,"./text-track-button.js":90}],90:[function(_dereq_,module,exports){
  7116  /**
  7117   * @file text-track-button.js
  7118   */
  7119  'use strict';
  7120  
  7121  exports.__esModule = true;
  7122  
  7123  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  7124  
  7125  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  7126  
  7127  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  7128  
  7129  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  7130  
  7131  var _menuMenuButtonJs = _dereq_('../../menu/menu-button.js');
  7132  
  7133  var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs);
  7134  
  7135  var _componentJs = _dereq_('../../component.js');
  7136  
  7137  var _componentJs2 = _interopRequireDefault(_componentJs);
  7138  
  7139  var _utilsFnJs = _dereq_('../../utils/fn.js');
  7140  
  7141  var Fn = _interopRequireWildcard(_utilsFnJs);
  7142  
  7143  var _textTrackMenuItemJs = _dereq_('./text-track-menu-item.js');
  7144  
  7145  var _textTrackMenuItemJs2 = _interopRequireDefault(_textTrackMenuItemJs);
  7146  
  7147  var _offTextTrackMenuItemJs = _dereq_('./off-text-track-menu-item.js');
  7148  
  7149  var _offTextTrackMenuItemJs2 = _interopRequireDefault(_offTextTrackMenuItemJs);
  7150  
  7151  /**
  7152   * The base class for buttons that toggle specific text track types (e.g. subtitles)
  7153   *
  7154   * @param {Player|Object} player
  7155   * @param {Object=} options
  7156   * @extends MenuButton
  7157   * @class TextTrackButton
  7158   */
  7159  
  7160  var TextTrackButton = (function (_MenuButton) {
  7161    _inherits(TextTrackButton, _MenuButton);
  7162  
  7163    function TextTrackButton(player, options) {
  7164      _classCallCheck(this, TextTrackButton);
  7165  
  7166      _MenuButton.call(this, player, options);
  7167  
  7168      var tracks = this.player_.textTracks();
  7169  
  7170      if (this.items.length <= 1) {
  7171        this.hide();
  7172      }
  7173  
  7174      if (!tracks) {
  7175        return;
  7176      }
  7177  
  7178      var updateHandler = Fn.bind(this, this.update);
  7179      tracks.addEventListener('removetrack', updateHandler);
  7180      tracks.addEventListener('addtrack', updateHandler);
  7181  
  7182      this.player_.on('dispose', function () {
  7183        tracks.removeEventListener('removetrack', updateHandler);
  7184        tracks.removeEventListener('addtrack', updateHandler);
  7185      });
  7186    }
  7187  
  7188    // Create a menu item for each text track
  7189  
  7190    TextTrackButton.prototype.createItems = function createItems() {
  7191      var items = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
  7192  
  7193      // Add an OFF menu item to turn all tracks off
  7194      items.push(new _offTextTrackMenuItemJs2['default'](this.player_, { 'kind': this.kind_ }));
  7195  
  7196      var tracks = this.player_.textTracks();
  7197  
  7198      if (!tracks) {
  7199        return items;
  7200      }
  7201  
  7202      for (var i = 0; i < tracks.length; i++) {
  7203        var track = tracks[i];
  7204  
  7205        // only add tracks that are of the appropriate kind and have a label
  7206        if (track['kind'] === this.kind_) {
  7207          items.push(new _textTrackMenuItemJs2['default'](this.player_, {
  7208            // MenuItem is selectable
  7209            'selectable': true,
  7210            'track': track
  7211          }));
  7212        }
  7213      }
  7214  
  7215      return items;
  7216    };
  7217  
  7218    return TextTrackButton;
  7219  })(_menuMenuButtonJs2['default']);
  7220  
  7221  _componentJs2['default'].registerComponent('TextTrackButton', TextTrackButton);
  7222  exports['default'] = TextTrackButton;
  7223  module.exports = exports['default'];
  7224  
  7225  },{"../../component.js":67,"../../menu/menu-button.js":106,"../../utils/fn.js":136,"./off-text-track-menu-item.js":88,"./text-track-menu-item.js":91}],91:[function(_dereq_,module,exports){
  7226  /**
  7227   * @file text-track-menu-item.js
  7228   */
  7229  'use strict';
  7230  
  7231  exports.__esModule = true;
  7232  
  7233  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  7234  
  7235  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  7236  
  7237  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  7238  
  7239  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  7240  
  7241  var _menuMenuItemJs = _dereq_('../../menu/menu-item.js');
  7242  
  7243  var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);
  7244  
  7245  var _componentJs = _dereq_('../../component.js');
  7246  
  7247  var _componentJs2 = _interopRequireDefault(_componentJs);
  7248  
  7249  var _utilsFnJs = _dereq_('../../utils/fn.js');
  7250  
  7251  var Fn = _interopRequireWildcard(_utilsFnJs);
  7252  
  7253  var _globalWindow = _dereq_('global/window');
  7254  
  7255  var _globalWindow2 = _interopRequireDefault(_globalWindow);
  7256  
  7257  var _globalDocument = _dereq_('global/document');
  7258  
  7259  var _globalDocument2 = _interopRequireDefault(_globalDocument);
  7260  
  7261  /**
  7262   * The specific menu item type for selecting a language within a text track kind
  7263   *
  7264   * @param {Player|Object} player
  7265   * @param {Object=} options
  7266   * @extends MenuItem
  7267   * @class TextTrackMenuItem
  7268   */
  7269  
  7270  var TextTrackMenuItem = (function (_MenuItem) {
  7271    _inherits(TextTrackMenuItem, _MenuItem);
  7272  
  7273    function TextTrackMenuItem(player, options) {
  7274      var _this = this;
  7275  
  7276      _classCallCheck(this, TextTrackMenuItem);
  7277  
  7278      var track = options['track'];
  7279      var tracks = player.textTracks();
  7280  
  7281      // Modify options for parent MenuItem class's init.
  7282      options['label'] = track['label'] || track['language'] || 'Unknown';
  7283      options['selected'] = track['default'] || track['mode'] === 'showing';
  7284  
  7285      _MenuItem.call(this, player, options);
  7286  
  7287      this.track = track;
  7288  
  7289      if (tracks) {
  7290        (function () {
  7291          var changeHandler = Fn.bind(_this, _this.handleTracksChange);
  7292  
  7293          tracks.addEventListener('change', changeHandler);
  7294          _this.on('dispose', function () {
  7295            tracks.removeEventListener('change', changeHandler);
  7296          });
  7297        })();
  7298      }
  7299  
  7300      // iOS7 doesn't dispatch change events to TextTrackLists when an
  7301      // associated track's mode changes. Without something like
  7302      // Object.observe() (also not present on iOS7), it's not
  7303      // possible to detect changes to the mode attribute and polyfill
  7304      // the change event. As a poor substitute, we manually dispatch
  7305      // change events whenever the controls modify the mode.
  7306      if (tracks && tracks.onchange === undefined) {
  7307        (function () {
  7308          var event = undefined;
  7309  
  7310          _this.on(['tap', 'click'], function () {
  7311            if (typeof _globalWindow2['default'].Event !== 'object') {
  7312              // Android 2.3 throws an Illegal Constructor error for window.Event
  7313              try {
  7314                event = new _globalWindow2['default'].Event('change');
  7315              } catch (err) {}
  7316            }
  7317  
  7318            if (!event) {
  7319              event = _globalDocument2['default'].createEvent('Event');
  7320              event.initEvent('change', true, true);
  7321            }
  7322  
  7323            tracks.dispatchEvent(event);
  7324          });
  7325        })();
  7326      }
  7327    }
  7328  
  7329    /**
  7330     * Handle click on text track
  7331     *
  7332     * @method handleClick
  7333     */
  7334  
  7335    TextTrackMenuItem.prototype.handleClick = function handleClick(event) {
  7336      var kind = this.track['kind'];
  7337      var tracks = this.player_.textTracks();
  7338  
  7339      _MenuItem.prototype.handleClick.call(this, event);
  7340  
  7341      if (!tracks) return;
  7342  
  7343      for (var i = 0; i < tracks.length; i++) {
  7344        var track = tracks[i];
  7345  
  7346        if (track['kind'] !== kind) {
  7347          continue;
  7348        }
  7349  
  7350        if (track === this.track) {
  7351          track['mode'] = 'showing';
  7352        } else {
  7353          track['mode'] = 'disabled';
  7354        }
  7355      }
  7356    };
  7357  
  7358    /**
  7359     * Handle text track change
  7360     *
  7361     * @method handleTracksChange
  7362     */
  7363  
  7364    TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
  7365      this.selected(this.track['mode'] === 'showing');
  7366    };
  7367  
  7368    return TextTrackMenuItem;
  7369  })(_menuMenuItemJs2['default']);
  7370  
  7371  _componentJs2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem);
  7372  exports['default'] = TextTrackMenuItem;
  7373  module.exports = exports['default'];
  7374  
  7375  },{"../../component.js":67,"../../menu/menu-item.js":107,"../../utils/fn.js":136,"global/document":1,"global/window":2}],92:[function(_dereq_,module,exports){
  7376  /**
  7377   * @file current-time-display.js
  7378   */
  7379  'use strict';
  7380  
  7381  exports.__esModule = true;
  7382  
  7383  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  7384  
  7385  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  7386  
  7387  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  7388  
  7389  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  7390  
  7391  var _componentJs = _dereq_('../../component.js');
  7392  
  7393  var _componentJs2 = _interopRequireDefault(_componentJs);
  7394  
  7395  var _utilsDomJs = _dereq_('../../utils/dom.js');
  7396  
  7397  var Dom = _interopRequireWildcard(_utilsDomJs);
  7398  
  7399  var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
  7400  
  7401  var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
  7402  
  7403  /**
  7404   * Displays the current time
  7405   *
  7406   * @param {Player|Object} player
  7407   * @param {Object=} options
  7408   * @extends Component
  7409   * @class CurrentTimeDisplay
  7410   */
  7411  
  7412  var CurrentTimeDisplay = (function (_Component) {
  7413    _inherits(CurrentTimeDisplay, _Component);
  7414  
  7415    function CurrentTimeDisplay(player, options) {
  7416      _classCallCheck(this, CurrentTimeDisplay);
  7417  
  7418      _Component.call(this, player, options);
  7419  
  7420      this.on(player, 'timeupdate', this.updateContent);
  7421    }
  7422  
  7423    /**
  7424     * Create the component's DOM element
  7425     *
  7426     * @return {Element}
  7427     * @method createEl
  7428     */
  7429  
  7430    CurrentTimeDisplay.prototype.createEl = function createEl() {
  7431      var el = _Component.prototype.createEl.call(this, 'div', {
  7432        className: 'vjs-current-time vjs-time-control vjs-control'
  7433      });
  7434  
  7435      this.contentEl_ = Dom.createEl('div', {
  7436        className: 'vjs-current-time-display',
  7437        // label the current time for screen reader users
  7438        innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00'
  7439      }, {
  7440        // tell screen readers not to automatically read the time as it changes
  7441        'aria-live': 'off'
  7442      });
  7443  
  7444      el.appendChild(this.contentEl_);
  7445      return el;
  7446    };
  7447  
  7448    /**
  7449     * Update current time display
  7450     *
  7451     * @method updateContent
  7452     */
  7453  
  7454    CurrentTimeDisplay.prototype.updateContent = function updateContent() {
  7455      // Allows for smooth scrubbing, when player can't keep up.
  7456      var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
  7457      var localizedText = this.localize('Current Time');
  7458      var formattedTime = _utilsFormatTimeJs2['default'](time, this.player_.duration());
  7459      if (formattedTime !== this.formattedTime_) {
  7460        this.formattedTime_ = formattedTime;
  7461        this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
  7462      }
  7463    };
  7464  
  7465    return CurrentTimeDisplay;
  7466  })(_componentJs2['default']);
  7467  
  7468  _componentJs2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
  7469  exports['default'] = CurrentTimeDisplay;
  7470  module.exports = exports['default'];
  7471  
  7472  },{"../../component.js":67,"../../utils/dom.js":134,"../../utils/format-time.js":137}],93:[function(_dereq_,module,exports){
  7473  /**
  7474   * @file duration-display.js
  7475   */
  7476  'use strict';
  7477  
  7478  exports.__esModule = true;
  7479  
  7480  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  7481  
  7482  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  7483  
  7484  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  7485  
  7486  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  7487  
  7488  var _componentJs = _dereq_('../../component.js');
  7489  
  7490  var _componentJs2 = _interopRequireDefault(_componentJs);
  7491  
  7492  var _utilsDomJs = _dereq_('../../utils/dom.js');
  7493  
  7494  var Dom = _interopRequireWildcard(_utilsDomJs);
  7495  
  7496  var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
  7497  
  7498  var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
  7499  
  7500  /**
  7501   * Displays the duration
  7502   *
  7503   * @param {Player|Object} player
  7504   * @param {Object=} options
  7505   * @extends Component
  7506   * @class DurationDisplay
  7507   */
  7508  
  7509  var DurationDisplay = (function (_Component) {
  7510    _inherits(DurationDisplay, _Component);
  7511  
  7512    function DurationDisplay(player, options) {
  7513      _classCallCheck(this, DurationDisplay);
  7514  
  7515      _Component.call(this, player, options);
  7516  
  7517      // this might need to be changed to 'durationchange' instead of 'timeupdate' eventually,
  7518      // however the durationchange event fires before this.player_.duration() is set,
  7519      // so the value cannot be written out using this method.
  7520      // Once the order of durationchange and this.player_.duration() being set is figured out,
  7521      // this can be updated.
  7522      this.on(player, 'timeupdate', this.updateContent);
  7523      this.on(player, 'loadedmetadata', this.updateContent);
  7524    }
  7525  
  7526    /**
  7527     * Create the component's DOM element
  7528     *
  7529     * @return {Element}
  7530     * @method createEl
  7531     */
  7532  
  7533    DurationDisplay.prototype.createEl = function createEl() {
  7534      var el = _Component.prototype.createEl.call(this, 'div', {
  7535        className: 'vjs-duration vjs-time-control vjs-control'
  7536      });
  7537  
  7538      this.contentEl_ = Dom.createEl('div', {
  7539        className: 'vjs-duration-display',
  7540        // label the duration time for screen reader users
  7541        innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00'
  7542      }, {
  7543        // tell screen readers not to automatically read the time as it changes
  7544        'aria-live': 'off'
  7545      });
  7546  
  7547      el.appendChild(this.contentEl_);
  7548      return el;
  7549    };
  7550  
  7551    /**
  7552     * Update duration time display
  7553     *
  7554     * @method updateContent
  7555     */
  7556  
  7557    DurationDisplay.prototype.updateContent = function updateContent() {
  7558      var duration = this.player_.duration();
  7559      if (duration && this.duration_ !== duration) {
  7560        this.duration_ = duration;
  7561        var localizedText = this.localize('Duration Time');
  7562        var formattedTime = _utilsFormatTimeJs2['default'](duration);
  7563        this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime; // label the duration time for screen reader users
  7564      }
  7565    };
  7566  
  7567    return DurationDisplay;
  7568  })(_componentJs2['default']);
  7569  
  7570  _componentJs2['default'].registerComponent('DurationDisplay', DurationDisplay);
  7571  exports['default'] = DurationDisplay;
  7572  module.exports = exports['default'];
  7573  
  7574  },{"../../component.js":67,"../../utils/dom.js":134,"../../utils/format-time.js":137}],94:[function(_dereq_,module,exports){
  7575  /**
  7576   * @file remaining-time-display.js
  7577   */
  7578  'use strict';
  7579  
  7580  exports.__esModule = true;
  7581  
  7582  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  7583  
  7584  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  7585  
  7586  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  7587  
  7588  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  7589  
  7590  var _componentJs = _dereq_('../../component.js');
  7591  
  7592  var _componentJs2 = _interopRequireDefault(_componentJs);
  7593  
  7594  var _utilsDomJs = _dereq_('../../utils/dom.js');
  7595  
  7596  var Dom = _interopRequireWildcard(_utilsDomJs);
  7597  
  7598  var _utilsFormatTimeJs = _dereq_('../../utils/format-time.js');
  7599  
  7600  var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
  7601  
  7602  /**
  7603   * Displays the time left in the video
  7604   *
  7605   * @param {Player|Object} player
  7606   * @param {Object=} options
  7607   * @extends Component
  7608   * @class RemainingTimeDisplay
  7609   */
  7610  
  7611  var RemainingTimeDisplay = (function (_Component) {
  7612    _inherits(RemainingTimeDisplay, _Component);
  7613  
  7614    function RemainingTimeDisplay(player, options) {
  7615      _classCallCheck(this, RemainingTimeDisplay);
  7616  
  7617      _Component.call(this, player, options);
  7618  
  7619      this.on(player, 'timeupdate', this.updateContent);
  7620    }
  7621  
  7622    /**
  7623     * Create the component's DOM element
  7624     *
  7625     * @return {Element}
  7626     * @method createEl
  7627     */
  7628  
  7629    RemainingTimeDisplay.prototype.createEl = function createEl() {
  7630      var el = _Component.prototype.createEl.call(this, 'div', {
  7631        className: 'vjs-remaining-time vjs-time-control vjs-control'
  7632      });
  7633  
  7634      this.contentEl_ = Dom.createEl('div', {
  7635        className: 'vjs-remaining-time-display',
  7636        // label the remaining time for screen reader users
  7637        innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00'
  7638      }, {
  7639        // tell screen readers not to automatically read the time as it changes
  7640        'aria-live': 'off'
  7641      });
  7642  
  7643      el.appendChild(this.contentEl_);
  7644      return el;
  7645    };
  7646  
  7647    /**
  7648     * Update remaining time display
  7649     *
  7650     * @method updateContent
  7651     */
  7652  
  7653    RemainingTimeDisplay.prototype.updateContent = function updateContent() {
  7654      if (this.player_.duration()) {
  7655        var localizedText = this.localize('Remaining Time');
  7656        var formattedTime = _utilsFormatTimeJs2['default'](this.player_.remainingTime());
  7657        if (formattedTime !== this.formattedTime_) {
  7658          this.formattedTime_ = formattedTime;
  7659          this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime;
  7660        }
  7661      }
  7662  
  7663      // Allows for smooth scrubbing, when player can't keep up.
  7664      // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
  7665      // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration());
  7666    };
  7667  
  7668    return RemainingTimeDisplay;
  7669  })(_componentJs2['default']);
  7670  
  7671  _componentJs2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
  7672  exports['default'] = RemainingTimeDisplay;
  7673  module.exports = exports['default'];
  7674  
  7675  },{"../../component.js":67,"../../utils/dom.js":134,"../../utils/format-time.js":137}],95:[function(_dereq_,module,exports){
  7676  /**
  7677   * @file time-divider.js
  7678   */
  7679  'use strict';
  7680  
  7681  exports.__esModule = true;
  7682  
  7683  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  7684  
  7685  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  7686  
  7687  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  7688  
  7689  var _componentJs = _dereq_('../../component.js');
  7690  
  7691  var _componentJs2 = _interopRequireDefault(_componentJs);
  7692  
  7693  /**
  7694   * The separator between the current time and duration.
  7695   * Can be hidden if it's not needed in the design.
  7696   *
  7697   * @param {Player|Object} player
  7698   * @param {Object=} options
  7699   * @extends Component
  7700   * @class TimeDivider
  7701   */
  7702  
  7703  var TimeDivider = (function (_Component) {
  7704    _inherits(TimeDivider, _Component);
  7705  
  7706    function TimeDivider() {
  7707      _classCallCheck(this, TimeDivider);
  7708  
  7709      _Component.apply(this, arguments);
  7710    }
  7711  
  7712    /**
  7713     * Create the component's DOM element
  7714     *
  7715     * @return {Element}
  7716     * @method createEl
  7717     */
  7718  
  7719    TimeDivider.prototype.createEl = function createEl() {
  7720      return _Component.prototype.createEl.call(this, 'div', {
  7721        className: 'vjs-time-control vjs-time-divider',
  7722        innerHTML: '<div><span>/</span></div>'
  7723      });
  7724    };
  7725  
  7726    return TimeDivider;
  7727  })(_componentJs2['default']);
  7728  
  7729  _componentJs2['default'].registerComponent('TimeDivider', TimeDivider);
  7730  exports['default'] = TimeDivider;
  7731  module.exports = exports['default'];
  7732  
  7733  },{"../../component.js":67}],96:[function(_dereq_,module,exports){
  7734  /**
  7735   * @file volume-bar.js
  7736   */
  7737  'use strict';
  7738  
  7739  exports.__esModule = true;
  7740  
  7741  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  7742  
  7743  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  7744  
  7745  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  7746  
  7747  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  7748  
  7749  var _sliderSliderJs = _dereq_('../../slider/slider.js');
  7750  
  7751  var _sliderSliderJs2 = _interopRequireDefault(_sliderSliderJs);
  7752  
  7753  var _componentJs = _dereq_('../../component.js');
  7754  
  7755  var _componentJs2 = _interopRequireDefault(_componentJs);
  7756  
  7757  var _utilsFnJs = _dereq_('../../utils/fn.js');
  7758  
  7759  var Fn = _interopRequireWildcard(_utilsFnJs);
  7760  
  7761  // Required children
  7762  
  7763  var _volumeLevelJs = _dereq_('./volume-level.js');
  7764  
  7765  var _volumeLevelJs2 = _interopRequireDefault(_volumeLevelJs);
  7766  
  7767  /**
  7768   * The bar that contains the volume level and can be clicked on to adjust the level
  7769   *
  7770   * @param {Player|Object} player
  7771   * @param {Object=} options
  7772   * @extends Slider
  7773   * @class VolumeBar
  7774   */
  7775  
  7776  var VolumeBar = (function (_Slider) {
  7777    _inherits(VolumeBar, _Slider);
  7778  
  7779    function VolumeBar(player, options) {
  7780      _classCallCheck(this, VolumeBar);
  7781  
  7782      _Slider.call(this, player, options);
  7783      this.on(player, 'volumechange', this.updateARIAAttributes);
  7784      player.ready(Fn.bind(this, this.updateARIAAttributes));
  7785    }
  7786  
  7787    /**
  7788     * Create the component's DOM element
  7789     *
  7790     * @return {Element}
  7791     * @method createEl
  7792     */
  7793  
  7794    VolumeBar.prototype.createEl = function createEl() {
  7795      return _Slider.prototype.createEl.call(this, 'div', {
  7796        className: 'vjs-volume-bar vjs-slider-bar'
  7797      }, {
  7798        'aria-label': 'volume level'
  7799      });
  7800    };
  7801  
  7802    /**
  7803     * Handle mouse move on volume bar
  7804     *
  7805     * @method handleMouseMove
  7806     */
  7807  
  7808    VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) {
  7809      this.checkMuted();
  7810      this.player_.volume(this.calculateDistance(event));
  7811    };
  7812  
  7813    VolumeBar.prototype.checkMuted = function checkMuted() {
  7814      if (this.player_.muted()) {
  7815        this.player_.muted(false);
  7816      }
  7817    };
  7818  
  7819    /**
  7820     * Get percent of volume level
  7821     *
  7822     * @retun {Number} Volume level percent
  7823     * @method getPercent
  7824     */
  7825  
  7826    VolumeBar.prototype.getPercent = function getPercent() {
  7827      if (this.player_.muted()) {
  7828        return 0;
  7829      } else {
  7830        return this.player_.volume();
  7831      }
  7832    };
  7833  
  7834    /**
  7835     * Increase volume level for keyboard users
  7836     *
  7837     * @method stepForward
  7838     */
  7839  
  7840    VolumeBar.prototype.stepForward = function stepForward() {
  7841      this.checkMuted();
  7842      this.player_.volume(this.player_.volume() + 0.1);
  7843    };
  7844  
  7845    /**
  7846     * Decrease volume level for keyboard users
  7847     *
  7848     * @method stepBack
  7849     */
  7850  
  7851    VolumeBar.prototype.stepBack = function stepBack() {
  7852      this.checkMuted();
  7853      this.player_.volume(this.player_.volume() - 0.1);
  7854    };
  7855  
  7856    /**
  7857     * Update ARIA accessibility attributes
  7858     *
  7859     * @method updateARIAAttributes
  7860     */
  7861  
  7862    VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes() {
  7863      // Current value of volume bar as a percentage
  7864      var volume = (this.player_.volume() * 100).toFixed(2);
  7865      this.el_.setAttribute('aria-valuenow', volume);
  7866      this.el_.setAttribute('aria-valuetext', volume + '%');
  7867    };
  7868  
  7869    return VolumeBar;
  7870  })(_sliderSliderJs2['default']);
  7871  
  7872  VolumeBar.prototype.options_ = {
  7873    children: ['volumeLevel'],
  7874    'barName': 'volumeLevel'
  7875  };
  7876  
  7877  VolumeBar.prototype.playerEvent = 'volumechange';
  7878  
  7879  _componentJs2['default'].registerComponent('VolumeBar', VolumeBar);
  7880  exports['default'] = VolumeBar;
  7881  module.exports = exports['default'];
  7882  
  7883  },{"../../component.js":67,"../../slider/slider.js":116,"../../utils/fn.js":136,"./volume-level.js":98}],97:[function(_dereq_,module,exports){
  7884  /**
  7885   * @file volume-control.js
  7886   */
  7887  'use strict';
  7888  
  7889  exports.__esModule = true;
  7890  
  7891  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  7892  
  7893  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  7894  
  7895  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  7896  
  7897  var _componentJs = _dereq_('../../component.js');
  7898  
  7899  var _componentJs2 = _interopRequireDefault(_componentJs);
  7900  
  7901  // Required children
  7902  
  7903  var _volumeBarJs = _dereq_('./volume-bar.js');
  7904  
  7905  var _volumeBarJs2 = _interopRequireDefault(_volumeBarJs);
  7906  
  7907  /**
  7908   * The component for controlling the volume level
  7909   *
  7910   * @param {Player|Object} player
  7911   * @param {Object=} options
  7912   * @extends Component
  7913   * @class VolumeControl
  7914   */
  7915  
  7916  var VolumeControl = (function (_Component) {
  7917    _inherits(VolumeControl, _Component);
  7918  
  7919    function VolumeControl(player, options) {
  7920      _classCallCheck(this, VolumeControl);
  7921  
  7922      _Component.call(this, player, options);
  7923  
  7924      // hide volume controls when they're not supported by the current tech
  7925      if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
  7926        this.addClass('vjs-hidden');
  7927      }
  7928      this.on(player, 'loadstart', function () {
  7929        if (player.tech_['featuresVolumeControl'] === false) {
  7930          this.addClass('vjs-hidden');
  7931        } else {
  7932          this.removeClass('vjs-hidden');
  7933        }
  7934      });
  7935    }
  7936  
  7937    /**
  7938     * Create the component's DOM element
  7939     *
  7940     * @return {Element}
  7941     * @method createEl
  7942     */
  7943  
  7944    VolumeControl.prototype.createEl = function createEl() {
  7945      return _Component.prototype.createEl.call(this, 'div', {
  7946        className: 'vjs-volume-control vjs-control'
  7947      });
  7948    };
  7949  
  7950    return VolumeControl;
  7951  })(_componentJs2['default']);
  7952  
  7953  VolumeControl.prototype.options_ = {
  7954    children: ['volumeBar']
  7955  };
  7956  
  7957  _componentJs2['default'].registerComponent('VolumeControl', VolumeControl);
  7958  exports['default'] = VolumeControl;
  7959  module.exports = exports['default'];
  7960  
  7961  },{"../../component.js":67,"./volume-bar.js":96}],98:[function(_dereq_,module,exports){
  7962  /**
  7963   * @file volume-level.js
  7964   */
  7965  'use strict';
  7966  
  7967  exports.__esModule = true;
  7968  
  7969  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  7970  
  7971  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  7972  
  7973  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  7974  
  7975  var _componentJs = _dereq_('../../component.js');
  7976  
  7977  var _componentJs2 = _interopRequireDefault(_componentJs);
  7978  
  7979  /**
  7980   * Shows volume level
  7981   *
  7982   * @param {Player|Object} player
  7983   * @param {Object=} options
  7984   * @extends Component
  7985   * @class VolumeLevel
  7986   */
  7987  
  7988  var VolumeLevel = (function (_Component) {
  7989    _inherits(VolumeLevel, _Component);
  7990  
  7991    function VolumeLevel() {
  7992      _classCallCheck(this, VolumeLevel);
  7993  
  7994      _Component.apply(this, arguments);
  7995    }
  7996  
  7997    /**
  7998     * Create the component's DOM element
  7999     *
  8000     * @return {Element}
  8001     * @method createEl
  8002     */
  8003  
  8004    VolumeLevel.prototype.createEl = function createEl() {
  8005      return _Component.prototype.createEl.call(this, 'div', {
  8006        className: 'vjs-volume-level',
  8007        innerHTML: '<span class="vjs-control-text"></span>'
  8008      });
  8009    };
  8010  
  8011    return VolumeLevel;
  8012  })(_componentJs2['default']);
  8013  
  8014  _componentJs2['default'].registerComponent('VolumeLevel', VolumeLevel);
  8015  exports['default'] = VolumeLevel;
  8016  module.exports = exports['default'];
  8017  
  8018  },{"../../component.js":67}],99:[function(_dereq_,module,exports){
  8019  /**
  8020   * @file volume-menu-button.js
  8021   */
  8022  'use strict';
  8023  
  8024  exports.__esModule = true;
  8025  
  8026  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  8027  
  8028  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  8029  
  8030  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  8031  
  8032  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  8033  
  8034  var _utilsFnJs = _dereq_('../utils/fn.js');
  8035  
  8036  var Fn = _interopRequireWildcard(_utilsFnJs);
  8037  
  8038  var _componentJs = _dereq_('../component.js');
  8039  
  8040  var _componentJs2 = _interopRequireDefault(_componentJs);
  8041  
  8042  var _popupPopupJs = _dereq_('../popup/popup.js');
  8043  
  8044  var _popupPopupJs2 = _interopRequireDefault(_popupPopupJs);
  8045  
  8046  var _popupPopupButtonJs = _dereq_('../popup/popup-button.js');
  8047  
  8048  var _popupPopupButtonJs2 = _interopRequireDefault(_popupPopupButtonJs);
  8049  
  8050  var _muteToggleJs = _dereq_('./mute-toggle.js');
  8051  
  8052  var _muteToggleJs2 = _interopRequireDefault(_muteToggleJs);
  8053  
  8054  var _volumeControlVolumeBarJs = _dereq_('./volume-control/volume-bar.js');
  8055  
  8056  var _volumeControlVolumeBarJs2 = _interopRequireDefault(_volumeControlVolumeBarJs);
  8057  
  8058  /**
  8059   * Button for volume popup
  8060   *
  8061   * @param {Player|Object} player
  8062   * @param {Object=} options
  8063   * @extends PopupButton
  8064   * @class VolumeMenuButton
  8065   */
  8066  
  8067  var VolumeMenuButton = (function (_PopupButton) {
  8068    _inherits(VolumeMenuButton, _PopupButton);
  8069  
  8070    function VolumeMenuButton(player) {
  8071      var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
  8072  
  8073      _classCallCheck(this, VolumeMenuButton);
  8074  
  8075      // Default to inline
  8076      if (options.inline === undefined) {
  8077        options.inline = true;
  8078      }
  8079  
  8080      // If the vertical option isn't passed at all, default to true.
  8081      if (options.vertical === undefined) {
  8082        // If an inline volumeMenuButton is used, we should default to using
  8083        // a horizontal slider for obvious reasons.
  8084        if (options.inline) {
  8085          options.vertical = false;
  8086        } else {
  8087          options.vertical = true;
  8088        }
  8089      }
  8090  
  8091      // The vertical option needs to be set on the volumeBar as well,
  8092      // since that will need to be passed along to the VolumeBar constructor
  8093      options.volumeBar = options.volumeBar || {};
  8094      options.volumeBar.vertical = !!options.vertical;
  8095  
  8096      _PopupButton.call(this, player, options);
  8097  
  8098      // Same listeners as MuteToggle
  8099      this.on(player, 'volumechange', this.volumeUpdate);
  8100      this.on(player, 'loadstart', this.volumeUpdate);
  8101  
  8102      // hide mute toggle if the current tech doesn't support volume control
  8103      function updateVisibility() {
  8104        if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
  8105          this.addClass('vjs-hidden');
  8106        } else {
  8107          this.removeClass('vjs-hidden');
  8108        }
  8109      }
  8110  
  8111      updateVisibility.call(this);
  8112      this.on(player, 'loadstart', updateVisibility);
  8113  
  8114      this.on(this.volumeBar, ['slideractive', 'focus'], function () {
  8115        this.addClass('vjs-slider-active');
  8116      });
  8117  
  8118      this.on(this.volumeBar, ['sliderinactive', 'blur'], function () {
  8119        this.removeClass('vjs-slider-active');
  8120      });
  8121  
  8122      this.on(this.volumeBar, ['focus'], function () {
  8123        this.addClass('vjs-lock-showing');
  8124      });
  8125  
  8126      this.on(this.volumeBar, ['blur'], function () {
  8127        this.removeClass('vjs-lock-showing');
  8128      });
  8129    }
  8130  
  8131    /**
  8132     * Allow sub components to stack CSS class names
  8133     *
  8134     * @return {String} The constructed class name
  8135     * @method buildCSSClass
  8136     */
  8137  
  8138    VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() {
  8139      var orientationClass = '';
  8140      if (!!this.options_.vertical) {
  8141        orientationClass = 'vjs-volume-menu-button-vertical';
  8142      } else {
  8143        orientationClass = 'vjs-volume-menu-button-horizontal';
  8144      }
  8145  
  8146      return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass;
  8147    };
  8148  
  8149    /**
  8150     * Allow sub components to stack CSS class names
  8151     *
  8152     * @return {Popup} The volume popup button
  8153     * @method createPopup
  8154     */
  8155  
  8156    VolumeMenuButton.prototype.createPopup = function createPopup() {
  8157      var popup = new _popupPopupJs2['default'](this.player_, {
  8158        contentElType: 'div'
  8159      });
  8160  
  8161      var vb = new _volumeControlVolumeBarJs2['default'](this.player_, this.options_.volumeBar);
  8162  
  8163      popup.addChild(vb);
  8164  
  8165      this.menuContent = popup;
  8166      this.volumeBar = vb;
  8167  
  8168      this.attachVolumeBarEvents();
  8169  
  8170      return popup;
  8171    };
  8172  
  8173    /**
  8174     * Handle click on volume popup and calls super
  8175     *
  8176     * @method handleClick
  8177     */
  8178  
  8179    VolumeMenuButton.prototype.handleClick = function handleClick() {
  8180      _muteToggleJs2['default'].prototype.handleClick.call(this);
  8181      _PopupButton.prototype.handleClick.call(this);
  8182    };
  8183  
  8184    VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() {
  8185      this.menuContent.on(['mousedown', 'touchdown'], Fn.bind(this, this.handleMouseDown));
  8186    };
  8187  
  8188    VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) {
  8189      this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
  8190      this.on(this.el_.ownerDocument, ['mouseup', 'touchend'], this.handleMouseUp);
  8191    };
  8192  
  8193    VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) {
  8194      this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
  8195    };
  8196  
  8197    return VolumeMenuButton;
  8198  })(_popupPopupButtonJs2['default']);
  8199  
  8200  VolumeMenuButton.prototype.volumeUpdate = _muteToggleJs2['default'].prototype.update;
  8201  VolumeMenuButton.prototype.controlText_ = 'Mute';
  8202  
  8203  _componentJs2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton);
  8204  exports['default'] = VolumeMenuButton;
  8205  module.exports = exports['default'];
  8206  
  8207  },{"../component.js":67,"../popup/popup-button.js":112,"../popup/popup.js":113,"../utils/fn.js":136,"./mute-toggle.js":71,"./volume-control/volume-bar.js":96}],100:[function(_dereq_,module,exports){
  8208  /**
  8209   * @file error-display.js
  8210   */
  8211  'use strict';
  8212  
  8213  exports.__esModule = true;
  8214  
  8215  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  8216  
  8217  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  8218  
  8219  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  8220  
  8221  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  8222  
  8223  var _component = _dereq_('./component');
  8224  
  8225  var _component2 = _interopRequireDefault(_component);
  8226  
  8227  var _modalDialog = _dereq_('./modal-dialog');
  8228  
  8229  var _modalDialog2 = _interopRequireDefault(_modalDialog);
  8230  
  8231  var _utilsDom = _dereq_('./utils/dom');
  8232  
  8233  var Dom = _interopRequireWildcard(_utilsDom);
  8234  
  8235  var _utilsMergeOptions = _dereq_('./utils/merge-options');
  8236  
  8237  var _utilsMergeOptions2 = _interopRequireDefault(_utilsMergeOptions);
  8238  
  8239  /**
  8240   * Display that an error has occurred making the video unplayable.
  8241   *
  8242   * @extends ModalDialog
  8243   * @class ErrorDisplay
  8244   */
  8245  
  8246  var ErrorDisplay = (function (_ModalDialog) {
  8247    _inherits(ErrorDisplay, _ModalDialog);
  8248  
  8249    /**
  8250     * Constructor for error display modal.
  8251     *
  8252     * @param  {Player} player
  8253     * @param  {Object} [options]
  8254     */
  8255  
  8256    function ErrorDisplay(player, options) {
  8257      _classCallCheck(this, ErrorDisplay);
  8258  
  8259      _ModalDialog.call(this, player, options);
  8260      this.on(player, 'error', this.open);
  8261    }
  8262  
  8263    /**
  8264     * Include the old class for backward-compatibility.
  8265     *
  8266     * This can be removed in 6.0.
  8267     *
  8268     * @method buildCSSClass
  8269     * @deprecated
  8270     * @return {String}
  8271     */
  8272  
  8273    ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() {
  8274      return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this);
  8275    };
  8276  
  8277    /**
  8278     * Generates the modal content based on the player error.
  8279     *
  8280     * @return {String|Null}
  8281     */
  8282  
  8283    ErrorDisplay.prototype.content = function content() {
  8284      var error = this.player().error();
  8285      return error ? this.localize(error.message) : '';
  8286    };
  8287  
  8288    return ErrorDisplay;
  8289  })(_modalDialog2['default']);
  8290  
  8291  ErrorDisplay.prototype.options_ = _utilsMergeOptions2['default'](_modalDialog2['default'].prototype.options_, {
  8292    fillAlways: true,
  8293    temporary: false,
  8294    uncloseable: true
  8295  });
  8296  
  8297  _component2['default'].registerComponent('ErrorDisplay', ErrorDisplay);
  8298  exports['default'] = ErrorDisplay;
  8299  module.exports = exports['default'];
  8300  
  8301  },{"./component":67,"./modal-dialog":109,"./utils/dom":134,"./utils/merge-options":140}],101:[function(_dereq_,module,exports){
  8302  /**
  8303   * @file event-target.js
  8304   */
  8305  'use strict';
  8306  
  8307  exports.__esModule = true;
  8308  
  8309  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  8310  
  8311  var _utilsEventsJs = _dereq_('./utils/events.js');
  8312  
  8313  var Events = _interopRequireWildcard(_utilsEventsJs);
  8314  
  8315  var EventTarget = function EventTarget() {};
  8316  
  8317  EventTarget.prototype.allowedEvents_ = {};
  8318  
  8319  EventTarget.prototype.on = function (type, fn) {
  8320    // Remove the addEventListener alias before calling Events.on
  8321    // so we don't get into an infinite type loop
  8322    var ael = this.addEventListener;
  8323    this.addEventListener = Function.prototype;
  8324    Events.on(this, type, fn);
  8325    this.addEventListener = ael;
  8326  };
  8327  EventTarget.prototype.addEventListener = EventTarget.prototype.on;
  8328  
  8329  EventTarget.prototype.off = function (type, fn) {
  8330    Events.off(this, type, fn);
  8331  };
  8332  EventTarget.prototype.removeEventListener = EventTarget.prototype.off;
  8333  
  8334  EventTarget.prototype.one = function (type, fn) {
  8335    Events.one(this, type, fn);
  8336  };
  8337  
  8338  EventTarget.prototype.trigger = function (event) {
  8339    var type = event.type || event;
  8340  
  8341    if (typeof event === 'string') {
  8342      event = {
  8343        type: type
  8344      };
  8345    }
  8346    event = Events.fixEvent(event);
  8347  
  8348    if (this.allowedEvents_[type] && this['on' + type]) {
  8349      this['on' + type](event);
  8350    }
  8351  
  8352    Events.trigger(this, event);
  8353  };
  8354  // The standard DOM EventTarget.dispatchEvent() is aliased to trigger()
  8355  EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;
  8356  
  8357  exports['default'] = EventTarget;
  8358  module.exports = exports['default'];
  8359  
  8360  },{"./utils/events.js":135}],102:[function(_dereq_,module,exports){
  8361  'use strict';
  8362  
  8363  exports.__esModule = true;
  8364  
  8365  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  8366  
  8367  var _utilsLog = _dereq_('./utils/log');
  8368  
  8369  var _utilsLog2 = _interopRequireDefault(_utilsLog);
  8370  
  8371  /*
  8372   * @file extend.js
  8373   *
  8374   * A combination of node inherits and babel's inherits (after transpile).
  8375   * Both work the same but node adds `super_` to the subClass
  8376   * and Bable adds the superClass as __proto__. Both seem useful.
  8377   */
  8378  var _inherits = function _inherits(subClass, superClass) {
  8379    if (typeof superClass !== 'function' && superClass !== null) {
  8380      throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
  8381    }
  8382  
  8383    subClass.prototype = Object.create(superClass && superClass.prototype, {
  8384      constructor: {
  8385        value: subClass,
  8386        enumerable: false,
  8387        writable: true,
  8388        configurable: true
  8389      }
  8390    });
  8391  
  8392    if (superClass) {
  8393      // node
  8394      subClass.super_ = superClass;
  8395    }
  8396  };
  8397  
  8398  /*
  8399   * Function for subclassing using the same inheritance that
  8400   * videojs uses internally
  8401   * ```js
  8402   * var Button = videojs.getComponent('Button');
  8403   * ```
  8404   * ```js
  8405   * var MyButton = videojs.extend(Button, {
  8406   *   constructor: function(player, options) {
  8407   *     Button.call(this, player, options);
  8408   *   },
  8409   *   onClick: function() {
  8410   *     // doSomething
  8411   *   }
  8412   * });
  8413   * ```
  8414   */
  8415  var extendFn = function extendFn(superClass) {
  8416    var subClassMethods = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
  8417  
  8418    var subClass = function subClass() {
  8419      superClass.apply(this, arguments);
  8420    };
  8421    var methods = {};
  8422  
  8423    if (typeof subClassMethods === 'object') {
  8424      if (typeof subClassMethods.init === 'function') {
  8425        _utilsLog2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.');
  8426        subClassMethods.constructor = subClassMethods.init;
  8427      }
  8428      if (subClassMethods.constructor !== Object.prototype.constructor) {
  8429        subClass = subClassMethods.constructor;
  8430      }
  8431      methods = subClassMethods;
  8432    } else if (typeof subClassMethods === 'function') {
  8433      subClass = subClassMethods;
  8434    }
  8435  
  8436    _inherits(subClass, superClass);
  8437  
  8438    // Extend subObj's prototype with functions and other properties from props
  8439    for (var name in methods) {
  8440      if (methods.hasOwnProperty(name)) {
  8441        subClass.prototype[name] = methods[name];
  8442      }
  8443    }
  8444  
  8445    return subClass;
  8446  };
  8447  
  8448  exports['default'] = extendFn;
  8449  module.exports = exports['default'];
  8450  
  8451  },{"./utils/log":139}],103:[function(_dereq_,module,exports){
  8452  /**
  8453   * @file fullscreen-api.js
  8454   */
  8455  'use strict';
  8456  
  8457  exports.__esModule = true;
  8458  
  8459  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  8460  
  8461  var _globalDocument = _dereq_('global/document');
  8462  
  8463  var _globalDocument2 = _interopRequireDefault(_globalDocument);
  8464  
  8465  /*
  8466   * Store the browser-specific methods for the fullscreen API
  8467   * @type {Object|undefined}
  8468   * @private
  8469   */
  8470  var FullscreenApi = {};
  8471  
  8472  // browser API methods
  8473  // map approach from Screenful.js - https://github.com/sindresorhus/screenfull.js
  8474  var apiMap = [
  8475  // Spec: https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  8476  ['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'],
  8477  // WebKit
  8478  ['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'],
  8479  // Old WebKit (Safari 5.1)
  8480  ['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'],
  8481  // Mozilla
  8482  ['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'],
  8483  // Microsoft
  8484  ['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']];
  8485  
  8486  var specApi = apiMap[0];
  8487  var browserApi = undefined;
  8488  
  8489  // determine the supported set of functions
  8490  for (var i = 0; i < apiMap.length; i++) {
  8491    // check for exitFullscreen function
  8492    if (apiMap[i][1] in _globalDocument2['default']) {
  8493      browserApi = apiMap[i];
  8494      break;
  8495    }
  8496  }
  8497  
  8498  // map the browser API names to the spec API names
  8499  if (browserApi) {
  8500    for (var i = 0; i < browserApi.length; i++) {
  8501      FullscreenApi[specApi[i]] = browserApi[i];
  8502    }
  8503  }
  8504  
  8505  exports['default'] = FullscreenApi;
  8506  module.exports = exports['default'];
  8507  
  8508  },{"global/document":1}],104:[function(_dereq_,module,exports){
  8509  /**
  8510   * @file loading-spinner.js
  8511   */
  8512  'use strict';
  8513  
  8514  exports.__esModule = true;
  8515  
  8516  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  8517  
  8518  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  8519  
  8520  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  8521  
  8522  var _component = _dereq_('./component');
  8523  
  8524  var _component2 = _interopRequireDefault(_component);
  8525  
  8526  /* Loading Spinner
  8527  ================================================================================ */
  8528  /**
  8529   * Loading spinner for waiting events
  8530   *
  8531   * @extends Component
  8532   * @class LoadingSpinner
  8533   */
  8534  
  8535  var LoadingSpinner = (function (_Component) {
  8536    _inherits(LoadingSpinner, _Component);
  8537  
  8538    function LoadingSpinner() {
  8539      _classCallCheck(this, LoadingSpinner);
  8540  
  8541      _Component.apply(this, arguments);
  8542    }
  8543  
  8544    /**
  8545     * Create the component's DOM element
  8546     *
  8547     * @method createEl
  8548     */
  8549  
  8550    LoadingSpinner.prototype.createEl = function createEl() {
  8551      return _Component.prototype.createEl.call(this, 'div', {
  8552        className: 'vjs-loading-spinner',
  8553        dir: 'ltr'
  8554      });
  8555    };
  8556  
  8557    return LoadingSpinner;
  8558  })(_component2['default']);
  8559  
  8560  _component2['default'].registerComponent('LoadingSpinner', LoadingSpinner);
  8561  exports['default'] = LoadingSpinner;
  8562  module.exports = exports['default'];
  8563  
  8564  },{"./component":67}],105:[function(_dereq_,module,exports){
  8565  /**
  8566   * @file media-error.js
  8567   */
  8568  'use strict';
  8569  
  8570  exports.__esModule = true;
  8571  
  8572  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  8573  
  8574  var _objectAssign = _dereq_('object.assign');
  8575  
  8576  var _objectAssign2 = _interopRequireDefault(_objectAssign);
  8577  
  8578  /*
  8579   * Custom MediaError to mimic the HTML5 MediaError
  8580   *
  8581   * @param {Number} code The media error code
  8582   */
  8583  var MediaError = function MediaError(code) {
  8584    if (typeof code === 'number') {
  8585      this.code = code;
  8586    } else if (typeof code === 'string') {
  8587      // default code is zero, so this is a custom error
  8588      this.message = code;
  8589    } else if (typeof code === 'object') {
  8590      // object
  8591      _objectAssign2['default'](this, code);
  8592    }
  8593  
  8594    if (!this.message) {
  8595      this.message = MediaError.defaultMessages[this.code] || '';
  8596    }
  8597  };
  8598  
  8599  /*
  8600   * The error code that refers two one of the defined
  8601   * MediaError types
  8602   *
  8603   * @type {Number}
  8604   */
  8605  MediaError.prototype.code = 0;
  8606  
  8607  /*
  8608   * An optional message to be shown with the error.
  8609   * Message is not part of the HTML5 video spec
  8610   * but allows for more informative custom errors.
  8611   *
  8612   * @type {String}
  8613   */
  8614  MediaError.prototype.message = '';
  8615  
  8616  /*
  8617   * An optional status code that can be set by plugins
  8618   * to allow even more detail about the error.
  8619   * For example the HLS plugin might provide the specific
  8620   * HTTP status code that was returned when the error
  8621   * occurred, then allowing a custom error overlay
  8622   * to display more information.
  8623   *
  8624   * @type {Array}
  8625   */
  8626  MediaError.prototype.status = null;
  8627  
  8628  MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', // = 0
  8629  'MEDIA_ERR_ABORTED', // = 1
  8630  'MEDIA_ERR_NETWORK', // = 2
  8631  'MEDIA_ERR_DECODE', // = 3
  8632  'MEDIA_ERR_SRC_NOT_SUPPORTED', // = 4
  8633  'MEDIA_ERR_ENCRYPTED' // = 5
  8634  ];
  8635  
  8636  MediaError.defaultMessages = {
  8637    1: 'You aborted the media playback',
  8638    2: 'A network error caused the media download to fail part-way.',
  8639    3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.',
  8640    4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.',
  8641    5: 'The media is encrypted and we do not have the keys to decrypt it.'
  8642  };
  8643  
  8644  // Add types as properties on MediaError
  8645  // e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
  8646  for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) {
  8647    MediaError[MediaError.errorTypes[errNum]] = errNum;
  8648    // values should be accessible on both the class and instance
  8649    MediaError.prototype[MediaError.errorTypes[errNum]] = errNum;
  8650  }
  8651  
  8652  exports['default'] = MediaError;
  8653  module.exports = exports['default'];
  8654  
  8655  },{"object.assign":45}],106:[function(_dereq_,module,exports){
  8656  /**
  8657   * @file menu-button.js
  8658   */
  8659  'use strict';
  8660  
  8661  exports.__esModule = true;
  8662  
  8663  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  8664  
  8665  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  8666  
  8667  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  8668  
  8669  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  8670  
  8671  var _clickableComponentJs = _dereq_('../clickable-component.js');
  8672  
  8673  var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
  8674  
  8675  var _componentJs = _dereq_('../component.js');
  8676  
  8677  var _componentJs2 = _interopRequireDefault(_componentJs);
  8678  
  8679  var _menuJs = _dereq_('./menu.js');
  8680  
  8681  var _menuJs2 = _interopRequireDefault(_menuJs);
  8682  
  8683  var _utilsDomJs = _dereq_('../utils/dom.js');
  8684  
  8685  var Dom = _interopRequireWildcard(_utilsDomJs);
  8686  
  8687  var _utilsFnJs = _dereq_('../utils/fn.js');
  8688  
  8689  var Fn = _interopRequireWildcard(_utilsFnJs);
  8690  
  8691  var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js');
  8692  
  8693  var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
  8694  
  8695  /**
  8696   * A button class with a popup menu
  8697   *
  8698   * @param {Player|Object} player
  8699   * @param {Object=} options
  8700   * @extends Button
  8701   * @class MenuButton
  8702   */
  8703  
  8704  var MenuButton = (function (_ClickableComponent) {
  8705    _inherits(MenuButton, _ClickableComponent);
  8706  
  8707    function MenuButton(player) {
  8708      var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
  8709  
  8710      _classCallCheck(this, MenuButton);
  8711  
  8712      _ClickableComponent.call(this, player, options);
  8713  
  8714      this.update();
  8715  
  8716      this.enabled_ = true;
  8717  
  8718      this.el_.setAttribute('aria-haspopup', 'true');
  8719      this.el_.setAttribute('role', 'menuitem');
  8720      this.on('keydown', this.handleSubmenuKeyPress);
  8721    }
  8722  
  8723    /**
  8724     * Update menu
  8725     *
  8726     * @method update
  8727     */
  8728  
  8729    MenuButton.prototype.update = function update() {
  8730      var menu = this.createMenu();
  8731  
  8732      if (this.menu) {
  8733        this.removeChild(this.menu);
  8734      }
  8735  
  8736      this.menu = menu;
  8737      this.addChild(menu);
  8738  
  8739      /**
  8740       * Track the state of the menu button
  8741       *
  8742       * @type {Boolean}
  8743       * @private
  8744       */
  8745      this.buttonPressed_ = false;
  8746      this.el_.setAttribute('aria-expanded', 'false');
  8747  
  8748      if (this.items && this.items.length === 0) {
  8749        this.hide();
  8750      } else if (this.items && this.items.length > 1) {
  8751        this.show();
  8752      }
  8753    };
  8754  
  8755    /**
  8756     * Create menu
  8757     *
  8758     * @return {Menu} The constructed menu
  8759     * @method createMenu
  8760     */
  8761  
  8762    MenuButton.prototype.createMenu = function createMenu() {
  8763      var menu = new _menuJs2['default'](this.player_);
  8764  
  8765      // Add a title list item to the top
  8766      if (this.options_.title) {
  8767        var title = Dom.createEl('li', {
  8768          className: 'vjs-menu-title',
  8769          innerHTML: _utilsToTitleCaseJs2['default'](this.options_.title),
  8770          tabIndex: -1
  8771        });
  8772        menu.children_.unshift(title);
  8773        Dom.insertElFirst(title, menu.contentEl());
  8774      }
  8775  
  8776      this.items = this['createItems']();
  8777  
  8778      if (this.items) {
  8779        // Add menu items to the menu
  8780        for (var i = 0; i < this.items.length; i++) {
  8781          menu.addItem(this.items[i]);
  8782        }
  8783      }
  8784  
  8785      return menu;
  8786    };
  8787  
  8788    /**
  8789     * Create the list of menu items. Specific to each subclass.
  8790     *
  8791     * @method createItems
  8792     */
  8793  
  8794    MenuButton.prototype.createItems = function createItems() {};
  8795  
  8796    /**
  8797     * Create the component's DOM element
  8798     *
  8799     * @return {Element}
  8800     * @method createEl
  8801     */
  8802  
  8803    MenuButton.prototype.createEl = function createEl() {
  8804      return _ClickableComponent.prototype.createEl.call(this, 'div', {
  8805        className: this.buildCSSClass()
  8806      });
  8807    };
  8808  
  8809    /**
  8810     * Allow sub components to stack CSS class names
  8811     *
  8812     * @return {String} The constructed class name
  8813     * @method buildCSSClass
  8814     */
  8815  
  8816    MenuButton.prototype.buildCSSClass = function buildCSSClass() {
  8817      var menuButtonClass = 'vjs-menu-button';
  8818  
  8819      // If the inline option is passed, we want to use different styles altogether.
  8820      if (this.options_.inline === true) {
  8821        menuButtonClass += '-inline';
  8822      } else {
  8823        menuButtonClass += '-popup';
  8824      }
  8825  
  8826      return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
  8827    };
  8828  
  8829    /**
  8830     * When you click the button it adds focus, which
  8831     * will show the menu indefinitely.
  8832     * So we'll remove focus when the mouse leaves the button.
  8833     * Focus is needed for tab navigation.
  8834     * Allow sub components to stack CSS class names
  8835     *
  8836     * @method handleClick
  8837     */
  8838  
  8839    MenuButton.prototype.handleClick = function handleClick() {
  8840      this.one('mouseout', Fn.bind(this, function () {
  8841        this.menu.unlockShowing();
  8842        this.el_.blur();
  8843      }));
  8844      if (this.buttonPressed_) {
  8845        this.unpressButton();
  8846      } else {
  8847        this.pressButton();
  8848      }
  8849    };
  8850  
  8851    /**
  8852     * Handle key press on menu
  8853     *
  8854     * @param {Object} event Key press event
  8855     * @method handleKeyPress
  8856     */
  8857  
  8858    MenuButton.prototype.handleKeyPress = function handleKeyPress(event) {
  8859  
  8860      // Escape (27) key or Tab (9) key unpress the 'button'
  8861      if (event.which === 27 || event.which === 9) {
  8862        if (this.buttonPressed_) {
  8863          this.unpressButton();
  8864        }
  8865        // Don't preventDefault for Tab key - we still want to lose focus
  8866        if (event.which !== 9) {
  8867          event.preventDefault();
  8868        }
  8869        // Up (38) key or Down (40) key press the 'button'
  8870      } else if (event.which === 38 || event.which === 40) {
  8871          if (!this.buttonPressed_) {
  8872            this.pressButton();
  8873            event.preventDefault();
  8874          }
  8875        } else {
  8876          _ClickableComponent.prototype.handleKeyPress.call(this, event);
  8877        }
  8878    };
  8879  
  8880    /**
  8881     * Handle key press on submenu
  8882     *
  8883     * @param {Object} event Key press event
  8884     * @method handleSubmenuKeyPress
  8885     */
  8886  
  8887    MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) {
  8888  
  8889      // Escape (27) key or Tab (9) key unpress the 'button'
  8890      if (event.which === 27 || event.which === 9) {
  8891        if (this.buttonPressed_) {
  8892          this.unpressButton();
  8893        }
  8894        // Don't preventDefault for Tab key - we still want to lose focus
  8895        if (event.which !== 9) {
  8896          event.preventDefault();
  8897        }
  8898      }
  8899    };
  8900  
  8901    /**
  8902     * Makes changes based on button pressed
  8903     *
  8904     * @method pressButton
  8905     */
  8906  
  8907    MenuButton.prototype.pressButton = function pressButton() {
  8908      if (this.enabled_) {
  8909        this.buttonPressed_ = true;
  8910        this.menu.lockShowing();
  8911        this.el_.setAttribute('aria-expanded', 'true');
  8912        this.menu.focus(); // set the focus into the submenu
  8913      }
  8914    };
  8915  
  8916    /**
  8917     * Makes changes based on button unpressed
  8918     *
  8919     * @method unpressButton
  8920     */
  8921  
  8922    MenuButton.prototype.unpressButton = function unpressButton() {
  8923      if (this.enabled_) {
  8924        this.buttonPressed_ = false;
  8925        this.menu.unlockShowing();
  8926        this.el_.setAttribute('aria-expanded', 'false');
  8927        this.el_.focus(); // Set focus back to this menu button
  8928      }
  8929    };
  8930  
  8931    /**
  8932     * Disable the menu button
  8933     *
  8934     * @return {Component}
  8935     * @method disable
  8936     */
  8937  
  8938    MenuButton.prototype.disable = function disable() {
  8939      // Unpress, but don't force focus on this button
  8940      this.buttonPressed_ = false;
  8941      this.menu.unlockShowing();
  8942      this.el_.setAttribute('aria-expanded', 'false');
  8943  
  8944      this.enabled_ = false;
  8945  
  8946      return _ClickableComponent.prototype.disable.call(this);
  8947    };
  8948  
  8949    /**
  8950     * Enable the menu button
  8951     *
  8952     * @return {Component}
  8953     * @method disable
  8954     */
  8955  
  8956    MenuButton.prototype.enable = function enable() {
  8957      this.enabled_ = true;
  8958  
  8959      return _ClickableComponent.prototype.enable.call(this);
  8960    };
  8961  
  8962    return MenuButton;
  8963  })(_clickableComponentJs2['default']);
  8964  
  8965  _componentJs2['default'].registerComponent('MenuButton', MenuButton);
  8966  exports['default'] = MenuButton;
  8967  module.exports = exports['default'];
  8968  
  8969  },{"../clickable-component.js":65,"../component.js":67,"../utils/dom.js":134,"../utils/fn.js":136,"../utils/to-title-case.js":143,"./menu.js":108}],107:[function(_dereq_,module,exports){
  8970  /**
  8971   * @file menu-item.js
  8972   */
  8973  'use strict';
  8974  
  8975  exports.__esModule = true;
  8976  
  8977  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  8978  
  8979  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  8980  
  8981  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  8982  
  8983  var _clickableComponentJs = _dereq_('../clickable-component.js');
  8984  
  8985  var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
  8986  
  8987  var _componentJs = _dereq_('../component.js');
  8988  
  8989  var _componentJs2 = _interopRequireDefault(_componentJs);
  8990  
  8991  var _objectAssign = _dereq_('object.assign');
  8992  
  8993  var _objectAssign2 = _interopRequireDefault(_objectAssign);
  8994  
  8995  /**
  8996   * The component for a menu item. `<li>`
  8997   *
  8998   * @param {Player|Object} player
  8999   * @param {Object=} options
  9000   * @extends Button
  9001   * @class MenuItem
  9002   */
  9003  
  9004  var MenuItem = (function (_ClickableComponent) {
  9005    _inherits(MenuItem, _ClickableComponent);
  9006  
  9007    function MenuItem(player, options) {
  9008      _classCallCheck(this, MenuItem);
  9009  
  9010      _ClickableComponent.call(this, player, options);
  9011  
  9012      this.selectable = options['selectable'];
  9013  
  9014      this.selected(options['selected']);
  9015  
  9016      if (this.selectable) {
  9017        // TODO: May need to be either menuitemcheckbox or menuitemradio,
  9018        //       and may need logical grouping of menu items.
  9019        this.el_.setAttribute('role', 'menuitemcheckbox');
  9020      } else {
  9021        this.el_.setAttribute('role', 'menuitem');
  9022      }
  9023    }
  9024  
  9025    /**
  9026     * Create the component's DOM element
  9027     *
  9028     * @param {String=} type Desc
  9029     * @param {Object=} props Desc
  9030     * @return {Element}
  9031     * @method createEl
  9032     */
  9033  
  9034    MenuItem.prototype.createEl = function createEl(type, props, attrs) {
  9035      return _ClickableComponent.prototype.createEl.call(this, 'li', _objectAssign2['default']({
  9036        className: 'vjs-menu-item',
  9037        innerHTML: this.localize(this.options_['label']),
  9038        tabIndex: -1
  9039      }, props), attrs);
  9040    };
  9041  
  9042    /**
  9043     * Handle a click on the menu item, and set it to selected
  9044     *
  9045     * @method handleClick
  9046     */
  9047  
  9048    MenuItem.prototype.handleClick = function handleClick() {
  9049      this.selected(true);
  9050    };
  9051  
  9052    /**
  9053     * Set this menu item as selected or not
  9054     *
  9055     * @param  {Boolean} selected
  9056     * @method selected
  9057     */
  9058  
  9059    MenuItem.prototype.selected = function selected(_selected) {
  9060      if (this.selectable) {
  9061        if (_selected) {
  9062          this.addClass('vjs-selected');
  9063          this.el_.setAttribute('aria-checked', 'true');
  9064          // aria-checked isn't fully supported by browsers/screen readers,
  9065          // so indicate selected state to screen reader in the control text.
  9066          this.controlText(', selected');
  9067        } else {
  9068          this.removeClass('vjs-selected');
  9069          this.el_.setAttribute('aria-checked', 'false');
  9070          // Indicate un-selected state to screen reader
  9071          // Note that a space clears out the selected state text
  9072          this.controlText(' ');
  9073        }
  9074      }
  9075    };
  9076  
  9077    return MenuItem;
  9078  })(_clickableComponentJs2['default']);
  9079  
  9080  _componentJs2['default'].registerComponent('MenuItem', MenuItem);
  9081  exports['default'] = MenuItem;
  9082  module.exports = exports['default'];
  9083  
  9084  },{"../clickable-component.js":65,"../component.js":67,"object.assign":45}],108:[function(_dereq_,module,exports){
  9085  /**
  9086   * @file menu.js
  9087   */
  9088  'use strict';
  9089  
  9090  exports.__esModule = true;
  9091  
  9092  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  9093  
  9094  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  9095  
  9096  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  9097  
  9098  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  9099  
  9100  var _componentJs = _dereq_('../component.js');
  9101  
  9102  var _componentJs2 = _interopRequireDefault(_componentJs);
  9103  
  9104  var _utilsDomJs = _dereq_('../utils/dom.js');
  9105  
  9106  var Dom = _interopRequireWildcard(_utilsDomJs);
  9107  
  9108  var _utilsFnJs = _dereq_('../utils/fn.js');
  9109  
  9110  var Fn = _interopRequireWildcard(_utilsFnJs);
  9111  
  9112  var _utilsEventsJs = _dereq_('../utils/events.js');
  9113  
  9114  var Events = _interopRequireWildcard(_utilsEventsJs);
  9115  
  9116  /**
  9117   * The Menu component is used to build pop up menus, including subtitle and
  9118   * captions selection menus.
  9119   *
  9120   * @extends Component
  9121   * @class Menu
  9122   */
  9123  
  9124  var Menu = (function (_Component) {
  9125    _inherits(Menu, _Component);
  9126  
  9127    function Menu(player, options) {
  9128      _classCallCheck(this, Menu);
  9129  
  9130      _Component.call(this, player, options);
  9131  
  9132      this.focusedChild_ = -1;
  9133  
  9134      this.on('keydown', this.handleKeyPress);
  9135    }
  9136  
  9137    /**
  9138     * Add a menu item to the menu
  9139     *
  9140     * @param {Object|String} component Component or component type to add
  9141     * @method addItem
  9142     */
  9143  
  9144    Menu.prototype.addItem = function addItem(component) {
  9145      this.addChild(component);
  9146      component.on('click', Fn.bind(this, function () {
  9147        this.unlockShowing();
  9148        //TODO: Need to set keyboard focus back to the menuButton
  9149      }));
  9150    };
  9151  
  9152    /**
  9153     * Create the component's DOM element
  9154     *
  9155     * @return {Element}
  9156     * @method createEl
  9157     */
  9158  
  9159    Menu.prototype.createEl = function createEl() {
  9160      var contentElType = this.options_.contentElType || 'ul';
  9161      this.contentEl_ = Dom.createEl(contentElType, {
  9162        className: 'vjs-menu-content'
  9163      });
  9164      this.contentEl_.setAttribute('role', 'menu');
  9165      var el = _Component.prototype.createEl.call(this, 'div', {
  9166        append: this.contentEl_,
  9167        className: 'vjs-menu'
  9168      });
  9169      el.setAttribute('role', 'presentation');
  9170      el.appendChild(this.contentEl_);
  9171  
  9172      // Prevent clicks from bubbling up. Needed for Menu Buttons,
  9173      // where a click on the parent is significant
  9174      Events.on(el, 'click', function (event) {
  9175        event.preventDefault();
  9176        event.stopImmediatePropagation();
  9177      });
  9178  
  9179      return el;
  9180    };
  9181  
  9182    /**
  9183     * Handle key press for menu
  9184     *
  9185     * @param {Object} event Event object
  9186     * @method handleKeyPress
  9187     */
  9188  
  9189    Menu.prototype.handleKeyPress = function handleKeyPress(event) {
  9190      if (event.which === 37 || event.which === 40) {
  9191        // Left and Down Arrows
  9192        event.preventDefault();
  9193        this.stepForward();
  9194      } else if (event.which === 38 || event.which === 39) {
  9195        // Up and Right Arrows
  9196        event.preventDefault();
  9197        this.stepBack();
  9198      }
  9199    };
  9200  
  9201    /**
  9202     * Move to next (lower) menu item for keyboard users
  9203     *
  9204     * @method stepForward
  9205     */
  9206  
  9207    Menu.prototype.stepForward = function stepForward() {
  9208      var stepChild = 0;
  9209  
  9210      if (this.focusedChild_ !== undefined) {
  9211        stepChild = this.focusedChild_ + 1;
  9212      }
  9213      this.focus(stepChild);
  9214    };
  9215  
  9216    /**
  9217     * Move to previous (higher) menu item for keyboard users
  9218     *
  9219     * @method stepBack
  9220     */
  9221  
  9222    Menu.prototype.stepBack = function stepBack() {
  9223      var stepChild = 0;
  9224  
  9225      if (this.focusedChild_ !== undefined) {
  9226        stepChild = this.focusedChild_ - 1;
  9227      }
  9228      this.focus(stepChild);
  9229    };
  9230  
  9231    /**
  9232     * Set focus on a menu item in the menu
  9233     *
  9234     * @param {Object|String} item Index of child item set focus on
  9235     * @method focus
  9236     */
  9237  
  9238    Menu.prototype.focus = function focus() {
  9239      var item = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];
  9240  
  9241      var children = this.children().slice();
  9242      var haveTitle = children.length && children[0].className && /vjs-menu-title/.test(children[0].className);
  9243  
  9244      if (haveTitle) {
  9245        children.shift();
  9246      }
  9247  
  9248      if (children.length > 0) {
  9249        if (item < 0) {
  9250          item = 0;
  9251        } else if (item >= children.length) {
  9252          item = children.length - 1;
  9253        }
  9254  
  9255        this.focusedChild_ = item;
  9256  
  9257        children[item].el_.focus();
  9258      }
  9259    };
  9260  
  9261    return Menu;
  9262  })(_componentJs2['default']);
  9263  
  9264  _componentJs2['default'].registerComponent('Menu', Menu);
  9265  exports['default'] = Menu;
  9266  module.exports = exports['default'];
  9267  
  9268  },{"../component.js":67,"../utils/dom.js":134,"../utils/events.js":135,"../utils/fn.js":136}],109:[function(_dereq_,module,exports){
  9269  /**
  9270   * @file modal-dialog.js
  9271   */
  9272  'use strict';
  9273  
  9274  exports.__esModule = true;
  9275  
  9276  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  9277  
  9278  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  9279  
  9280  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  9281  
  9282  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  9283  
  9284  var _utilsDom = _dereq_('./utils/dom');
  9285  
  9286  var Dom = _interopRequireWildcard(_utilsDom);
  9287  
  9288  var _utilsFn = _dereq_('./utils/fn');
  9289  
  9290  var Fn = _interopRequireWildcard(_utilsFn);
  9291  
  9292  var _utilsLog = _dereq_('./utils/log');
  9293  
  9294  var _utilsLog2 = _interopRequireDefault(_utilsLog);
  9295  
  9296  var _component = _dereq_('./component');
  9297  
  9298  var _component2 = _interopRequireDefault(_component);
  9299  
  9300  var _closeButton = _dereq_('./close-button');
  9301  
  9302  var _closeButton2 = _interopRequireDefault(_closeButton);
  9303  
  9304  var MODAL_CLASS_NAME = 'vjs-modal-dialog';
  9305  var ESC = 27;
  9306  
  9307  /**
  9308   * The `ModalDialog` displays over the video and its controls, which blocks
  9309   * interaction with the player until it is closed.
  9310   *
  9311   * Modal dialogs include a "Close" button and will close when that button
  9312   * is activated - or when ESC is pressed anywhere.
  9313   *
  9314   * @extends Component
  9315   * @class ModalDialog
  9316   */
  9317  
  9318  var ModalDialog = (function (_Component) {
  9319    _inherits(ModalDialog, _Component);
  9320  
  9321    /**
  9322     * Constructor for modals.
  9323     *
  9324     * @param  {Player} player
  9325     * @param  {Object} [options]
  9326     * @param  {Mixed} [options.content=undefined]
  9327     *         Provide customized content for this modal.
  9328     *
  9329     * @param  {String} [options.description]
  9330     *         A text description for the modal, primarily for accessibility.
  9331     *
  9332     * @param  {Boolean} [options.fillAlways=false]
  9333     *         Normally, modals are automatically filled only the first time
  9334     *         they open. This tells the modal to refresh its content
  9335     *         every time it opens.
  9336     *
  9337     * @param  {String} [options.label]
  9338     *         A text label for the modal, primarily for accessibility.
  9339     *
  9340     * @param  {Boolean} [options.temporary=true]
  9341     *         If `true`, the modal can only be opened once; it will be
  9342     *         disposed as soon as it's closed.
  9343     *
  9344     * @param  {Boolean} [options.uncloseable=false]
  9345     *         If `true`, the user will not be able to close the modal
  9346     *         through the UI in the normal ways. Programmatic closing is
  9347     *         still possible.
  9348     *
  9349     */
  9350  
  9351    function ModalDialog(player, options) {
  9352      _classCallCheck(this, ModalDialog);
  9353  
  9354      _Component.call(this, player, options);
  9355      this.opened_ = this.hasBeenOpened_ = this.hasBeenFilled_ = false;
  9356  
  9357      this.closeable(!this.options_.uncloseable);
  9358      this.content(this.options_.content);
  9359  
  9360      // Make sure the contentEl is defined AFTER any children are initialized
  9361      // because we only want the contents of the modal in the contentEl
  9362      // (not the UI elements like the close button).
  9363      this.contentEl_ = Dom.createEl('div', {
  9364        className: MODAL_CLASS_NAME + '-content'
  9365      }, {
  9366        role: 'document'
  9367      });
  9368  
  9369      this.descEl_ = Dom.createEl('p', {
  9370        className: MODAL_CLASS_NAME + '-description vjs-offscreen',
  9371        id: this.el().getAttribute('aria-describedby')
  9372      });
  9373  
  9374      Dom.textContent(this.descEl_, this.description());
  9375      this.el_.appendChild(this.descEl_);
  9376      this.el_.appendChild(this.contentEl_);
  9377    }
  9378  
  9379    /*
  9380     * Modal dialog default options.
  9381     *
  9382     * @type {Object}
  9383     * @private
  9384     */
  9385  
  9386    /**
  9387     * Create the modal's DOM element
  9388     *
  9389     * @method createEl
  9390     * @return {Element}
  9391     */
  9392  
  9393    ModalDialog.prototype.createEl = function createEl() {
  9394      return _Component.prototype.createEl.call(this, 'div', {
  9395        className: this.buildCSSClass(),
  9396        tabIndex: -1
  9397      }, {
  9398        'aria-describedby': this.id() + '_description',
  9399        'aria-hidden': 'true',
  9400        'aria-label': this.label(),
  9401        role: 'dialog'
  9402      });
  9403    };
  9404  
  9405    /**
  9406     * Build the modal's CSS class.
  9407     *
  9408     * @method buildCSSClass
  9409     * @return {String}
  9410     */
  9411  
  9412    ModalDialog.prototype.buildCSSClass = function buildCSSClass() {
  9413      return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this);
  9414    };
  9415  
  9416    /**
  9417     * Handles key presses on the document, looking for ESC, which closes
  9418     * the modal.
  9419     *
  9420     * @method handleKeyPress
  9421     * @param  {Event} e
  9422     */
  9423  
  9424    ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) {
  9425      if (e.which === ESC && this.closeable()) {
  9426        this.close();
  9427      }
  9428    };
  9429  
  9430    /**
  9431     * Returns the label string for this modal. Primarily used for accessibility.
  9432     *
  9433     * @return {String}
  9434     */
  9435  
  9436    ModalDialog.prototype.label = function label() {
  9437      return this.options_.label || this.localize('Modal Window');
  9438    };
  9439  
  9440    /**
  9441     * Returns the description string for this modal. Primarily used for
  9442     * accessibility.
  9443     *
  9444     * @return {String}
  9445     */
  9446  
  9447    ModalDialog.prototype.description = function description() {
  9448      var desc = this.options_.description || this.localize('This is a modal window.');
  9449  
  9450      // Append a universal closeability message if the modal is closeable.
  9451      if (this.closeable()) {
  9452        desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.');
  9453      }
  9454  
  9455      return desc;
  9456    };
  9457  
  9458    /**
  9459     * Opens the modal.
  9460     *
  9461     * @method open
  9462     * @return {ModalDialog}
  9463     */
  9464  
  9465    ModalDialog.prototype.open = function open() {
  9466      if (!this.opened_) {
  9467        var player = this.player();
  9468  
  9469        this.trigger('beforemodalopen');
  9470        this.opened_ = true;
  9471  
  9472        // Fill content if the modal has never opened before and
  9473        // never been filled.
  9474        if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) {
  9475          this.fill();
  9476        }
  9477  
  9478        // If the player was playing, pause it and take note of its previously
  9479        // playing state.
  9480        this.wasPlaying_ = !player.paused();
  9481  
  9482        if (this.wasPlaying_) {
  9483          player.pause();
  9484        }
  9485  
  9486        if (this.closeable()) {
  9487          this.on(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
  9488        }
  9489  
  9490        player.controls(false);
  9491        this.show();
  9492        this.el().setAttribute('aria-hidden', 'false');
  9493        this.trigger('modalopen');
  9494        this.hasBeenOpened_ = true;
  9495      }
  9496      return this;
  9497    };
  9498  
  9499    /**
  9500     * Whether or not the modal is opened currently.
  9501     *
  9502     * @method opened
  9503     * @param  {Boolean} [value]
  9504     *         If given, it will open (`true`) or close (`false`) the modal.
  9505     *
  9506     * @return {Boolean}
  9507     */
  9508  
  9509    ModalDialog.prototype.opened = function opened(value) {
  9510      if (typeof value === 'boolean') {
  9511        this[value ? 'open' : 'close']();
  9512      }
  9513      return this.opened_;
  9514    };
  9515  
  9516    /**
  9517     * Closes the modal.
  9518     *
  9519     * @method close
  9520     * @return {ModalDialog}
  9521     */
  9522  
  9523    ModalDialog.prototype.close = function close() {
  9524      if (this.opened_) {
  9525        var player = this.player();
  9526  
  9527        this.trigger('beforemodalclose');
  9528        this.opened_ = false;
  9529  
  9530        if (this.wasPlaying_) {
  9531          player.play();
  9532        }
  9533  
  9534        if (this.closeable()) {
  9535          this.off(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
  9536        }
  9537  
  9538        player.controls(true);
  9539        this.hide();
  9540        this.el().setAttribute('aria-hidden', 'true');
  9541        this.trigger('modalclose');
  9542  
  9543        if (this.options_.temporary) {
  9544          this.dispose();
  9545        }
  9546      }
  9547      return this;
  9548    };
  9549  
  9550    /**
  9551     * Whether or not the modal is closeable via the UI.
  9552     *
  9553     * @method closeable
  9554     * @param  {Boolean} [value]
  9555     *         If given as a Boolean, it will set the `closeable` option.
  9556     *
  9557     * @return {Boolean}
  9558     */
  9559  
  9560    ModalDialog.prototype.closeable = function closeable(value) {
  9561      if (typeof value === 'boolean') {
  9562        var closeable = this.closeable_ = !!value;
  9563        var _close = this.getChild('closeButton');
  9564  
  9565        // If this is being made closeable and has no close button, add one.
  9566        if (closeable && !_close) {
  9567  
  9568          // The close button should be a child of the modal - not its
  9569          // content element, so temporarily change the content element.
  9570          var temp = this.contentEl_;
  9571          this.contentEl_ = this.el_;
  9572          _close = this.addChild('closeButton');
  9573          this.contentEl_ = temp;
  9574          this.on(_close, 'close', this.close);
  9575        }
  9576  
  9577        // If this is being made uncloseable and has a close button, remove it.
  9578        if (!closeable && _close) {
  9579          this.off(_close, 'close', this.close);
  9580          this.removeChild(_close);
  9581          _close.dispose();
  9582        }
  9583      }
  9584      return this.closeable_;
  9585    };
  9586  
  9587    /**
  9588     * Fill the modal's content element with the modal's "content" option.
  9589     *
  9590     * The content element will be emptied before this change takes place.
  9591     *
  9592     * @method fill
  9593     * @return {ModalDialog}
  9594     */
  9595  
  9596    ModalDialog.prototype.fill = function fill() {
  9597      return this.fillWith(this.content());
  9598    };
  9599  
  9600    /**
  9601     * Fill the modal's content element with arbitrary content.
  9602     *
  9603     * The content element will be emptied before this change takes place.
  9604     *
  9605     * @method fillWith
  9606     * @param  {Mixed} [content]
  9607     *         The same rules apply to this as apply to the `content` option.
  9608     *
  9609     * @return {ModalDialog}
  9610     */
  9611  
  9612    ModalDialog.prototype.fillWith = function fillWith(content) {
  9613      var contentEl = this.contentEl();
  9614      var parentEl = contentEl.parentNode;
  9615      var nextSiblingEl = contentEl.nextSibling;
  9616  
  9617      this.trigger('beforemodalfill');
  9618      this.hasBeenFilled_ = true;
  9619  
  9620      // Detach the content element from the DOM before performing
  9621      // manipulation to avoid modifying the live DOM multiple times.
  9622      parentEl.removeChild(contentEl);
  9623      this.empty();
  9624      Dom.insertContent(contentEl, content);
  9625      this.trigger('modalfill');
  9626  
  9627      // Re-inject the re-filled content element.
  9628      if (nextSiblingEl) {
  9629        parentEl.insertBefore(contentEl, nextSiblingEl);
  9630      } else {
  9631        parentEl.appendChild(contentEl);
  9632      }
  9633  
  9634      return this;
  9635    };
  9636  
  9637    /**
  9638     * Empties the content element.
  9639     *
  9640     * This happens automatically anytime the modal is filled.
  9641     *
  9642     * @method empty
  9643     * @return {ModalDialog}
  9644     */
  9645  
  9646    ModalDialog.prototype.empty = function empty() {
  9647      this.trigger('beforemodalempty');
  9648      Dom.emptyEl(this.contentEl());
  9649      this.trigger('modalempty');
  9650      return this;
  9651    };
  9652  
  9653    /**
  9654     * Gets or sets the modal content, which gets normalized before being
  9655     * rendered into the DOM.
  9656     *
  9657     * This does not update the DOM or fill the modal, but it is called during
  9658     * that process.
  9659     *
  9660     * @method content
  9661     * @param  {Mixed} [value]
  9662     *         If defined, sets the internal content value to be used on the
  9663     *         next call(s) to `fill`. This value is normalized before being
  9664     *         inserted. To "clear" the internal content value, pass `null`.
  9665     *
  9666     * @return {Mixed}
  9667     */
  9668  
  9669    ModalDialog.prototype.content = function content(value) {
  9670      if (typeof value !== 'undefined') {
  9671        this.content_ = value;
  9672      }
  9673      return this.content_;
  9674    };
  9675  
  9676    return ModalDialog;
  9677  })(_component2['default']);
  9678  
  9679  ModalDialog.prototype.options_ = {
  9680    temporary: true
  9681  };
  9682  
  9683  _component2['default'].registerComponent('ModalDialog', ModalDialog);
  9684  exports['default'] = ModalDialog;
  9685  module.exports = exports['default'];
  9686  
  9687  },{"./close-button":66,"./component":67,"./utils/dom":134,"./utils/fn":136,"./utils/log":139}],110:[function(_dereq_,module,exports){
  9688  /**
  9689   * @file player.js
  9690   */
  9691  // Subclasses Component
  9692  'use strict';
  9693  
  9694  exports.__esModule = true;
  9695  
  9696  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  9697  
  9698  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  9699  
  9700  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  9701  
  9702  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  9703  
  9704  var _componentJs = _dereq_('./component.js');
  9705  
  9706  var _componentJs2 = _interopRequireDefault(_componentJs);
  9707  
  9708  var _globalDocument = _dereq_('global/document');
  9709  
  9710  var _globalDocument2 = _interopRequireDefault(_globalDocument);
  9711  
  9712  var _globalWindow = _dereq_('global/window');
  9713  
  9714  var _globalWindow2 = _interopRequireDefault(_globalWindow);
  9715  
  9716  var _utilsEventsJs = _dereq_('./utils/events.js');
  9717  
  9718  var Events = _interopRequireWildcard(_utilsEventsJs);
  9719  
  9720  var _utilsDomJs = _dereq_('./utils/dom.js');
  9721  
  9722  var Dom = _interopRequireWildcard(_utilsDomJs);
  9723  
  9724  var _utilsFnJs = _dereq_('./utils/fn.js');
  9725  
  9726  var Fn = _interopRequireWildcard(_utilsFnJs);
  9727  
  9728  var _utilsGuidJs = _dereq_('./utils/guid.js');
  9729  
  9730  var Guid = _interopRequireWildcard(_utilsGuidJs);
  9731  
  9732  var _utilsBrowserJs = _dereq_('./utils/browser.js');
  9733  
  9734  var browser = _interopRequireWildcard(_utilsBrowserJs);
  9735  
  9736  var _utilsLogJs = _dereq_('./utils/log.js');
  9737  
  9738  var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
  9739  
  9740  var _utilsToTitleCaseJs = _dereq_('./utils/to-title-case.js');
  9741  
  9742  var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
  9743  
  9744  var _utilsTimeRangesJs = _dereq_('./utils/time-ranges.js');
  9745  
  9746  var _utilsBufferJs = _dereq_('./utils/buffer.js');
  9747  
  9748  var _utilsStylesheetJs = _dereq_('./utils/stylesheet.js');
  9749  
  9750  var stylesheet = _interopRequireWildcard(_utilsStylesheetJs);
  9751  
  9752  var _fullscreenApiJs = _dereq_('./fullscreen-api.js');
  9753  
  9754  var _fullscreenApiJs2 = _interopRequireDefault(_fullscreenApiJs);
  9755  
  9756  var _mediaErrorJs = _dereq_('./media-error.js');
  9757  
  9758  var _mediaErrorJs2 = _interopRequireDefault(_mediaErrorJs);
  9759  
  9760  var _safeJsonParseTuple = _dereq_('safe-json-parse/tuple');
  9761  
  9762  var _safeJsonParseTuple2 = _interopRequireDefault(_safeJsonParseTuple);
  9763  
  9764  var _objectAssign = _dereq_('object.assign');
  9765  
  9766  var _objectAssign2 = _interopRequireDefault(_objectAssign);
  9767  
  9768  var _utilsMergeOptionsJs = _dereq_('./utils/merge-options.js');
  9769  
  9770  var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);
  9771  
  9772  var _tracksTextTrackListConverterJs = _dereq_('./tracks/text-track-list-converter.js');
  9773  
  9774  var _tracksTextTrackListConverterJs2 = _interopRequireDefault(_tracksTextTrackListConverterJs);
  9775  
  9776  // Include required child components (importing also registers them)
  9777  
  9778  var _techLoaderJs = _dereq_('./tech/loader.js');
  9779  
  9780  var _techLoaderJs2 = _interopRequireDefault(_techLoaderJs);
  9781  
  9782  var _posterImageJs = _dereq_('./poster-image.js');
  9783  
  9784  var _posterImageJs2 = _interopRequireDefault(_posterImageJs);
  9785  
  9786  var _tracksTextTrackDisplayJs = _dereq_('./tracks/text-track-display.js');
  9787  
  9788  var _tracksTextTrackDisplayJs2 = _interopRequireDefault(_tracksTextTrackDisplayJs);
  9789  
  9790  var _loadingSpinnerJs = _dereq_('./loading-spinner.js');
  9791  
  9792  var _loadingSpinnerJs2 = _interopRequireDefault(_loadingSpinnerJs);
  9793  
  9794  var _bigPlayButtonJs = _dereq_('./big-play-button.js');
  9795  
  9796  var _bigPlayButtonJs2 = _interopRequireDefault(_bigPlayButtonJs);
  9797  
  9798  var _controlBarControlBarJs = _dereq_('./control-bar/control-bar.js');
  9799  
  9800  var _controlBarControlBarJs2 = _interopRequireDefault(_controlBarControlBarJs);
  9801  
  9802  var _errorDisplayJs = _dereq_('./error-display.js');
  9803  
  9804  var _errorDisplayJs2 = _interopRequireDefault(_errorDisplayJs);
  9805  
  9806  var _tracksTextTrackSettingsJs = _dereq_('./tracks/text-track-settings.js');
  9807  
  9808  var _tracksTextTrackSettingsJs2 = _interopRequireDefault(_tracksTextTrackSettingsJs);
  9809  
  9810  var _modalDialog = _dereq_('./modal-dialog');
  9811  
  9812  var _modalDialog2 = _interopRequireDefault(_modalDialog);
  9813  
  9814  // Require html5 tech, at least for disposing the original video tag
  9815  
  9816  var _techTechJs = _dereq_('./tech/tech.js');
  9817  
  9818  var _techTechJs2 = _interopRequireDefault(_techTechJs);
  9819  
  9820  var _techHtml5Js = _dereq_('./tech/html5.js');
  9821  
  9822  var _techHtml5Js2 = _interopRequireDefault(_techHtml5Js);
  9823  
  9824  /**
  9825   * An instance of the `Player` class is created when any of the Video.js setup methods are used to initialize a video.
  9826   * ```js
  9827   * var myPlayer = videojs('example_video_1');
  9828   * ```
  9829   * In the following example, the `data-setup` attribute tells the Video.js library to create a player instance when the library is ready.
  9830   * ```html
  9831   * <video id="example_video_1" data-setup='{}' controls>
  9832   *   <source src="my-source.mp4" type="video/mp4">
  9833   * </video>
  9834   * ```
  9835   * After an instance has been created it can be accessed globally using `Video('example_video_1')`.
  9836   *
  9837   * @param {Element} tag        The original video tag used for configuring options
  9838   * @param {Object=} options    Object of option names and values
  9839   * @param {Function=} ready    Ready callback function
  9840   * @extends Component
  9841   * @class Player
  9842   */
  9843  
  9844  var Player = (function (_Component) {
  9845    _inherits(Player, _Component);
  9846  
  9847    /**
  9848     * player's constructor function
  9849     *
  9850     * @constructs
  9851     * @method init
  9852     * @param {Element} tag        The original video tag used for configuring options
  9853     * @param {Object=} options    Player options
  9854     * @param {Function=} ready    Ready callback function
  9855     */
  9856  
  9857    function Player(tag, options, ready) {
  9858      var _this = this;
  9859  
  9860      _classCallCheck(this, Player);
  9861  
  9862      // Make sure tag ID exists
  9863      tag.id = tag.id || 'vjs_video_' + Guid.newGUID();
  9864  
  9865      // Set Options
  9866      // The options argument overrides options set in the video tag
  9867      // which overrides globally set options.
  9868      // This latter part coincides with the load order
  9869      // (tag must exist before Player)
  9870      options = _objectAssign2['default'](Player.getTagSettings(tag), options);
  9871  
  9872      // Delay the initialization of children because we need to set up
  9873      // player properties first, and can't use `this` before `super()`
  9874      options.initChildren = false;
  9875  
  9876      // Same with creating the element
  9877      options.createEl = false;
  9878  
  9879      // we don't want the player to report touch activity on itself
  9880      // see enableTouchActivity in Component
  9881      options.reportTouchActivity = false;
  9882  
  9883      // Run base component initializing with new options
  9884      _Component.call(this, null, options, ready);
  9885  
  9886      // if the global option object was accidentally blown away by
  9887      // someone, bail early with an informative error
  9888      if (!this.options_ || !this.options_.techOrder || !this.options_.techOrder.length) {
  9889        throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?');
  9890      }
  9891  
  9892      this.tag = tag; // Store the original tag used to set options
  9893  
  9894      // Store the tag attributes used to restore html5 element
  9895      this.tagAttributes = tag && Dom.getElAttributes(tag);
  9896  
  9897      // Update current language
  9898      this.language(this.options_.language);
  9899  
  9900      // Update Supported Languages
  9901      if (options.languages) {
  9902        (function () {
  9903          // Normalise player option languages to lowercase
  9904          var languagesToLower = {};
  9905  
  9906          Object.getOwnPropertyNames(options.languages).forEach(function (name) {
  9907            languagesToLower[name.toLowerCase()] = options.languages[name];
  9908          });
  9909          _this.languages_ = languagesToLower;
  9910        })();
  9911      } else {
  9912        this.languages_ = Player.prototype.options_.languages;
  9913      }
  9914  
  9915      // Cache for video property values.
  9916      this.cache_ = {};
  9917  
  9918      // Set poster
  9919      this.poster_ = options.poster || '';
  9920  
  9921      // Set controls
  9922      this.controls_ = !!options.controls;
  9923  
  9924      // Original tag settings stored in options
  9925      // now remove immediately so native controls don't flash.
  9926      // May be turned back on by HTML5 tech if nativeControlsForTouch is true
  9927      tag.controls = false;
  9928  
  9929      /*
  9930       * Store the internal state of scrubbing
  9931       *
  9932       * @private
  9933       * @return {Boolean} True if the user is scrubbing
  9934       */
  9935      this.scrubbing_ = false;
  9936  
  9937      this.el_ = this.createEl();
  9938  
  9939      // We also want to pass the original player options to each component and plugin
  9940      // as well so they don't need to reach back into the player for options later.
  9941      // We also need to do another copy of this.options_ so we don't end up with
  9942      // an infinite loop.
  9943      var playerOptionsCopy = _utilsMergeOptionsJs2['default'](this.options_);
  9944  
  9945      // Load plugins
  9946      if (options.plugins) {
  9947        (function () {
  9948          var plugins = options.plugins;
  9949  
  9950          Object.getOwnPropertyNames(plugins).forEach(function (name) {
  9951            if (typeof this[name] === 'function') {
  9952              this[name](plugins[name]);
  9953            } else {
  9954              _utilsLogJs2['default'].error('Unable to find plugin:', name);
  9955            }
  9956          }, _this);
  9957        })();
  9958      }
  9959  
  9960      this.options_.playerOptions = playerOptionsCopy;
  9961  
  9962      this.initChildren();
  9963  
  9964      // Set isAudio based on whether or not an audio tag was used
  9965      this.isAudio(tag.nodeName.toLowerCase() === 'audio');
  9966  
  9967      // Update controls className. Can't do this when the controls are initially
  9968      // set because the element doesn't exist yet.
  9969      if (this.controls()) {
  9970        this.addClass('vjs-controls-enabled');
  9971      } else {
  9972        this.addClass('vjs-controls-disabled');
  9973      }
  9974  
  9975      // Set ARIA label and region role depending on player type
  9976      this.el_.setAttribute('role', 'region');
  9977      if (this.isAudio()) {
  9978        this.el_.setAttribute('aria-label', 'audio player');
  9979      } else {
  9980        this.el_.setAttribute('aria-label', 'video player');
  9981      }
  9982  
  9983      if (this.isAudio()) {
  9984        this.addClass('vjs-audio');
  9985      }
  9986  
  9987      if (this.flexNotSupported_()) {
  9988        this.addClass('vjs-no-flex');
  9989      }
  9990  
  9991      // TODO: Make this smarter. Toggle user state between touching/mousing
  9992      // using events, since devices can have both touch and mouse events.
  9993      // if (browser.TOUCH_ENABLED) {
  9994      //   this.addClass('vjs-touch-enabled');
  9995      // }
  9996  
  9997      // iOS Safari has broken hover handling
  9998      if (!browser.IS_IOS) {
  9999        this.addClass('vjs-workinghover');
 10000      }
 10001  
 10002      // Make player easily findable by ID
 10003      Player.players[this.id_] = this;
 10004  
 10005      // When the player is first initialized, trigger activity so components
 10006      // like the control bar show themselves if needed
 10007      this.userActive(true);
 10008      this.reportUserActivity();
 10009      this.listenForUserActivity_();
 10010  
 10011      this.on('fullscreenchange', this.handleFullscreenChange_);
 10012      this.on('stageclick', this.handleStageClick_);
 10013    }
 10014  
 10015    /*
 10016     * Global player list
 10017     *
 10018     * @type {Object}
 10019     */
 10020  
 10021    /**
 10022     * Destroys the video player and does any necessary cleanup
 10023     * ```js
 10024     *     myPlayer.dispose();
 10025     * ```
 10026     * This is especially helpful if you are dynamically adding and removing videos
 10027     * to/from the DOM.
 10028     *
 10029     * @method dispose
 10030     */
 10031  
 10032    Player.prototype.dispose = function dispose() {
 10033      this.trigger('dispose');
 10034      // prevent dispose from being called twice
 10035      this.off('dispose');
 10036  
 10037      if (this.styleEl_ && this.styleEl_.parentNode) {
 10038        this.styleEl_.parentNode.removeChild(this.styleEl_);
 10039      }
 10040  
 10041      // Kill reference to this player
 10042      Player.players[this.id_] = null;
 10043      if (this.tag && this.tag.player) {
 10044        this.tag.player = null;
 10045      }
 10046      if (this.el_ && this.el_.player) {
 10047        this.el_.player = null;
 10048      }
 10049  
 10050      if (this.tech_) {
 10051        this.tech_.dispose();
 10052      }
 10053  
 10054      _Component.prototype.dispose.call(this);
 10055    };
 10056  
 10057    /**
 10058     * Create the component's DOM element
 10059     *
 10060     * @return {Element}
 10061     * @method createEl
 10062     */
 10063  
 10064    Player.prototype.createEl = function createEl() {
 10065      var el = this.el_ = _Component.prototype.createEl.call(this, 'div');
 10066      var tag = this.tag;
 10067  
 10068      // Remove width/height attrs from tag so CSS can make it 100% width/height
 10069      tag.removeAttribute('width');
 10070      tag.removeAttribute('height');
 10071  
 10072      // Copy over all the attributes from the tag, including ID and class
 10073      // ID will now reference player box, not the video tag
 10074      var attrs = Dom.getElAttributes(tag);
 10075  
 10076      Object.getOwnPropertyNames(attrs).forEach(function (attr) {
 10077        // workaround so we don't totally break IE7
 10078        // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7
 10079        if (attr === 'class') {
 10080          el.className = attrs[attr];
 10081        } else {
 10082          el.setAttribute(attr, attrs[attr]);
 10083        }
 10084      });
 10085  
 10086      // Update tag id/class for use as HTML5 playback tech
 10087      // Might think we should do this after embedding in container so .vjs-tech class
 10088      // doesn't flash 100% width/height, but class only applies with .video-js parent
 10089      tag.playerId = tag.id;
 10090      tag.id += '_html5_api';
 10091      tag.className = 'vjs-tech';
 10092  
 10093      // Make player findable on elements
 10094      tag.player = el.player = this;
 10095      // Default state of video is paused
 10096      this.addClass('vjs-paused');
 10097  
 10098      // Add a style element in the player that we'll use to set the width/height
 10099      // of the player in a way that's still overrideable by CSS, just like the
 10100      // video element
 10101      if (_globalWindow2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) {
 10102        this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions');
 10103        var defaultsStyleEl = Dom.$('.vjs-styles-defaults');
 10104        var head = Dom.$('head');
 10105        head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild);
 10106      }
 10107  
 10108      // Pass in the width/height/aspectRatio options which will update the style el
 10109      this.width(this.options_.width);
 10110      this.height(this.options_.height);
 10111      this.fluid(this.options_.fluid);
 10112      this.aspectRatio(this.options_.aspectRatio);
 10113  
 10114      // Hide any links within the video/audio tag, because IE doesn't hide them completely.
 10115      var links = tag.getElementsByTagName('a');
 10116      for (var i = 0; i < links.length; i++) {
 10117        var linkEl = links.item(i);
 10118        Dom.addElClass(linkEl, 'vjs-hidden');
 10119        linkEl.setAttribute('hidden', 'hidden');
 10120      }
 10121  
 10122      // insertElFirst seems to cause the networkState to flicker from 3 to 2, so
 10123      // keep track of the original for later so we can know if the source originally failed
 10124      tag.initNetworkState_ = tag.networkState;
 10125  
 10126      // Wrap video tag in div (el/box) container
 10127      if (tag.parentNode) {
 10128        tag.parentNode.insertBefore(el, tag);
 10129      }
 10130  
 10131      // insert the tag as the first child of the player element
 10132      // then manually add it to the children array so that this.addChild
 10133      // will work properly for other components
 10134      Dom.insertElFirst(tag, el); // Breaks iPhone, fixed in HTML5 setup.
 10135      this.children_.unshift(tag);
 10136  
 10137      this.el_ = el;
 10138  
 10139      return el;
 10140    };
 10141  
 10142    /**
 10143     * Get/set player width
 10144     *
 10145     * @param {Number=} value Value for width
 10146     * @return {Number} Width when getting
 10147     * @method width
 10148     */
 10149  
 10150    Player.prototype.width = function width(value) {
 10151      return this.dimension('width', value);
 10152    };
 10153  
 10154    /**
 10155     * Get/set player height
 10156     *
 10157     * @param {Number=} value Value for height
 10158     * @return {Number} Height when getting
 10159     * @method height
 10160     */
 10161  
 10162    Player.prototype.height = function height(value) {
 10163      return this.dimension('height', value);
 10164    };
 10165  
 10166    /**
 10167     * Get/set dimension for player
 10168     *
 10169     * @param {String} dimension Either width or height
 10170     * @param {Number=} value Value for dimension
 10171     * @return {Component}
 10172     * @method dimension
 10173     */
 10174  
 10175    Player.prototype.dimension = function dimension(_dimension, value) {
 10176      var privDimension = _dimension + '_';
 10177  
 10178      if (value === undefined) {
 10179        return this[privDimension] || 0;
 10180      }
 10181  
 10182      if (value === '') {
 10183        // If an empty string is given, reset the dimension to be automatic
 10184        this[privDimension] = undefined;
 10185      } else {
 10186        var parsedVal = parseFloat(value);
 10187  
 10188        if (isNaN(parsedVal)) {
 10189          _utilsLogJs2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension);
 10190          return this;
 10191        }
 10192  
 10193        this[privDimension] = parsedVal;
 10194      }
 10195  
 10196      this.updateStyleEl_();
 10197      return this;
 10198    };
 10199  
 10200    /**
 10201     * Add/remove the vjs-fluid class
 10202     *
 10203     * @param {Boolean} bool Value of true adds the class, value of false removes the class
 10204     * @method fluid
 10205     */
 10206  
 10207    Player.prototype.fluid = function fluid(bool) {
 10208      if (bool === undefined) {
 10209        return !!this.fluid_;
 10210      }
 10211  
 10212      this.fluid_ = !!bool;
 10213  
 10214      if (bool) {
 10215        this.addClass('vjs-fluid');
 10216      } else {
 10217        this.removeClass('vjs-fluid');
 10218      }
 10219    };
 10220  
 10221    /**
 10222     * Get/Set the aspect ratio
 10223     *
 10224     * @param {String=} ratio Aspect ratio for player
 10225     * @return aspectRatio
 10226     * @method aspectRatio
 10227     */
 10228  
 10229    Player.prototype.aspectRatio = function aspectRatio(ratio) {
 10230      if (ratio === undefined) {
 10231        return this.aspectRatio_;
 10232      }
 10233  
 10234      // Check for width:height format
 10235      if (!/^\d+\:\d+$/.test(ratio)) {
 10236        throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.');
 10237      }
 10238      this.aspectRatio_ = ratio;
 10239  
 10240      // We're assuming if you set an aspect ratio you want fluid mode,
 10241      // because in fixed mode you could calculate width and height yourself.
 10242      this.fluid(true);
 10243  
 10244      this.updateStyleEl_();
 10245    };
 10246  
 10247    /**
 10248     * Update styles of the player element (height, width and aspect ratio)
 10249     *
 10250     * @method updateStyleEl_
 10251     */
 10252  
 10253    Player.prototype.updateStyleEl_ = function updateStyleEl_() {
 10254      if (_globalWindow2['default'].VIDEOJS_NO_DYNAMIC_STYLE === true) {
 10255        var _width = typeof this.width_ === 'number' ? this.width_ : this.options_.width;
 10256        var _height = typeof this.height_ === 'number' ? this.height_ : this.options_.height;
 10257        var techEl = this.tech_ && this.tech_.el();
 10258  
 10259        if (techEl) {
 10260          if (_width >= 0) {
 10261            techEl.width = _width;
 10262          }
 10263          if (_height >= 0) {
 10264            techEl.height = _height;
 10265          }
 10266        }
 10267  
 10268        return;
 10269      }
 10270  
 10271      var width = undefined;
 10272      var height = undefined;
 10273      var aspectRatio = undefined;
 10274      var idClass = undefined;
 10275  
 10276      // The aspect ratio is either used directly or to calculate width and height.
 10277      if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') {
 10278        // Use any aspectRatio that's been specifically set
 10279        aspectRatio = this.aspectRatio_;
 10280      } else if (this.videoWidth()) {
 10281        // Otherwise try to get the aspect ratio from the video metadata
 10282        aspectRatio = this.videoWidth() + ':' + this.videoHeight();
 10283      } else {
 10284        // Or use a default. The video element's is 2:1, but 16:9 is more common.
 10285        aspectRatio = '16:9';
 10286      }
 10287  
 10288      // Get the ratio as a decimal we can use to calculate dimensions
 10289      var ratioParts = aspectRatio.split(':');
 10290      var ratioMultiplier = ratioParts[1] / ratioParts[0];
 10291  
 10292      if (this.width_ !== undefined) {
 10293        // Use any width that's been specifically set
 10294        width = this.width_;
 10295      } else if (this.height_ !== undefined) {
 10296        // Or calulate the width from the aspect ratio if a height has been set
 10297        width = this.height_ / ratioMultiplier;
 10298      } else {
 10299        // Or use the video's metadata, or use the video el's default of 300
 10300        width = this.videoWidth() || 300;
 10301      }
 10302  
 10303      if (this.height_ !== undefined) {
 10304        // Use any height that's been specifically set
 10305        height = this.height_;
 10306      } else {
 10307        // Otherwise calculate the height from the ratio and the width
 10308        height = width * ratioMultiplier;
 10309      }
 10310  
 10311      // Ensure the CSS class is valid by starting with an alpha character
 10312      if (/^[^a-zA-Z]/.test(this.id())) {
 10313        idClass = 'dimensions-' + this.id();
 10314      } else {
 10315        idClass = this.id() + '-dimensions';
 10316      }
 10317  
 10318      // Ensure the right class is still on the player for the style element
 10319      this.addClass(idClass);
 10320  
 10321      stylesheet.setTextContent(this.styleEl_, '\n      .' + idClass + ' {\n        width: ' + width + 'px;\n        height: ' + height + 'px;\n      }\n\n      .' + idClass + '.vjs-fluid {\n        padding-top: ' + ratioMultiplier * 100 + '%;\n      }\n    ');
 10322    };
 10323  
 10324    /**
 10325     * Load the Media Playback Technology (tech)
 10326     * Load/Create an instance of playback technology including element and API methods
 10327     * And append playback element in player div.
 10328     *
 10329     * @param {String} techName Name of the playback technology
 10330     * @param {String} source Video source
 10331     * @method loadTech_
 10332     * @private
 10333     */
 10334  
 10335    Player.prototype.loadTech_ = function loadTech_(techName, source) {
 10336  
 10337      // Pause and remove current playback technology
 10338      if (this.tech_) {
 10339        this.unloadTech_();
 10340      }
 10341  
 10342      // get rid of the HTML5 video tag as soon as we are using another tech
 10343      if (techName !== 'Html5' && this.tag) {
 10344        _techTechJs2['default'].getTech('Html5').disposeMediaElement(this.tag);
 10345        this.tag.player = null;
 10346        this.tag = null;
 10347      }
 10348  
 10349      this.techName_ = techName;
 10350  
 10351      // Turn off API access because we're loading a new tech that might load asynchronously
 10352      this.isReady_ = false;
 10353  
 10354      // Grab tech-specific options from player options and add source and parent element to use.
 10355      var techOptions = _objectAssign2['default']({
 10356        'nativeControlsForTouch': this.options_.nativeControlsForTouch,
 10357        'source': source,
 10358        'playerId': this.id(),
 10359        'techId': this.id() + '_' + techName + '_api',
 10360        'textTracks': this.textTracks_,
 10361        'autoplay': this.options_.autoplay,
 10362        'preload': this.options_.preload,
 10363        'loop': this.options_.loop,
 10364        'muted': this.options_.muted,
 10365        'poster': this.poster(),
 10366        'language': this.language(),
 10367        'vtt.js': this.options_['vtt.js']
 10368      }, this.options_[techName.toLowerCase()]);
 10369  
 10370      if (this.tag) {
 10371        techOptions.tag = this.tag;
 10372      }
 10373  
 10374      if (source) {
 10375        this.currentType_ = source.type;
 10376        if (source.src === this.cache_.src && this.cache_.currentTime > 0) {
 10377          techOptions.startTime = this.cache_.currentTime;
 10378        }
 10379  
 10380        this.cache_.src = source.src;
 10381      }
 10382  
 10383      // Initialize tech instance
 10384      var techComponent = _techTechJs2['default'].getTech(techName);
 10385      // Support old behavior of techs being registered as components.
 10386      // Remove once that deprecated behavior is removed.
 10387      if (!techComponent) {
 10388        techComponent = _componentJs2['default'].getComponent(techName);
 10389      }
 10390      this.tech_ = new techComponent(techOptions);
 10391  
 10392      // player.triggerReady is always async, so don't need this to be async
 10393      this.tech_.ready(Fn.bind(this, this.handleTechReady_), true);
 10394  
 10395      _tracksTextTrackListConverterJs2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_);
 10396  
 10397      // Listen to all HTML5-defined events and trigger them on the player
 10398      this.on(this.tech_, 'loadstart', this.handleTechLoadStart_);
 10399      this.on(this.tech_, 'waiting', this.handleTechWaiting_);
 10400      this.on(this.tech_, 'canplay', this.handleTechCanPlay_);
 10401      this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_);
 10402      this.on(this.tech_, 'playing', this.handleTechPlaying_);
 10403      this.on(this.tech_, 'ended', this.handleTechEnded_);
 10404      this.on(this.tech_, 'seeking', this.handleTechSeeking_);
 10405      this.on(this.tech_, 'seeked', this.handleTechSeeked_);
 10406      this.on(this.tech_, 'play', this.handleTechPlay_);
 10407      this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_);
 10408      this.on(this.tech_, 'pause', this.handleTechPause_);
 10409      this.on(this.tech_, 'progress', this.handleTechProgress_);
 10410      this.on(this.tech_, 'durationchange', this.handleTechDurationChange_);
 10411      this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_);
 10412      this.on(this.tech_, 'error', this.handleTechError_);
 10413      this.on(this.tech_, 'suspend', this.handleTechSuspend_);
 10414      this.on(this.tech_, 'abort', this.handleTechAbort_);
 10415      this.on(this.tech_, 'emptied', this.handleTechEmptied_);
 10416      this.on(this.tech_, 'stalled', this.handleTechStalled_);
 10417      this.on(this.tech_, 'loadedmetadata', this.handleTechLoadedMetaData_);
 10418      this.on(this.tech_, 'loadeddata', this.handleTechLoadedData_);
 10419      this.on(this.tech_, 'timeupdate', this.handleTechTimeUpdate_);
 10420      this.on(this.tech_, 'ratechange', this.handleTechRateChange_);
 10421      this.on(this.tech_, 'volumechange', this.handleTechVolumeChange_);
 10422      this.on(this.tech_, 'texttrackchange', this.handleTechTextTrackChange_);
 10423      this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_);
 10424      this.on(this.tech_, 'posterchange', this.handleTechPosterChange_);
 10425  
 10426      this.usingNativeControls(this.techGet_('controls'));
 10427  
 10428      if (this.controls() && !this.usingNativeControls()) {
 10429        this.addTechControlsListeners_();
 10430      }
 10431  
 10432      // Add the tech element in the DOM if it was not already there
 10433      // Make sure to not insert the original video element if using Html5
 10434      if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) {
 10435        Dom.insertElFirst(this.tech_.el(), this.el());
 10436      }
 10437  
 10438      // Get rid of the original video tag reference after the first tech is loaded
 10439      if (this.tag) {
 10440        this.tag.player = null;
 10441        this.tag = null;
 10442      }
 10443    };
 10444  
 10445    /**
 10446     * Unload playback technology
 10447     *
 10448     * @method unloadTech_
 10449     * @private
 10450     */
 10451  
 10452    Player.prototype.unloadTech_ = function unloadTech_() {
 10453      // Save the current text tracks so that we can reuse the same text tracks with the next tech
 10454      this.textTracks_ = this.textTracks();
 10455      this.textTracksJson_ = _tracksTextTrackListConverterJs2['default'].textTracksToJson(this.tech_);
 10456  
 10457      this.isReady_ = false;
 10458  
 10459      this.tech_.dispose();
 10460  
 10461      this.tech_ = false;
 10462    };
 10463  
 10464    /**
 10465     * Return a reference to the current tech.
 10466     * It will only return a reference to the tech if given an object with the
 10467     * `IWillNotUseThisInPlugins` property on it. This is try and prevent misuse
 10468     * of techs by plugins.
 10469     *
 10470     * @param {Object}
 10471     * @return {Object} The Tech
 10472     * @method tech
 10473     */
 10474  
 10475    Player.prototype.tech = function tech(safety) {
 10476      if (safety && safety.IWillNotUseThisInPlugins) {
 10477        return this.tech_;
 10478      }
 10479      var errorText = '\n      Please make sure that you are not using this inside of a plugin.\n      To disable this alert and error, please pass in an object with\n      `IWillNotUseThisInPlugins` to the `tech` method. See\n      https://github.com/videojs/video.js/issues/2617 for more info.\n    ';
 10480      _globalWindow2['default'].alert(errorText);
 10481      throw new Error(errorText);
 10482    };
 10483  
 10484    /**
 10485     * Set up click and touch listeners for the playback element
 10486     *
 10487     * On desktops, a click on the video itself will toggle playback,
 10488     * on a mobile device a click on the video toggles controls.
 10489     * (toggling controls is done by toggling the user state between active and
 10490     * inactive)
 10491     * A tap can signal that a user has become active, or has become inactive
 10492     * e.g. a quick tap on an iPhone movie should reveal the controls. Another
 10493     * quick tap should hide them again (signaling the user is in an inactive
 10494     * viewing state)
 10495     * In addition to this, we still want the user to be considered inactive after
 10496     * a few seconds of inactivity.
 10497     * Note: the only part of iOS interaction we can't mimic with this setup
 10498     * is a touch and hold on the video element counting as activity in order to
 10499     * keep the controls showing, but that shouldn't be an issue. A touch and hold
 10500     * on any controls will still keep the user active
 10501     *
 10502     * @private
 10503     * @method addTechControlsListeners_
 10504     */
 10505  
 10506    Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() {
 10507      // Make sure to remove all the previous listeners in case we are called multiple times.
 10508      this.removeTechControlsListeners_();
 10509  
 10510      // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
 10511      // trigger mousedown/up.
 10512      // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object
 10513      // Any touch events are set to block the mousedown event from happening
 10514      this.on(this.tech_, 'mousedown', this.handleTechClick_);
 10515  
 10516      // If the controls were hidden we don't want that to change without a tap event
 10517      // so we'll check if the controls were already showing before reporting user
 10518      // activity
 10519      this.on(this.tech_, 'touchstart', this.handleTechTouchStart_);
 10520      this.on(this.tech_, 'touchmove', this.handleTechTouchMove_);
 10521      this.on(this.tech_, 'touchend', this.handleTechTouchEnd_);
 10522  
 10523      // The tap listener needs to come after the touchend listener because the tap
 10524      // listener cancels out any reportedUserActivity when setting userActive(false)
 10525      this.on(this.tech_, 'tap', this.handleTechTap_);
 10526    };
 10527  
 10528    /**
 10529     * Remove the listeners used for click and tap controls. This is needed for
 10530     * toggling to controls disabled, where a tap/touch should do nothing.
 10531     *
 10532     * @method removeTechControlsListeners_
 10533     * @private
 10534     */
 10535  
 10536    Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() {
 10537      // We don't want to just use `this.off()` because there might be other needed
 10538      // listeners added by techs that extend this.
 10539      this.off(this.tech_, 'tap', this.handleTechTap_);
 10540      this.off(this.tech_, 'touchstart', this.handleTechTouchStart_);
 10541      this.off(this.tech_, 'touchmove', this.handleTechTouchMove_);
 10542      this.off(this.tech_, 'touchend', this.handleTechTouchEnd_);
 10543      this.off(this.tech_, 'mousedown', this.handleTechClick_);
 10544    };
 10545  
 10546    /**
 10547     * Player waits for the tech to be ready
 10548     *
 10549     * @method handleTechReady_
 10550     * @private
 10551     */
 10552  
 10553    Player.prototype.handleTechReady_ = function handleTechReady_() {
 10554      this.triggerReady();
 10555  
 10556      // Keep the same volume as before
 10557      if (this.cache_.volume) {
 10558        this.techCall_('setVolume', this.cache_.volume);
 10559      }
 10560  
 10561      // Look if the tech found a higher resolution poster while loading
 10562      this.handleTechPosterChange_();
 10563  
 10564      // Update the duration if available
 10565      this.handleTechDurationChange_();
 10566  
 10567      // Chrome and Safari both have issues with autoplay.
 10568      // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
 10569      // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
 10570      // This fixes both issues. Need to wait for API, so it updates displays correctly
 10571      if (this.src() && this.tag && this.options_.autoplay && this.paused()) {
 10572        delete this.tag.poster; // Chrome Fix. Fixed in Chrome v16.
 10573        this.play();
 10574      }
 10575    };
 10576  
 10577    /**
 10578     * Fired when the user agent begins looking for media data
 10579     *
 10580     * @private
 10581     * @method handleTechLoadStart_
 10582     */
 10583  
 10584    Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() {
 10585      // TODO: Update to use `emptied` event instead. See #1277.
 10586  
 10587      this.removeClass('vjs-ended');
 10588  
 10589      // reset the error state
 10590      this.error(null);
 10591  
 10592      // If it's already playing we want to trigger a firstplay event now.
 10593      // The firstplay event relies on both the play and loadstart events
 10594      // which can happen in any order for a new source
 10595      if (!this.paused()) {
 10596        this.trigger('loadstart');
 10597        this.trigger('firstplay');
 10598      } else {
 10599        // reset the hasStarted state
 10600        this.hasStarted(false);
 10601        this.trigger('loadstart');
 10602      }
 10603    };
 10604  
 10605    /**
 10606     * Add/remove the vjs-has-started class
 10607     *
 10608     * @param {Boolean} hasStarted The value of true adds the class the value of false remove the class
 10609     * @return {Boolean} Boolean value if has started
 10610     * @private
 10611     * @method hasStarted
 10612     */
 10613  
 10614    Player.prototype.hasStarted = function hasStarted(_hasStarted) {
 10615      if (_hasStarted !== undefined) {
 10616        // only update if this is a new value
 10617        if (this.hasStarted_ !== _hasStarted) {
 10618          this.hasStarted_ = _hasStarted;
 10619          if (_hasStarted) {
 10620            this.addClass('vjs-has-started');
 10621            // trigger the firstplay event if this newly has played
 10622            this.trigger('firstplay');
 10623          } else {
 10624            this.removeClass('vjs-has-started');
 10625          }
 10626        }
 10627        return this;
 10628      }
 10629      return !!this.hasStarted_;
 10630    };
 10631  
 10632    /**
 10633     * Fired whenever the media begins or resumes playback
 10634     *
 10635     * @private
 10636     * @method handleTechPlay_
 10637     */
 10638  
 10639    Player.prototype.handleTechPlay_ = function handleTechPlay_() {
 10640      this.removeClass('vjs-ended');
 10641      this.removeClass('vjs-paused');
 10642      this.addClass('vjs-playing');
 10643  
 10644      // hide the poster when the user hits play
 10645      // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play
 10646      this.hasStarted(true);
 10647  
 10648      this.trigger('play');
 10649    };
 10650  
 10651    /**
 10652     * Fired whenever the media begins waiting
 10653     *
 10654     * @private
 10655     * @method handleTechWaiting_
 10656     */
 10657  
 10658    Player.prototype.handleTechWaiting_ = function handleTechWaiting_() {
 10659      var _this2 = this;
 10660  
 10661      this.addClass('vjs-waiting');
 10662      this.trigger('waiting');
 10663      this.one('timeupdate', function () {
 10664        return _this2.removeClass('vjs-waiting');
 10665      });
 10666    };
 10667  
 10668    /**
 10669     * A handler for events that signal that waiting has ended
 10670     * which is not consistent between browsers. See #1351
 10671     *
 10672     * @private
 10673     * @method handleTechCanPlay_
 10674     */
 10675  
 10676    Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() {
 10677      this.removeClass('vjs-waiting');
 10678      this.trigger('canplay');
 10679    };
 10680  
 10681    /**
 10682     * A handler for events that signal that waiting has ended
 10683     * which is not consistent between browsers. See #1351
 10684     *
 10685     * @private
 10686     * @method handleTechCanPlayThrough_
 10687     */
 10688  
 10689    Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() {
 10690      this.removeClass('vjs-waiting');
 10691      this.trigger('canplaythrough');
 10692    };
 10693  
 10694    /**
 10695     * A handler for events that signal that waiting has ended
 10696     * which is not consistent between browsers. See #1351
 10697     *
 10698     * @private
 10699     * @method handleTechPlaying_
 10700     */
 10701  
 10702    Player.prototype.handleTechPlaying_ = function handleTechPlaying_() {
 10703      this.removeClass('vjs-waiting');
 10704      this.trigger('playing');
 10705    };
 10706  
 10707    /**
 10708     * Fired whenever the player is jumping to a new time
 10709     *
 10710     * @private
 10711     * @method handleTechSeeking_
 10712     */
 10713  
 10714    Player.prototype.handleTechSeeking_ = function handleTechSeeking_() {
 10715      this.addClass('vjs-seeking');
 10716      this.trigger('seeking');
 10717    };
 10718  
 10719    /**
 10720     * Fired when the player has finished jumping to a new time
 10721     *
 10722     * @private
 10723     * @method handleTechSeeked_
 10724     */
 10725  
 10726    Player.prototype.handleTechSeeked_ = function handleTechSeeked_() {
 10727      this.removeClass('vjs-seeking');
 10728      this.trigger('seeked');
 10729    };
 10730  
 10731    /**
 10732     * Fired the first time a video is played
 10733     * Not part of the HLS spec, and we're not sure if this is the best
 10734     * implementation yet, so use sparingly. If you don't have a reason to
 10735     * prevent playback, use `myPlayer.one('play');` instead.
 10736     *
 10737     * @private
 10738     * @method handleTechFirstPlay_
 10739     */
 10740  
 10741    Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() {
 10742      //If the first starttime attribute is specified
 10743      //then we will start at the given offset in seconds
 10744      if (this.options_.starttime) {
 10745        this.currentTime(this.options_.starttime);
 10746      }
 10747  
 10748      this.addClass('vjs-has-started');
 10749      this.trigger('firstplay');
 10750    };
 10751  
 10752    /**
 10753     * Fired whenever the media has been paused
 10754     *
 10755     * @private
 10756     * @method handleTechPause_
 10757     */
 10758  
 10759    Player.prototype.handleTechPause_ = function handleTechPause_() {
 10760      this.removeClass('vjs-playing');
 10761      this.addClass('vjs-paused');
 10762      this.trigger('pause');
 10763    };
 10764  
 10765    /**
 10766     * Fired while the user agent is downloading media data
 10767     *
 10768     * @private
 10769     * @method handleTechProgress_
 10770     */
 10771  
 10772    Player.prototype.handleTechProgress_ = function handleTechProgress_() {
 10773      this.trigger('progress');
 10774    };
 10775  
 10776    /**
 10777     * Fired when the end of the media resource is reached (currentTime == duration)
 10778     *
 10779     * @private
 10780     * @method handleTechEnded_
 10781     */
 10782  
 10783    Player.prototype.handleTechEnded_ = function handleTechEnded_() {
 10784      this.addClass('vjs-ended');
 10785      if (this.options_.loop) {
 10786        this.currentTime(0);
 10787        this.play();
 10788      } else if (!this.paused()) {
 10789        this.pause();
 10790      }
 10791  
 10792      this.trigger('ended');
 10793    };
 10794  
 10795    /**
 10796     * Fired when the duration of the media resource is first known or changed
 10797     *
 10798     * @private
 10799     * @method handleTechDurationChange_
 10800     */
 10801  
 10802    Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() {
 10803      this.duration(this.techGet_('duration'));
 10804    };
 10805  
 10806    /**
 10807     * Handle a click on the media element to play/pause
 10808     *
 10809     * @param {Object=} event Event object
 10810     * @private
 10811     * @method handleTechClick_
 10812     */
 10813  
 10814    Player.prototype.handleTechClick_ = function handleTechClick_(event) {
 10815      // We're using mousedown to detect clicks thanks to Flash, but mousedown
 10816      // will also be triggered with right-clicks, so we need to prevent that
 10817      if (event.button !== 0) return;
 10818  
 10819      // When controls are disabled a click should not toggle playback because
 10820      // the click is considered a control
 10821      if (this.controls()) {
 10822        if (this.paused()) {
 10823          this.play();
 10824        } else {
 10825          this.pause();
 10826        }
 10827      }
 10828    };
 10829  
 10830    /**
 10831     * Handle a tap on the media element. It will toggle the user
 10832     * activity state, which hides and shows the controls.
 10833     *
 10834     * @private
 10835     * @method handleTechTap_
 10836     */
 10837  
 10838    Player.prototype.handleTechTap_ = function handleTechTap_() {
 10839      this.userActive(!this.userActive());
 10840    };
 10841  
 10842    /**
 10843     * Handle touch to start
 10844     *
 10845     * @private
 10846     * @method handleTechTouchStart_
 10847     */
 10848  
 10849    Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() {
 10850      this.userWasActive = this.userActive();
 10851    };
 10852  
 10853    /**
 10854     * Handle touch to move
 10855     *
 10856     * @private
 10857     * @method handleTechTouchMove_
 10858     */
 10859  
 10860    Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() {
 10861      if (this.userWasActive) {
 10862        this.reportUserActivity();
 10863      }
 10864    };
 10865  
 10866    /**
 10867     * Handle touch to end
 10868     *
 10869     * @private
 10870     * @method handleTechTouchEnd_
 10871     */
 10872  
 10873    Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) {
 10874      // Stop the mouse events from also happening
 10875      event.preventDefault();
 10876    };
 10877  
 10878    /**
 10879     * Fired when the player switches in or out of fullscreen mode
 10880     *
 10881     * @private
 10882     * @method handleFullscreenChange_
 10883     */
 10884  
 10885    Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() {
 10886      if (this.isFullscreen()) {
 10887        this.addClass('vjs-fullscreen');
 10888      } else {
 10889        this.removeClass('vjs-fullscreen');
 10890      }
 10891    };
 10892  
 10893    /**
 10894     * native click events on the SWF aren't triggered on IE11, Win8.1RT
 10895     * use stageclick events triggered from inside the SWF instead
 10896     *
 10897     * @private
 10898     * @method handleStageClick_
 10899     */
 10900  
 10901    Player.prototype.handleStageClick_ = function handleStageClick_() {
 10902      this.reportUserActivity();
 10903    };
 10904  
 10905    /**
 10906     * Handle Tech Fullscreen Change
 10907     *
 10908     * @private
 10909     * @method handleTechFullscreenChange_
 10910     */
 10911  
 10912    Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) {
 10913      if (data) {
 10914        this.isFullscreen(data.isFullscreen);
 10915      }
 10916      this.trigger('fullscreenchange');
 10917    };
 10918  
 10919    /**
 10920     * Fires when an error occurred during the loading of an audio/video
 10921     *
 10922     * @private
 10923     * @method handleTechError_
 10924     */
 10925  
 10926    Player.prototype.handleTechError_ = function handleTechError_() {
 10927      var error = this.tech_.error();
 10928      this.error(error && error.code);
 10929    };
 10930  
 10931    /**
 10932     * Fires when the browser is intentionally not getting media data
 10933     *
 10934     * @private
 10935     * @method handleTechSuspend_
 10936     */
 10937  
 10938    Player.prototype.handleTechSuspend_ = function handleTechSuspend_() {
 10939      this.trigger('suspend');
 10940    };
 10941  
 10942    /**
 10943     * Fires when the loading of an audio/video is aborted
 10944     *
 10945     * @private
 10946     * @method handleTechAbort_
 10947     */
 10948  
 10949    Player.prototype.handleTechAbort_ = function handleTechAbort_() {
 10950      this.trigger('abort');
 10951    };
 10952  
 10953    /**
 10954     * Fires when the current playlist is empty
 10955     *
 10956     * @private
 10957     * @method handleTechEmptied_
 10958     */
 10959  
 10960    Player.prototype.handleTechEmptied_ = function handleTechEmptied_() {
 10961      this.trigger('emptied');
 10962    };
 10963  
 10964    /**
 10965     * Fires when the browser is trying to get media data, but data is not available
 10966     *
 10967     * @private
 10968     * @method handleTechStalled_
 10969     */
 10970  
 10971    Player.prototype.handleTechStalled_ = function handleTechStalled_() {
 10972      this.trigger('stalled');
 10973    };
 10974  
 10975    /**
 10976     * Fires when the browser has loaded meta data for the audio/video
 10977     *
 10978     * @private
 10979     * @method handleTechLoadedMetaData_
 10980     */
 10981  
 10982    Player.prototype.handleTechLoadedMetaData_ = function handleTechLoadedMetaData_() {
 10983      this.trigger('loadedmetadata');
 10984    };
 10985  
 10986    /**
 10987     * Fires when the browser has loaded the current frame of the audio/video
 10988     *
 10989     * @private
 10990     * @method handleTechLoadedData_
 10991     */
 10992  
 10993    Player.prototype.handleTechLoadedData_ = function handleTechLoadedData_() {
 10994      this.trigger('loadeddata');
 10995    };
 10996  
 10997    /**
 10998     * Fires when the current playback position has changed
 10999     *
 11000     * @private
 11001     * @method handleTechTimeUpdate_
 11002     */
 11003  
 11004    Player.prototype.handleTechTimeUpdate_ = function handleTechTimeUpdate_() {
 11005      this.trigger('timeupdate');
 11006    };
 11007  
 11008    /**
 11009     * Fires when the playing speed of the audio/video is changed
 11010     *
 11011     * @private
 11012     * @method handleTechRateChange_
 11013     */
 11014  
 11015    Player.prototype.handleTechRateChange_ = function handleTechRateChange_() {
 11016      this.trigger('ratechange');
 11017    };
 11018  
 11019    /**
 11020     * Fires when the volume has been changed
 11021     *
 11022     * @private
 11023     * @method handleTechVolumeChange_
 11024     */
 11025  
 11026    Player.prototype.handleTechVolumeChange_ = function handleTechVolumeChange_() {
 11027      this.trigger('volumechange');
 11028    };
 11029  
 11030    /**
 11031     * Fires when the text track has been changed
 11032     *
 11033     * @private
 11034     * @method handleTechTextTrackChange_
 11035     */
 11036  
 11037    Player.prototype.handleTechTextTrackChange_ = function handleTechTextTrackChange_() {
 11038      this.trigger('texttrackchange');
 11039    };
 11040  
 11041    /**
 11042     * Get object for cached values.
 11043     *
 11044     * @return {Object}
 11045     * @method getCache
 11046     */
 11047  
 11048    Player.prototype.getCache = function getCache() {
 11049      return this.cache_;
 11050    };
 11051  
 11052    /**
 11053     * Pass values to the playback tech
 11054     *
 11055     * @param {String=} method Method
 11056     * @param {Object=} arg Argument
 11057     * @private
 11058     * @method techCall_
 11059     */
 11060  
 11061    Player.prototype.techCall_ = function techCall_(method, arg) {
 11062      // If it's not ready yet, call method when it is
 11063      if (this.tech_ && !this.tech_.isReady_) {
 11064        this.tech_.ready(function () {
 11065          this[method](arg);
 11066        }, true);
 11067  
 11068        // Otherwise call method now
 11069      } else {
 11070          try {
 11071            this.tech_[method](arg);
 11072          } catch (e) {
 11073            _utilsLogJs2['default'](e);
 11074            throw e;
 11075          }
 11076        }
 11077    };
 11078  
 11079    /**
 11080     * Get calls can't wait for the tech, and sometimes don't need to.
 11081     *
 11082     * @param {String} method Tech method
 11083     * @return {Method}
 11084     * @private
 11085     * @method techGet_
 11086     */
 11087  
 11088    Player.prototype.techGet_ = function techGet_(method) {
 11089      if (this.tech_ && this.tech_.isReady_) {
 11090  
 11091        // Flash likes to die and reload when you hide or reposition it.
 11092        // In these cases the object methods go away and we get errors.
 11093        // When that happens we'll catch the errors and inform tech that it's not ready any more.
 11094        try {
 11095          return this.tech_[method]();
 11096        } catch (e) {
 11097          // When building additional tech libs, an expected method may not be defined yet
 11098          if (this.tech_[method] === undefined) {
 11099            _utilsLogJs2['default']('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e);
 11100          } else {
 11101            // When a method isn't available on the object it throws a TypeError
 11102            if (e.name === 'TypeError') {
 11103              _utilsLogJs2['default']('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e);
 11104              this.tech_.isReady_ = false;
 11105            } else {
 11106              _utilsLogJs2['default'](e);
 11107            }
 11108          }
 11109          throw e;
 11110        }
 11111      }
 11112  
 11113      return;
 11114    };
 11115  
 11116    /**
 11117     * start media playback
 11118     * ```js
 11119     *     myPlayer.play();
 11120     * ```
 11121     *
 11122     * @return {Player} self
 11123     * @method play
 11124     */
 11125  
 11126    Player.prototype.play = function play() {
 11127      this.techCall_('play');
 11128      return this;
 11129    };
 11130  
 11131    /**
 11132     * Pause the video playback
 11133     * ```js
 11134     *     myPlayer.pause();
 11135     * ```
 11136     *
 11137     * @return {Player} self
 11138     * @method pause
 11139     */
 11140  
 11141    Player.prototype.pause = function pause() {
 11142      this.techCall_('pause');
 11143      return this;
 11144    };
 11145  
 11146    /**
 11147     * Check if the player is paused
 11148     * ```js
 11149     *     var isPaused = myPlayer.paused();
 11150     *     var isPlaying = !myPlayer.paused();
 11151     * ```
 11152     *
 11153     * @return {Boolean} false if the media is currently playing, or true otherwise
 11154     * @method paused
 11155     */
 11156  
 11157    Player.prototype.paused = function paused() {
 11158      // The initial state of paused should be true (in Safari it's actually false)
 11159      return this.techGet_('paused') === false ? false : true;
 11160    };
 11161  
 11162    /**
 11163     * Returns whether or not the user is "scrubbing". Scrubbing is when the user
 11164     * has clicked the progress bar handle and is dragging it along the progress bar.
 11165     *
 11166     * @param  {Boolean} isScrubbing   True/false the user is scrubbing
 11167     * @return {Boolean}               The scrubbing status when getting
 11168     * @return {Object}                The player when setting
 11169     * @method scrubbing
 11170     */
 11171  
 11172    Player.prototype.scrubbing = function scrubbing(isScrubbing) {
 11173      if (isScrubbing !== undefined) {
 11174        this.scrubbing_ = !!isScrubbing;
 11175  
 11176        if (isScrubbing) {
 11177          this.addClass('vjs-scrubbing');
 11178        } else {
 11179          this.removeClass('vjs-scrubbing');
 11180        }
 11181  
 11182        return this;
 11183      }
 11184  
 11185      return this.scrubbing_;
 11186    };
 11187  
 11188    /**
 11189     * Get or set the current time (in seconds)
 11190     * ```js
 11191     *     // get
 11192     *     var whereYouAt = myPlayer.currentTime();
 11193     *     // set
 11194     *     myPlayer.currentTime(120); // 2 minutes into the video
 11195     * ```
 11196     *
 11197     * @param  {Number|String=} seconds The time to seek to
 11198     * @return {Number}        The time in seconds, when not setting
 11199     * @return {Player}    self, when the current time is set
 11200     * @method currentTime
 11201     */
 11202  
 11203    Player.prototype.currentTime = function currentTime(seconds) {
 11204      if (seconds !== undefined) {
 11205  
 11206        this.techCall_('setCurrentTime', seconds);
 11207  
 11208        return this;
 11209      }
 11210  
 11211      // cache last currentTime and return. default to 0 seconds
 11212      //
 11213      // Caching the currentTime is meant to prevent a massive amount of reads on the tech's
 11214      // currentTime when scrubbing, but may not provide much performance benefit afterall.
 11215      // Should be tested. Also something has to read the actual current time or the cache will
 11216      // never get updated.
 11217      return this.cache_.currentTime = this.techGet_('currentTime') || 0;
 11218    };
 11219  
 11220    /**
 11221     * Get the length in time of the video in seconds
 11222     * ```js
 11223     *     var lengthOfVideo = myPlayer.duration();
 11224     * ```
 11225     * **NOTE**: The video must have started loading before the duration can be
 11226     * known, and in the case of Flash, may not be known until the video starts
 11227     * playing.
 11228     *
 11229     * @param {Number} seconds Duration when setting
 11230     * @return {Number} The duration of the video in seconds when getting
 11231     * @method duration
 11232     */
 11233  
 11234    Player.prototype.duration = function duration(seconds) {
 11235      if (seconds === undefined) {
 11236        return this.cache_.duration || 0;
 11237      }
 11238  
 11239      seconds = parseFloat(seconds) || 0;
 11240  
 11241      // Standardize on Inifity for signaling video is live
 11242      if (seconds < 0) {
 11243        seconds = Infinity;
 11244      }
 11245  
 11246      if (seconds !== this.cache_.duration) {
 11247        // Cache the last set value for optimized scrubbing (esp. Flash)
 11248        this.cache_.duration = seconds;
 11249  
 11250        if (seconds === Infinity) {
 11251          this.addClass('vjs-live');
 11252        } else {
 11253          this.removeClass('vjs-live');
 11254        }
 11255  
 11256        this.trigger('durationchange');
 11257      }
 11258  
 11259      return this;
 11260    };
 11261  
 11262    /**
 11263     * Calculates how much time is left.
 11264     * ```js
 11265     *     var timeLeft = myPlayer.remainingTime();
 11266     * ```
 11267     * Not a native video element function, but useful
 11268     *
 11269     * @return {Number} The time remaining in seconds
 11270     * @method remainingTime
 11271     */
 11272  
 11273    Player.prototype.remainingTime = function remainingTime() {
 11274      return this.duration() - this.currentTime();
 11275    };
 11276  
 11277    // http://dev.w3.org/html5/spec/video.html#dom-media-buffered
 11278    // Buffered returns a timerange object.
 11279    // Kind of like an array of portions of the video that have been downloaded.
 11280  
 11281    /**
 11282     * Get a TimeRange object with the times of the video that have been downloaded
 11283     * If you just want the percent of the video that's been downloaded,
 11284     * use bufferedPercent.
 11285     * ```js
 11286     *     // Number of different ranges of time have been buffered. Usually 1.
 11287     *     numberOfRanges = bufferedTimeRange.length,
 11288     *     // Time in seconds when the first range starts. Usually 0.
 11289     *     firstRangeStart = bufferedTimeRange.start(0),
 11290     *     // Time in seconds when the first range ends
 11291     *     firstRangeEnd = bufferedTimeRange.end(0),
 11292     *     // Length in seconds of the first time range
 11293     *     firstRangeLength = firstRangeEnd - firstRangeStart;
 11294     * ```
 11295     *
 11296     * @return {Object} A mock TimeRange object (following HTML spec)
 11297     * @method buffered
 11298     */
 11299  
 11300    Player.prototype.buffered = function buffered() {
 11301      var buffered = this.techGet_('buffered');
 11302  
 11303      if (!buffered || !buffered.length) {
 11304        buffered = _utilsTimeRangesJs.createTimeRange(0, 0);
 11305      }
 11306  
 11307      return buffered;
 11308    };
 11309  
 11310    /**
 11311     * Get the percent (as a decimal) of the video that's been downloaded
 11312     * ```js
 11313     *     var howMuchIsDownloaded = myPlayer.bufferedPercent();
 11314     * ```
 11315     * 0 means none, 1 means all.
 11316     * (This method isn't in the HTML5 spec, but it's very convenient)
 11317     *
 11318     * @return {Number} A decimal between 0 and 1 representing the percent
 11319     * @method bufferedPercent
 11320     */
 11321  
 11322    Player.prototype.bufferedPercent = function bufferedPercent() {
 11323      return _utilsBufferJs.bufferedPercent(this.buffered(), this.duration());
 11324    };
 11325  
 11326    /**
 11327     * Get the ending time of the last buffered time range
 11328     * This is used in the progress bar to encapsulate all time ranges.
 11329     *
 11330     * @return {Number} The end of the last buffered time range
 11331     * @method bufferedEnd
 11332     */
 11333  
 11334    Player.prototype.bufferedEnd = function bufferedEnd() {
 11335      var buffered = this.buffered(),
 11336          duration = this.duration(),
 11337          end = buffered.end(buffered.length - 1);
 11338  
 11339      if (end > duration) {
 11340        end = duration;
 11341      }
 11342  
 11343      return end;
 11344    };
 11345  
 11346    /**
 11347     * Get or set the current volume of the media
 11348     * ```js
 11349     *     // get
 11350     *     var howLoudIsIt = myPlayer.volume();
 11351     *     // set
 11352     *     myPlayer.volume(0.5); // Set volume to half
 11353     * ```
 11354     * 0 is off (muted), 1.0 is all the way up, 0.5 is half way.
 11355     *
 11356     * @param  {Number} percentAsDecimal The new volume as a decimal percent
 11357     * @return {Number}              The current volume when getting
 11358     * @return {Player}              self when setting
 11359     * @method volume
 11360     */
 11361  
 11362    Player.prototype.volume = function volume(percentAsDecimal) {
 11363      var vol = undefined;
 11364  
 11365      if (percentAsDecimal !== undefined) {
 11366        vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); // Force value to between 0 and 1
 11367        this.cache_.volume = vol;
 11368        this.techCall_('setVolume', vol);
 11369  
 11370        return this;
 11371      }
 11372  
 11373      // Default to 1 when returning current volume.
 11374      vol = parseFloat(this.techGet_('volume'));
 11375      return isNaN(vol) ? 1 : vol;
 11376    };
 11377  
 11378    /**
 11379     * Get the current muted state, or turn mute on or off
 11380     * ```js
 11381     *     // get
 11382     *     var isVolumeMuted = myPlayer.muted();
 11383     *     // set
 11384     *     myPlayer.muted(true); // mute the volume
 11385     * ```
 11386     *
 11387     * @param  {Boolean=} muted True to mute, false to unmute
 11388     * @return {Boolean} True if mute is on, false if not when getting
 11389     * @return {Player} self when setting mute
 11390     * @method muted
 11391     */
 11392  
 11393    Player.prototype.muted = function muted(_muted) {
 11394      if (_muted !== undefined) {
 11395        this.techCall_('setMuted', _muted);
 11396        return this;
 11397      }
 11398      return this.techGet_('muted') || false; // Default to false
 11399    };
 11400  
 11401    // Check if current tech can support native fullscreen
 11402    // (e.g. with built in controls like iOS, so not our flash swf)
 11403    /**
 11404     * Check to see if fullscreen is supported
 11405     *
 11406     * @return {Boolean}
 11407     * @method supportsFullScreen
 11408     */
 11409  
 11410    Player.prototype.supportsFullScreen = function supportsFullScreen() {
 11411      return this.techGet_('supportsFullScreen') || false;
 11412    };
 11413  
 11414    /**
 11415     * Check if the player is in fullscreen mode
 11416     * ```js
 11417     *     // get
 11418     *     var fullscreenOrNot = myPlayer.isFullscreen();
 11419     *     // set
 11420     *     myPlayer.isFullscreen(true); // tell the player it's in fullscreen
 11421     * ```
 11422     * NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official
 11423     * property and instead document.fullscreenElement is used. But isFullscreen is
 11424     * still a valuable property for internal player workings.
 11425     *
 11426     * @param  {Boolean=} isFS Update the player's fullscreen state
 11427     * @return {Boolean} true if fullscreen false if not when getting
 11428     * @return {Player} self when setting
 11429     * @method isFullscreen
 11430     */
 11431  
 11432    Player.prototype.isFullscreen = function isFullscreen(isFS) {
 11433      if (isFS !== undefined) {
 11434        this.isFullscreen_ = !!isFS;
 11435        return this;
 11436      }
 11437      return !!this.isFullscreen_;
 11438    };
 11439  
 11440    /**
 11441     * Increase the size of the video to full screen
 11442     * ```js
 11443     *     myPlayer.requestFullscreen();
 11444     * ```
 11445     * In some browsers, full screen is not supported natively, so it enters
 11446     * "full window mode", where the video fills the browser window.
 11447     * In browsers and devices that support native full screen, sometimes the
 11448     * browser's default controls will be shown, and not the Video.js custom skin.
 11449     * This includes most mobile devices (iOS, Android) and older versions of
 11450     * Safari.
 11451     *
 11452     * @return {Player} self
 11453     * @method requestFullscreen
 11454     */
 11455  
 11456    Player.prototype.requestFullscreen = function requestFullscreen() {
 11457      var fsApi = _fullscreenApiJs2['default'];
 11458  
 11459      this.isFullscreen(true);
 11460  
 11461      if (fsApi.requestFullscreen) {
 11462        // the browser supports going fullscreen at the element level so we can
 11463        // take the controls fullscreen as well as the video
 11464  
 11465        // Trigger fullscreenchange event after change
 11466        // We have to specifically add this each time, and remove
 11467        // when canceling fullscreen. Otherwise if there's multiple
 11468        // players on a page, they would all be reacting to the same fullscreen
 11469        // events
 11470        Events.on(_globalDocument2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) {
 11471          this.isFullscreen(_globalDocument2['default'][fsApi.fullscreenElement]);
 11472  
 11473          // If cancelling fullscreen, remove event listener.
 11474          if (this.isFullscreen() === false) {
 11475            Events.off(_globalDocument2['default'], fsApi.fullscreenchange, documentFullscreenChange);
 11476          }
 11477  
 11478          this.trigger('fullscreenchange');
 11479        }));
 11480  
 11481        this.el_[fsApi.requestFullscreen]();
 11482      } else if (this.tech_.supportsFullScreen()) {
 11483        // we can't take the video.js controls fullscreen but we can go fullscreen
 11484        // with native controls
 11485        this.techCall_('enterFullScreen');
 11486      } else {
 11487        // fullscreen isn't supported so we'll just stretch the video element to
 11488        // fill the viewport
 11489        this.enterFullWindow();
 11490        this.trigger('fullscreenchange');
 11491      }
 11492  
 11493      return this;
 11494    };
 11495  
 11496    /**
 11497     * Return the video to its normal size after having been in full screen mode
 11498     * ```js
 11499     *     myPlayer.exitFullscreen();
 11500     * ```
 11501     *
 11502     * @return {Player} self
 11503     * @method exitFullscreen
 11504     */
 11505  
 11506    Player.prototype.exitFullscreen = function exitFullscreen() {
 11507      var fsApi = _fullscreenApiJs2['default'];
 11508      this.isFullscreen(false);
 11509  
 11510      // Check for browser element fullscreen support
 11511      if (fsApi.requestFullscreen) {
 11512        _globalDocument2['default'][fsApi.exitFullscreen]();
 11513      } else if (this.tech_.supportsFullScreen()) {
 11514        this.techCall_('exitFullScreen');
 11515      } else {
 11516        this.exitFullWindow();
 11517        this.trigger('fullscreenchange');
 11518      }
 11519  
 11520      return this;
 11521    };
 11522  
 11523    /**
 11524     * When fullscreen isn't supported we can stretch the video container to as wide as the browser will let us.
 11525     *
 11526     * @method enterFullWindow
 11527     */
 11528  
 11529    Player.prototype.enterFullWindow = function enterFullWindow() {
 11530      this.isFullWindow = true;
 11531  
 11532      // Storing original doc overflow value to return to when fullscreen is off
 11533      this.docOrigOverflow = _globalDocument2['default'].documentElement.style.overflow;
 11534  
 11535      // Add listener for esc key to exit fullscreen
 11536      Events.on(_globalDocument2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey));
 11537  
 11538      // Hide any scroll bars
 11539      _globalDocument2['default'].documentElement.style.overflow = 'hidden';
 11540  
 11541      // Apply fullscreen styles
 11542      Dom.addElClass(_globalDocument2['default'].body, 'vjs-full-window');
 11543  
 11544      this.trigger('enterFullWindow');
 11545    };
 11546  
 11547    /**
 11548     * Check for call to either exit full window or full screen on ESC key
 11549     *
 11550     * @param {String} event Event to check for key press
 11551     * @method fullWindowOnEscKey
 11552     */
 11553  
 11554    Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) {
 11555      if (event.keyCode === 27) {
 11556        if (this.isFullscreen() === true) {
 11557          this.exitFullscreen();
 11558        } else {
 11559          this.exitFullWindow();
 11560        }
 11561      }
 11562    };
 11563  
 11564    /**
 11565     * Exit full window
 11566     *
 11567     * @method exitFullWindow
 11568     */
 11569  
 11570    Player.prototype.exitFullWindow = function exitFullWindow() {
 11571      this.isFullWindow = false;
 11572      Events.off(_globalDocument2['default'], 'keydown', this.fullWindowOnEscKey);
 11573  
 11574      // Unhide scroll bars.
 11575      _globalDocument2['default'].documentElement.style.overflow = this.docOrigOverflow;
 11576  
 11577      // Remove fullscreen styles
 11578      Dom.removeElClass(_globalDocument2['default'].body, 'vjs-full-window');
 11579  
 11580      // Resize the box, controller, and poster to original sizes
 11581      // this.positionAll();
 11582      this.trigger('exitFullWindow');
 11583    };
 11584  
 11585    /**
 11586     * Check whether the player can play a given mimetype
 11587     *
 11588     * @param {String} type The mimetype to check
 11589     * @return {String} 'probably', 'maybe', or '' (empty string)
 11590     * @method canPlayType
 11591     */
 11592  
 11593    Player.prototype.canPlayType = function canPlayType(type) {
 11594      var can = undefined;
 11595  
 11596      // Loop through each playback technology in the options order
 11597      for (var i = 0, j = this.options_.techOrder; i < j.length; i++) {
 11598        var techName = _utilsToTitleCaseJs2['default'](j[i]);
 11599        var tech = _techTechJs2['default'].getTech(techName);
 11600  
 11601        // Support old behavior of techs being registered as components.
 11602        // Remove once that deprecated behavior is removed.
 11603        if (!tech) {
 11604          tech = _componentJs2['default'].getComponent(techName);
 11605        }
 11606  
 11607        // Check if the current tech is defined before continuing
 11608        if (!tech) {
 11609          _utilsLogJs2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
 11610          continue;
 11611        }
 11612  
 11613        // Check if the browser supports this technology
 11614        if (tech.isSupported()) {
 11615          can = tech.canPlayType(type);
 11616  
 11617          if (can) {
 11618            return can;
 11619          }
 11620        }
 11621      }
 11622  
 11623      return '';
 11624    };
 11625  
 11626    /**
 11627     * Select source based on tech-order or source-order
 11628     * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise,
 11629     * defaults to tech-order selection
 11630     *
 11631     * @param {Array} sources The sources for a media asset
 11632     * @return {Object|Boolean} Object of source and tech order, otherwise false
 11633     * @method selectSource
 11634     */
 11635  
 11636    Player.prototype.selectSource = function selectSource(sources) {
 11637      // Get only the techs specified in `techOrder` that exist and are supported by the
 11638      // current platform
 11639      var techs = this.options_.techOrder.map(_utilsToTitleCaseJs2['default']).map(function (techName) {
 11640        // `Component.getComponent(...)` is for support of old behavior of techs
 11641        // being registered as components.
 11642        // Remove once that deprecated behavior is removed.
 11643        return [techName, _techTechJs2['default'].getTech(techName) || _componentJs2['default'].getComponent(techName)];
 11644      }).filter(function (_ref) {
 11645        var techName = _ref[0];
 11646        var tech = _ref[1];
 11647  
 11648        // Check if the current tech is defined before continuing
 11649        if (tech) {
 11650          // Check if the browser supports this technology
 11651          return tech.isSupported();
 11652        }
 11653  
 11654        _utilsLogJs2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
 11655        return false;
 11656      });
 11657  
 11658      // Iterate over each `innerArray` element once per `outerArray` element and execute
 11659      // `tester` with both. If `tester` returns a non-falsy value, exit early and return
 11660      // that value.
 11661      var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) {
 11662        var found = undefined;
 11663  
 11664        outerArray.some(function (outerChoice) {
 11665          return innerArray.some(function (innerChoice) {
 11666            found = tester(outerChoice, innerChoice);
 11667  
 11668            if (found) {
 11669              return true;
 11670            }
 11671          });
 11672        });
 11673  
 11674        return found;
 11675      };
 11676  
 11677      var foundSourceAndTech = undefined;
 11678      var flip = function flip(fn) {
 11679        return function (a, b) {
 11680          return fn(b, a);
 11681        };
 11682      };
 11683      var finder = function finder(_ref2, source) {
 11684        var techName = _ref2[0];
 11685        var tech = _ref2[1];
 11686  
 11687        if (tech.canPlaySource(source)) {
 11688          return { source: source, tech: techName };
 11689        }
 11690      };
 11691  
 11692      // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources
 11693      // to select from them based on their priority.
 11694      if (this.options_.sourceOrder) {
 11695        // Source-first ordering
 11696        foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder));
 11697      } else {
 11698        // Tech-first ordering
 11699        foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder);
 11700      }
 11701  
 11702      return foundSourceAndTech || false;
 11703    };
 11704  
 11705    /**
 11706     * The source function updates the video source
 11707     * There are three types of variables you can pass as the argument.
 11708     * **URL String**: A URL to the the video file. Use this method if you are sure
 11709     * the current playback technology (HTML5/Flash) can support the source you
 11710     * provide. Currently only MP4 files can be used in both HTML5 and Flash.
 11711     * ```js
 11712     *     myPlayer.src("http://www.example.com/path/to/video.mp4");
 11713     * ```
 11714     * **Source Object (or element):* * A javascript object containing information
 11715     * about the source file. Use this method if you want the player to determine if
 11716     * it can support the file using the type information.
 11717     * ```js
 11718     *     myPlayer.src({ type: "video/mp4", src: "http://www.example.com/path/to/video.mp4" });
 11719     * ```
 11720     * **Array of Source Objects:* * To provide multiple versions of the source so
 11721     * that it can be played using HTML5 across browsers you can use an array of
 11722     * source objects. Video.js will detect which version is supported and load that
 11723     * file.
 11724     * ```js
 11725     *     myPlayer.src([
 11726     *       { type: "video/mp4", src: "http://www.example.com/path/to/video.mp4" },
 11727     *       { type: "video/webm", src: "http://www.example.com/path/to/video.webm" },
 11728     *       { type: "video/ogg", src: "http://www.example.com/path/to/video.ogv" }
 11729     *     ]);
 11730     * ```
 11731     *
 11732     * @param  {String|Object|Array=} source The source URL, object, or array of sources
 11733     * @return {String} The current video source when getting
 11734     * @return {String} The player when setting
 11735     * @method src
 11736     */
 11737  
 11738    Player.prototype.src = function src(source) {
 11739      if (source === undefined) {
 11740        return this.techGet_('src');
 11741      }
 11742  
 11743      var currentTech = _techTechJs2['default'].getTech(this.techName_);
 11744      // Support old behavior of techs being registered as components.
 11745      // Remove once that deprecated behavior is removed.
 11746      if (!currentTech) {
 11747        currentTech = _componentJs2['default'].getComponent(this.techName_);
 11748      }
 11749  
 11750      // case: Array of source objects to choose from and pick the best to play
 11751      if (Array.isArray(source)) {
 11752        this.sourceList_(source);
 11753  
 11754        // case: URL String (http://myvideo...)
 11755      } else if (typeof source === 'string') {
 11756          // create a source object from the string
 11757          this.src({ src: source });
 11758  
 11759          // case: Source object { src: '', type: '' ... }
 11760        } else if (source instanceof Object) {
 11761            // check if the source has a type and the loaded tech cannot play the source
 11762            // if there's no type we'll just try the current tech
 11763            if (source.type && !currentTech.canPlaySource(source)) {
 11764              // create a source list with the current source and send through
 11765              // the tech loop to check for a compatible technology
 11766              this.sourceList_([source]);
 11767            } else {
 11768              this.cache_.src = source.src;
 11769              this.currentType_ = source.type || '';
 11770  
 11771              // wait until the tech is ready to set the source
 11772              this.ready(function () {
 11773  
 11774                // The setSource tech method was added with source handlers
 11775                // so older techs won't support it
 11776                // We need to check the direct prototype for the case where subclasses
 11777                // of the tech do not support source handlers
 11778                if (currentTech.prototype.hasOwnProperty('setSource')) {
 11779                  this.techCall_('setSource', source);
 11780                } else {
 11781                  this.techCall_('src', source.src);
 11782                }
 11783  
 11784                if (this.options_.preload === 'auto') {
 11785                  this.load();
 11786                }
 11787  
 11788                if (this.options_.autoplay) {
 11789                  this.play();
 11790                }
 11791  
 11792                // Set the source synchronously if possible (#2326)
 11793              }, true);
 11794            }
 11795          }
 11796  
 11797      return this;
 11798    };
 11799  
 11800    /**
 11801     * Handle an array of source objects
 11802     *
 11803     * @param  {Array} sources Array of source objects
 11804     * @private
 11805     * @method sourceList_
 11806     */
 11807  
 11808    Player.prototype.sourceList_ = function sourceList_(sources) {
 11809      var sourceTech = this.selectSource(sources);
 11810  
 11811      if (sourceTech) {
 11812        if (sourceTech.tech === this.techName_) {
 11813          // if this technology is already loaded, set the source
 11814          this.src(sourceTech.source);
 11815        } else {
 11816          // load this technology with the chosen source
 11817          this.loadTech_(sourceTech.tech, sourceTech.source);
 11818        }
 11819      } else {
 11820        // We need to wrap this in a timeout to give folks a chance to add error event handlers
 11821        this.setTimeout(function () {
 11822          this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) });
 11823        }, 0);
 11824  
 11825        // we could not find an appropriate tech, but let's still notify the delegate that this is it
 11826        // this needs a better comment about why this is needed
 11827        this.triggerReady();
 11828      }
 11829    };
 11830  
 11831    /**
 11832     * Begin loading the src data.
 11833     *
 11834     * @return {Player} Returns the player
 11835     * @method load
 11836     */
 11837  
 11838    Player.prototype.load = function load() {
 11839      this.techCall_('load');
 11840      return this;
 11841    };
 11842  
 11843    /**
 11844     * Reset the player. Loads the first tech in the techOrder,
 11845     * and calls `reset` on the tech`.
 11846     *
 11847     * @return {Player} Returns the player
 11848     * @method reset
 11849     */
 11850  
 11851    Player.prototype.reset = function reset() {
 11852      this.loadTech_(_utilsToTitleCaseJs2['default'](this.options_.techOrder[0]), null);
 11853      this.techCall_('reset');
 11854      return this;
 11855    };
 11856  
 11857    /**
 11858     * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4
 11859     * Can be used in conjuction with `currentType` to assist in rebuilding the current source object.
 11860     *
 11861     * @return {String} The current source
 11862     * @method currentSrc
 11863     */
 11864  
 11865    Player.prototype.currentSrc = function currentSrc() {
 11866      return this.techGet_('currentSrc') || this.cache_.src || '';
 11867    };
 11868  
 11869    /**
 11870     * Get the current source type e.g. video/mp4
 11871     * This can allow you rebuild the current source object so that you could load the same
 11872     * source and tech later
 11873     *
 11874     * @return {String} The source MIME type
 11875     * @method currentType
 11876     */
 11877  
 11878    Player.prototype.currentType = function currentType() {
 11879      return this.currentType_ || '';
 11880    };
 11881  
 11882    /**
 11883     * Get or set the preload attribute
 11884     *
 11885     * @param {Boolean} value Boolean to determine if preload should be used
 11886     * @return {String} The preload attribute value when getting
 11887     * @return {Player} Returns the player when setting
 11888     * @method preload
 11889     */
 11890  
 11891    Player.prototype.preload = function preload(value) {
 11892      if (value !== undefined) {
 11893        this.techCall_('setPreload', value);
 11894        this.options_.preload = value;
 11895        return this;
 11896      }
 11897      return this.techGet_('preload');
 11898    };
 11899  
 11900    /**
 11901     * Get or set the autoplay attribute.
 11902     *
 11903     * @param {Boolean} value Boolean to determine if video should autoplay
 11904     * @return {String} The autoplay attribute value when getting
 11905     * @return {Player} Returns the player when setting
 11906     * @method autoplay
 11907     */
 11908  
 11909    Player.prototype.autoplay = function autoplay(value) {
 11910      if (value !== undefined) {
 11911        this.techCall_('setAutoplay', value);
 11912        this.options_.autoplay = value;
 11913        return this;
 11914      }
 11915      return this.techGet_('autoplay', value);
 11916    };
 11917  
 11918    /**
 11919     * Get or set the loop attribute on the video element.
 11920     *
 11921     * @param {Boolean} value Boolean to determine if video should loop
 11922     * @return {String} The loop attribute value when getting
 11923     * @return {Player} Returns the player when setting
 11924     * @method loop
 11925     */
 11926  
 11927    Player.prototype.loop = function loop(value) {
 11928      if (value !== undefined) {
 11929        this.techCall_('setLoop', value);
 11930        this.options_['loop'] = value;
 11931        return this;
 11932      }
 11933      return this.techGet_('loop');
 11934    };
 11935  
 11936    /**
 11937     * Get or set the poster image source url
 11938     *
 11939     * ##### EXAMPLE:
 11940     * ```js
 11941     *     // get
 11942     *     var currentPoster = myPlayer.poster();
 11943     *     // set
 11944     *     myPlayer.poster('http://example.com/myImage.jpg');
 11945     * ```
 11946     *
 11947     * @param  {String=} src Poster image source URL
 11948     * @return {String} poster URL when getting
 11949     * @return {Player} self when setting
 11950     * @method poster
 11951     */
 11952  
 11953    Player.prototype.poster = function poster(src) {
 11954      if (src === undefined) {
 11955        return this.poster_;
 11956      }
 11957  
 11958      // The correct way to remove a poster is to set as an empty string
 11959      // other falsey values will throw errors
 11960      if (!src) {
 11961        src = '';
 11962      }
 11963  
 11964      // update the internal poster variable
 11965      this.poster_ = src;
 11966  
 11967      // update the tech's poster
 11968      this.techCall_('setPoster', src);
 11969  
 11970      // alert components that the poster has been set
 11971      this.trigger('posterchange');
 11972  
 11973      return this;
 11974    };
 11975  
 11976    /**
 11977     * Some techs (e.g. YouTube) can provide a poster source in an
 11978     * asynchronous way. We want the poster component to use this
 11979     * poster source so that it covers up the tech's controls.
 11980     * (YouTube's play button). However we only want to use this
 11981     * soruce if the player user hasn't set a poster through
 11982     * the normal APIs.
 11983     *
 11984     * @private
 11985     * @method handleTechPosterChange_
 11986     */
 11987  
 11988    Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() {
 11989      if (!this.poster_ && this.tech_ && this.tech_.poster) {
 11990        this.poster_ = this.tech_.poster() || '';
 11991  
 11992        // Let components know the poster has changed
 11993        this.trigger('posterchange');
 11994      }
 11995    };
 11996  
 11997    /**
 11998     * Get or set whether or not the controls are showing.
 11999     *
 12000     * @param  {Boolean} bool Set controls to showing or not
 12001     * @return {Boolean}    Controls are showing
 12002     * @method controls
 12003     */
 12004  
 12005    Player.prototype.controls = function controls(bool) {
 12006      if (bool !== undefined) {
 12007        bool = !!bool; // force boolean
 12008        // Don't trigger a change event unless it actually changed
 12009        if (this.controls_ !== bool) {
 12010          this.controls_ = bool;
 12011  
 12012          if (this.usingNativeControls()) {
 12013            this.techCall_('setControls', bool);
 12014          }
 12015  
 12016          if (bool) {
 12017            this.removeClass('vjs-controls-disabled');
 12018            this.addClass('vjs-controls-enabled');
 12019            this.trigger('controlsenabled');
 12020  
 12021            if (!this.usingNativeControls()) {
 12022              this.addTechControlsListeners_();
 12023            }
 12024          } else {
 12025            this.removeClass('vjs-controls-enabled');
 12026            this.addClass('vjs-controls-disabled');
 12027            this.trigger('controlsdisabled');
 12028  
 12029            if (!this.usingNativeControls()) {
 12030              this.removeTechControlsListeners_();
 12031            }
 12032          }
 12033        }
 12034        return this;
 12035      }
 12036      return !!this.controls_;
 12037    };
 12038  
 12039    /**
 12040     * Toggle native controls on/off. Native controls are the controls built into
 12041     * devices (e.g. default iPhone controls), Flash, or other techs
 12042     * (e.g. Vimeo Controls)
 12043     * **This should only be set by the current tech, because only the tech knows
 12044     * if it can support native controls**
 12045     *
 12046     * @param  {Boolean} bool    True signals that native controls are on
 12047     * @return {Player}      Returns the player
 12048     * @private
 12049     * @method usingNativeControls
 12050     */
 12051  
 12052    Player.prototype.usingNativeControls = function usingNativeControls(bool) {
 12053      if (bool !== undefined) {
 12054        bool = !!bool; // force boolean
 12055        // Don't trigger a change event unless it actually changed
 12056        if (this.usingNativeControls_ !== bool) {
 12057          this.usingNativeControls_ = bool;
 12058          if (bool) {
 12059            this.addClass('vjs-using-native-controls');
 12060  
 12061            /**
 12062              * player is using the native device controls
 12063             *
 12064              * @event usingnativecontrols
 12065              * @memberof Player
 12066              * @instance
 12067              * @private
 12068              */
 12069            this.trigger('usingnativecontrols');
 12070          } else {
 12071            this.removeClass('vjs-using-native-controls');
 12072  
 12073            /**
 12074              * player is using the custom HTML controls
 12075             *
 12076              * @event usingcustomcontrols
 12077              * @memberof Player
 12078              * @instance
 12079              * @private
 12080              */
 12081            this.trigger('usingcustomcontrols');
 12082          }
 12083        }
 12084        return this;
 12085      }
 12086      return !!this.usingNativeControls_;
 12087    };
 12088  
 12089    /**
 12090     * Set or get the current MediaError
 12091     *
 12092     * @param  {*} err A MediaError or a String/Number to be turned into a MediaError
 12093     * @return {MediaError|null}     when getting
 12094     * @return {Player}              when setting
 12095     * @method error
 12096     */
 12097  
 12098    Player.prototype.error = function error(err) {
 12099      if (err === undefined) {
 12100        return this.error_ || null;
 12101      }
 12102  
 12103      // restoring to default
 12104      if (err === null) {
 12105        this.error_ = err;
 12106        this.removeClass('vjs-error');
 12107        this.errorDisplay.close();
 12108        return this;
 12109      }
 12110  
 12111      // error instance
 12112      if (err instanceof _mediaErrorJs2['default']) {
 12113        this.error_ = err;
 12114      } else {
 12115        this.error_ = new _mediaErrorJs2['default'](err);
 12116      }
 12117  
 12118      // add the vjs-error classname to the player
 12119      this.addClass('vjs-error');
 12120  
 12121      // log the name of the error type and any message
 12122      // ie8 just logs "[object object]" if you just log the error object
 12123      _utilsLogJs2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaErrorJs2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_);
 12124  
 12125      // fire an error event on the player
 12126      this.trigger('error');
 12127  
 12128      return this;
 12129    };
 12130  
 12131    /**
 12132     * Returns whether or not the player is in the "ended" state.
 12133     *
 12134     * @return {Boolean} True if the player is in the ended state, false if not.
 12135     * @method ended
 12136     */
 12137  
 12138    Player.prototype.ended = function ended() {
 12139      return this.techGet_('ended');
 12140    };
 12141  
 12142    /**
 12143     * Returns whether or not the player is in the "seeking" state.
 12144     *
 12145     * @return {Boolean} True if the player is in the seeking state, false if not.
 12146     * @method seeking
 12147     */
 12148  
 12149    Player.prototype.seeking = function seeking() {
 12150      return this.techGet_('seeking');
 12151    };
 12152  
 12153    /**
 12154     * Returns the TimeRanges of the media that are currently available
 12155     * for seeking to.
 12156     *
 12157     * @return {TimeRanges} the seekable intervals of the media timeline
 12158     * @method seekable
 12159     */
 12160  
 12161    Player.prototype.seekable = function seekable() {
 12162      return this.techGet_('seekable');
 12163    };
 12164  
 12165    /**
 12166     * Report user activity
 12167     *
 12168     * @param {Object} event Event object
 12169     * @method reportUserActivity
 12170     */
 12171  
 12172    Player.prototype.reportUserActivity = function reportUserActivity(event) {
 12173      this.userActivity_ = true;
 12174    };
 12175  
 12176    /**
 12177     * Get/set if user is active
 12178     *
 12179     * @param {Boolean} bool Value when setting
 12180     * @return {Boolean} Value if user is active user when getting
 12181     * @method userActive
 12182     */
 12183  
 12184    Player.prototype.userActive = function userActive(bool) {
 12185      if (bool !== undefined) {
 12186        bool = !!bool;
 12187        if (bool !== this.userActive_) {
 12188          this.userActive_ = bool;
 12189          if (bool) {
 12190            // If the user was inactive and is now active we want to reset the
 12191            // inactivity timer
 12192            this.userActivity_ = true;
 12193            this.removeClass('vjs-user-inactive');
 12194            this.addClass('vjs-user-active');
 12195            this.trigger('useractive');
 12196          } else {
 12197            // We're switching the state to inactive manually, so erase any other
 12198            // activity
 12199            this.userActivity_ = false;
 12200  
 12201            // Chrome/Safari/IE have bugs where when you change the cursor it can
 12202            // trigger a mousemove event. This causes an issue when you're hiding
 12203            // the cursor when the user is inactive, and a mousemove signals user
 12204            // activity. Making it impossible to go into inactive mode. Specifically
 12205            // this happens in fullscreen when we really need to hide the cursor.
 12206            //
 12207            // When this gets resolved in ALL browsers it can be removed
 12208            // https://code.google.com/p/chromium/issues/detail?id=103041
 12209            if (this.tech_) {
 12210              this.tech_.one('mousemove', function (e) {
 12211                e.stopPropagation();
 12212                e.preventDefault();
 12213              });
 12214            }
 12215  
 12216            this.removeClass('vjs-user-active');
 12217            this.addClass('vjs-user-inactive');
 12218            this.trigger('userinactive');
 12219          }
 12220        }
 12221        return this;
 12222      }
 12223      return this.userActive_;
 12224    };
 12225  
 12226    /**
 12227     * Listen for user activity based on timeout value
 12228     *
 12229     * @private
 12230     * @method listenForUserActivity_
 12231     */
 12232  
 12233    Player.prototype.listenForUserActivity_ = function listenForUserActivity_() {
 12234      var mouseInProgress = undefined,
 12235          lastMoveX = undefined,
 12236          lastMoveY = undefined;
 12237  
 12238      var handleActivity = Fn.bind(this, this.reportUserActivity);
 12239  
 12240      var handleMouseMove = function handleMouseMove(e) {
 12241        // #1068 - Prevent mousemove spamming
 12242        // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970
 12243        if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) {
 12244          lastMoveX = e.screenX;
 12245          lastMoveY = e.screenY;
 12246          handleActivity();
 12247        }
 12248      };
 12249  
 12250      var handleMouseDown = function handleMouseDown() {
 12251        handleActivity();
 12252        // For as long as the they are touching the device or have their mouse down,
 12253        // we consider them active even if they're not moving their finger or mouse.
 12254        // So we want to continue to update that they are active
 12255        this.clearInterval(mouseInProgress);
 12256        // Setting userActivity=true now and setting the interval to the same time
 12257        // as the activityCheck interval (250) should ensure we never miss the
 12258        // next activityCheck
 12259        mouseInProgress = this.setInterval(handleActivity, 250);
 12260      };
 12261  
 12262      var handleMouseUp = function handleMouseUp(event) {
 12263        handleActivity();
 12264        // Stop the interval that maintains activity if the mouse/touch is down
 12265        this.clearInterval(mouseInProgress);
 12266      };
 12267  
 12268      // Any mouse movement will be considered user activity
 12269      this.on('mousedown', handleMouseDown);
 12270      this.on('mousemove', handleMouseMove);
 12271      this.on('mouseup', handleMouseUp);
 12272  
 12273      // Listen for keyboard navigation
 12274      // Shouldn't need to use inProgress interval because of key repeat
 12275      this.on('keydown', handleActivity);
 12276      this.on('keyup', handleActivity);
 12277  
 12278      // Run an interval every 250 milliseconds instead of stuffing everything into
 12279      // the mousemove/touchmove function itself, to prevent performance degradation.
 12280      // `this.reportUserActivity` simply sets this.userActivity_ to true, which
 12281      // then gets picked up by this loop
 12282      // http://ejohn.org/blog/learning-from-twitter/
 12283      var inactivityTimeout = undefined;
 12284      var activityCheck = this.setInterval(function () {
 12285        // Check to see if mouse/touch activity has happened
 12286        if (this.userActivity_) {
 12287          // Reset the activity tracker
 12288          this.userActivity_ = false;
 12289  
 12290          // If the user state was inactive, set the state to active
 12291          this.userActive(true);
 12292  
 12293          // Clear any existing inactivity timeout to start the timer over
 12294          this.clearTimeout(inactivityTimeout);
 12295  
 12296          var timeout = this.options_['inactivityTimeout'];
 12297          if (timeout > 0) {
 12298            // In <timeout> milliseconds, if no more activity has occurred the
 12299            // user will be considered inactive
 12300            inactivityTimeout = this.setTimeout(function () {
 12301              // Protect against the case where the inactivityTimeout can trigger just
 12302              // before the next user activity is picked up by the activityCheck loop
 12303              // causing a flicker
 12304              if (!this.userActivity_) {
 12305                this.userActive(false);
 12306              }
 12307            }, timeout);
 12308          }
 12309        }
 12310      }, 250);
 12311    };
 12312  
 12313    /**
 12314     * Gets or sets the current playback rate.  A playback rate of
 12315     * 1.0 represents normal speed and 0.5 would indicate half-speed
 12316     * playback, for instance.
 12317     * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate
 12318     *
 12319     * @param  {Number} rate    New playback rate to set.
 12320     * @return {Number}         Returns the new playback rate when setting
 12321     * @return {Number}         Returns the current playback rate when getting
 12322     * @method playbackRate
 12323     */
 12324  
 12325    Player.prototype.playbackRate = function playbackRate(rate) {
 12326      if (rate !== undefined) {
 12327        this.techCall_('setPlaybackRate', rate);
 12328        return this;
 12329      }
 12330  
 12331      if (this.tech_ && this.tech_['featuresPlaybackRate']) {
 12332        return this.techGet_('playbackRate');
 12333      } else {
 12334        return 1.0;
 12335      }
 12336    };
 12337  
 12338    /**
 12339     * Gets or sets the audio flag
 12340     *
 12341     * @param  {Boolean} bool    True signals that this is an audio player.
 12342     * @return {Boolean}         Returns true if player is audio, false if not when getting
 12343     * @return {Player}      Returns the player if setting
 12344     * @private
 12345     * @method isAudio
 12346     */
 12347  
 12348    Player.prototype.isAudio = function isAudio(bool) {
 12349      if (bool !== undefined) {
 12350        this.isAudio_ = !!bool;
 12351        return this;
 12352      }
 12353  
 12354      return !!this.isAudio_;
 12355    };
 12356  
 12357    /**
 12358     * Returns the current state of network activity for the element, from
 12359     * the codes in the list below.
 12360     * - NETWORK_EMPTY (numeric value 0)
 12361     *   The element has not yet been initialised. All attributes are in
 12362     *   their initial states.
 12363     * - NETWORK_IDLE (numeric value 1)
 12364     *   The element's resource selection algorithm is active and has
 12365     *   selected a resource, but it is not actually using the network at
 12366     *   this time.
 12367     * - NETWORK_LOADING (numeric value 2)
 12368     *   The user agent is actively trying to download data.
 12369     * - NETWORK_NO_SOURCE (numeric value 3)
 12370     *   The element's resource selection algorithm is active, but it has
 12371     *   not yet found a resource to use.
 12372     *
 12373     * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states
 12374     * @return {Number} the current network activity state
 12375     * @method networkState
 12376     */
 12377  
 12378    Player.prototype.networkState = function networkState() {
 12379      return this.techGet_('networkState');
 12380    };
 12381  
 12382    /**
 12383     * Returns a value that expresses the current state of the element
 12384     * with respect to rendering the current playback position, from the
 12385     * codes in the list below.
 12386     * - HAVE_NOTHING (numeric value 0)
 12387     *   No information regarding the media resource is available.
 12388     * - HAVE_METADATA (numeric value 1)
 12389     *   Enough of the resource has been obtained that the duration of the
 12390     *   resource is available.
 12391     * - HAVE_CURRENT_DATA (numeric value 2)
 12392     *   Data for the immediate current playback position is available.
 12393     * - HAVE_FUTURE_DATA (numeric value 3)
 12394     *   Data for the immediate current playback position is available, as
 12395     *   well as enough data for the user agent to advance the current
 12396     *   playback position in the direction of playback.
 12397     * - HAVE_ENOUGH_DATA (numeric value 4)
 12398     *   The user agent estimates that enough data is available for
 12399     *   playback to proceed uninterrupted.
 12400     *
 12401     * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate
 12402     * @return {Number} the current playback rendering state
 12403     * @method readyState
 12404     */
 12405  
 12406    Player.prototype.readyState = function readyState() {
 12407      return this.techGet_('readyState');
 12408    };
 12409  
 12410    /**
 12411     * Text tracks are tracks of timed text events.
 12412     * Captions - text displayed over the video for the hearing impaired
 12413     * Subtitles - text displayed over the video for those who don't understand language in the video
 12414     * Chapters - text displayed in a menu allowing the user to jump to particular points (chapters) in the video
 12415     * Descriptions - audio descriptions that are read back to the user by a screen reading device
 12416     */
 12417  
 12418    /**
 12419     * Get an array of associated text tracks. captions, subtitles, chapters, descriptions
 12420     * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks
 12421     *
 12422     * @return {Array}           Array of track objects
 12423     * @method textTracks
 12424     */
 12425  
 12426    Player.prototype.textTracks = function textTracks() {
 12427      // cannot use techGet_ directly because it checks to see whether the tech is ready.
 12428      // Flash is unlikely to be ready in time but textTracks should still work.
 12429      return this.tech_ && this.tech_['textTracks']();
 12430    };
 12431  
 12432    /**
 12433     * Get an array of remote text tracks
 12434     *
 12435     * @return {Array}
 12436     * @method remoteTextTracks
 12437     */
 12438  
 12439    Player.prototype.remoteTextTracks = function remoteTextTracks() {
 12440      return this.tech_ && this.tech_['remoteTextTracks']();
 12441    };
 12442  
 12443    /**
 12444     * Get an array of remote html track elements
 12445     *
 12446     * @return {HTMLTrackElement[]}
 12447     * @method remoteTextTrackEls
 12448     */
 12449  
 12450    Player.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
 12451      return this.tech_ && this.tech_['remoteTextTrackEls']();
 12452    };
 12453  
 12454    /**
 12455     * Add a text track
 12456     * In addition to the W3C settings we allow adding additional info through options.
 12457     * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack
 12458     *
 12459     * @param {String}  kind        Captions, subtitles, chapters, descriptions, or metadata
 12460     * @param {String=} label       Optional label
 12461     * @param {String=} language    Optional language
 12462     * @method addTextTrack
 12463     */
 12464  
 12465    Player.prototype.addTextTrack = function addTextTrack(kind, label, language) {
 12466      return this.tech_ && this.tech_['addTextTrack'](kind, label, language);
 12467    };
 12468  
 12469    /**
 12470     * Add a remote text track
 12471     *
 12472     * @param {Object} options    Options for remote text track
 12473     * @method addRemoteTextTrack
 12474     */
 12475  
 12476    Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options) {
 12477      return this.tech_ && this.tech_['addRemoteTextTrack'](options);
 12478    };
 12479  
 12480    /**
 12481     * Remove a remote text track
 12482     *
 12483     * @param {Object} track    Remote text track to remove
 12484     * @method removeRemoteTextTrack
 12485     */
 12486  
 12487    Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
 12488      this.tech_ && this.tech_['removeRemoteTextTrack'](track);
 12489    };
 12490  
 12491    /**
 12492     * Get video width
 12493     *
 12494     * @return {Number} Video width
 12495     * @method videoWidth
 12496     */
 12497  
 12498    Player.prototype.videoWidth = function videoWidth() {
 12499      return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0;
 12500    };
 12501  
 12502    /**
 12503     * Get video height
 12504     *
 12505     * @return {Number} Video height
 12506     * @method videoHeight
 12507     */
 12508  
 12509    Player.prototype.videoHeight = function videoHeight() {
 12510      return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0;
 12511    };
 12512  
 12513    // Methods to add support for
 12514    // initialTime: function(){ return this.techCall_('initialTime'); },
 12515    // startOffsetTime: function(){ return this.techCall_('startOffsetTime'); },
 12516    // played: function(){ return this.techCall_('played'); },
 12517    // videoTracks: function(){ return this.techCall_('videoTracks'); },
 12518    // audioTracks: function(){ return this.techCall_('audioTracks'); },
 12519    // defaultPlaybackRate: function(){ return this.techCall_('defaultPlaybackRate'); },
 12520    // defaultMuted: function(){ return this.techCall_('defaultMuted'); }
 12521  
 12522    /**
 12523     * The player's language code
 12524     * NOTE: The language should be set in the player options if you want the
 12525     * the controls to be built with a specific language. Changing the lanugage
 12526     * later will not update controls text.
 12527     *
 12528     * @param {String} code  The locale string
 12529     * @return {String}      The locale string when getting
 12530     * @return {Player}      self when setting
 12531     * @method language
 12532     */
 12533  
 12534    Player.prototype.language = function language(code) {
 12535      if (code === undefined) {
 12536        return this.language_;
 12537      }
 12538  
 12539      this.language_ = ('' + code).toLowerCase();
 12540      return this;
 12541    };
 12542  
 12543    /**
 12544     * Get the player's language dictionary
 12545     * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time
 12546     * Languages specified directly in the player options have precedence
 12547     *
 12548     * @return {Array} Array of languages
 12549     * @method languages
 12550     */
 12551  
 12552    Player.prototype.languages = function languages() {
 12553      return _utilsMergeOptionsJs2['default'](Player.prototype.options_.languages, this.languages_);
 12554    };
 12555  
 12556    /**
 12557     * Converts track info to JSON
 12558     *
 12559     * @return {Object} JSON object of options
 12560     * @method toJSON
 12561     */
 12562  
 12563    Player.prototype.toJSON = function toJSON() {
 12564      var options = _utilsMergeOptionsJs2['default'](this.options_);
 12565      var tracks = options.tracks;
 12566  
 12567      options.tracks = [];
 12568  
 12569      for (var i = 0; i < tracks.length; i++) {
 12570        var track = tracks[i];
 12571  
 12572        // deep merge tracks and null out player so no circular references
 12573        track = _utilsMergeOptionsJs2['default'](track);
 12574        track.player = undefined;
 12575        options.tracks[i] = track;
 12576      }
 12577  
 12578      return options;
 12579    };
 12580  
 12581    /**
 12582     * Creates a simple modal dialog (an instance of the `ModalDialog`
 12583     * component) that immediately overlays the player with arbitrary
 12584     * content and removes itself when closed.
 12585     *
 12586     * @param {String|Function|Element|Array|Null} content
 12587     *        Same as `ModalDialog#content`'s param of the same name.
 12588     *
 12589     *        The most straight-forward usage is to provide a string or DOM
 12590     *        element.
 12591     *
 12592     * @param {Object} [options]
 12593     *        Extra options which will be passed on to the `ModalDialog`.
 12594     *
 12595     * @return {ModalDialog}
 12596     */
 12597  
 12598    Player.prototype.createModal = function createModal(content, options) {
 12599      var player = this;
 12600  
 12601      options = options || {};
 12602      options.content = content || '';
 12603  
 12604      var modal = new _modalDialog2['default'](player, options);
 12605  
 12606      player.addChild(modal);
 12607      modal.on('dispose', function () {
 12608        player.removeChild(modal);
 12609      });
 12610  
 12611      return modal.open();
 12612    };
 12613  
 12614    /**
 12615     * Gets tag settings
 12616     *
 12617     * @param {Element} tag The player tag
 12618     * @return {Array} An array of sources and track objects
 12619     * @static
 12620     * @method getTagSettings
 12621     */
 12622  
 12623    Player.getTagSettings = function getTagSettings(tag) {
 12624      var baseOptions = {
 12625        'sources': [],
 12626        'tracks': []
 12627      };
 12628  
 12629      var tagOptions = Dom.getElAttributes(tag);
 12630      var dataSetup = tagOptions['data-setup'];
 12631  
 12632      // Check if data-setup attr exists.
 12633      if (dataSetup !== null) {
 12634        // Parse options JSON
 12635  
 12636        var _safeParseTuple = _safeJsonParseTuple2['default'](dataSetup || '{}');
 12637  
 12638        var err = _safeParseTuple[0];
 12639        var data = _safeParseTuple[1];
 12640  
 12641        if (err) {
 12642          _utilsLogJs2['default'].error(err);
 12643        }
 12644        _objectAssign2['default'](tagOptions, data);
 12645      }
 12646  
 12647      _objectAssign2['default'](baseOptions, tagOptions);
 12648  
 12649      // Get tag children settings
 12650      if (tag.hasChildNodes()) {
 12651        var children = tag.childNodes;
 12652  
 12653        for (var i = 0, j = children.length; i < j; i++) {
 12654          var child = children[i];
 12655          // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/
 12656          var childName = child.nodeName.toLowerCase();
 12657          if (childName === 'source') {
 12658            baseOptions.sources.push(Dom.getElAttributes(child));
 12659          } else if (childName === 'track') {
 12660            baseOptions.tracks.push(Dom.getElAttributes(child));
 12661          }
 12662        }
 12663      }
 12664  
 12665      return baseOptions;
 12666    };
 12667  
 12668    return Player;
 12669  })(_componentJs2['default']);
 12670  
 12671  Player.players = {};
 12672  
 12673  var navigator = _globalWindow2['default'].navigator;
 12674  /*
 12675   * Player instance options, surfaced using options
 12676   * options = Player.prototype.options_
 12677   * Make changes in options, not here.
 12678   *
 12679   * @type {Object}
 12680   * @private
 12681   */
 12682  Player.prototype.options_ = {
 12683    // Default order of fallback technology
 12684    techOrder: ['html5', 'flash'],
 12685    // techOrder: ['flash','html5'],
 12686  
 12687    html5: {},
 12688    flash: {},
 12689  
 12690    // defaultVolume: 0.85,
 12691    defaultVolume: 0.00, // The freakin seaguls are driving me crazy!
 12692  
 12693    // default inactivity timeout
 12694    inactivityTimeout: 2000,
 12695  
 12696    // default playback rates
 12697    playbackRates: [],
 12698    // Add playback rate selection by adding rates
 12699    // 'playbackRates': [0.5, 1, 1.5, 2],
 12700  
 12701    // Included control sets
 12702    children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'],
 12703  
 12704    language: _globalDocument2['default'].getElementsByTagName('html')[0].getAttribute('lang') || navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language || 'en',
 12705  
 12706    // locales and their language translations
 12707    languages: {},
 12708  
 12709    // Default message to show when a video cannot be played.
 12710    notSupportedMessage: 'No compatible source was found for this media.'
 12711  };
 12712  
 12713  /**
 12714   * Fired when the player has initial duration and dimension information
 12715   *
 12716   * @event loadedmetadata
 12717   */
 12718  Player.prototype.handleLoadedMetaData_;
 12719  
 12720  /**
 12721   * Fired when the player has downloaded data at the current playback position
 12722   *
 12723   * @event loadeddata
 12724   */
 12725  Player.prototype.handleLoadedData_;
 12726  
 12727  /**
 12728   * Fired when the user is active, e.g. moves the mouse over the player
 12729   *
 12730   * @event useractive
 12731   */
 12732  Player.prototype.handleUserActive_;
 12733  
 12734  /**
 12735   * Fired when the user is inactive, e.g. a short delay after the last mouse move or control interaction
 12736   *
 12737   * @event userinactive
 12738   */
 12739  Player.prototype.handleUserInactive_;
 12740  
 12741  /**
 12742   * Fired when the current playback position has changed *
 12743   * During playback this is fired every 15-250 milliseconds, depending on the
 12744   * playback technology in use.
 12745   *
 12746   * @event timeupdate
 12747   */
 12748  Player.prototype.handleTimeUpdate_;
 12749  
 12750  /**
 12751   * Fired when video playback ends
 12752   *
 12753   * @event ended
 12754   */
 12755  Player.prototype.handleTechEnded_;
 12756  
 12757  /**
 12758   * Fired when the volume changes
 12759   *
 12760   * @event volumechange
 12761   */
 12762  Player.prototype.handleVolumeChange_;
 12763  
 12764  /**
 12765   * Fired when an error occurs
 12766   *
 12767   * @event error
 12768   */
 12769  Player.prototype.handleError_;
 12770  
 12771  Player.prototype.flexNotSupported_ = function () {
 12772    var elem = _globalDocument2['default'].createElement('i');
 12773  
 12774    // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more
 12775    // common flex features that we can rely on when checking for flex support.
 12776    return !('flexBasis' in elem.style || 'webkitFlexBasis' in elem.style || 'mozFlexBasis' in elem.style || 'msFlexBasis' in elem.style || 'msFlexOrder' in elem.style) /* IE10-specific (2012 flex spec)  */;
 12777  };
 12778  
 12779  _componentJs2['default'].registerComponent('Player', Player);
 12780  exports['default'] = Player;
 12781  module.exports = exports['default'];
 12782  // If empty string, make it a parsable json object.
 12783  
 12784  },{"./big-play-button.js":63,"./component.js":67,"./control-bar/control-bar.js":68,"./error-display.js":100,"./fullscreen-api.js":103,"./loading-spinner.js":104,"./media-error.js":105,"./modal-dialog":109,"./poster-image.js":114,"./tech/html5.js":119,"./tech/loader.js":120,"./tech/tech.js":121,"./tracks/text-track-display.js":125,"./tracks/text-track-list-converter.js":127,"./tracks/text-track-settings.js":129,"./utils/browser.js":131,"./utils/buffer.js":132,"./utils/dom.js":134,"./utils/events.js":135,"./utils/fn.js":136,"./utils/guid.js":138,"./utils/log.js":139,"./utils/merge-options.js":140,"./utils/stylesheet.js":141,"./utils/time-ranges.js":142,"./utils/to-title-case.js":143,"global/document":1,"global/window":2,"object.assign":45,"safe-json-parse/tuple":54}],111:[function(_dereq_,module,exports){
 12785  /**
 12786   * @file plugins.js
 12787   */
 12788  'use strict';
 12789  
 12790  exports.__esModule = true;
 12791  
 12792  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 12793  
 12794  var _playerJs = _dereq_('./player.js');
 12795  
 12796  var _playerJs2 = _interopRequireDefault(_playerJs);
 12797  
 12798  /**
 12799   * The method for registering a video.js plugin
 12800   *
 12801   * @param  {String} name The name of the plugin
 12802   * @param  {Function} init The function that is run when the player inits
 12803   * @method plugin
 12804   */
 12805  var plugin = function plugin(name, init) {
 12806    _playerJs2['default'].prototype[name] = init;
 12807  };
 12808  
 12809  exports['default'] = plugin;
 12810  module.exports = exports['default'];
 12811  
 12812  },{"./player.js":110}],112:[function(_dereq_,module,exports){
 12813  /**
 12814   * @file popup-button.js
 12815   */
 12816  'use strict';
 12817  
 12818  exports.__esModule = true;
 12819  
 12820  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 12821  
 12822  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 12823  
 12824  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 12825  
 12826  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 12827  
 12828  var _clickableComponentJs = _dereq_('../clickable-component.js');
 12829  
 12830  var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
 12831  
 12832  var _componentJs = _dereq_('../component.js');
 12833  
 12834  var _componentJs2 = _interopRequireDefault(_componentJs);
 12835  
 12836  var _popupJs = _dereq_('./popup.js');
 12837  
 12838  var _popupJs2 = _interopRequireDefault(_popupJs);
 12839  
 12840  var _utilsDomJs = _dereq_('../utils/dom.js');
 12841  
 12842  var Dom = _interopRequireWildcard(_utilsDomJs);
 12843  
 12844  var _utilsFnJs = _dereq_('../utils/fn.js');
 12845  
 12846  var Fn = _interopRequireWildcard(_utilsFnJs);
 12847  
 12848  var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js');
 12849  
 12850  var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
 12851  
 12852  /**
 12853   * A button class with a popup control
 12854   *
 12855   * @param {Player|Object} player
 12856   * @param {Object=} options
 12857   * @extends ClickableComponent
 12858   * @class PopupButton
 12859   */
 12860  
 12861  var PopupButton = (function (_ClickableComponent) {
 12862    _inherits(PopupButton, _ClickableComponent);
 12863  
 12864    function PopupButton(player) {
 12865      var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
 12866  
 12867      _classCallCheck(this, PopupButton);
 12868  
 12869      _ClickableComponent.call(this, player, options);
 12870  
 12871      this.update();
 12872    }
 12873  
 12874    /**
 12875     * Update popup
 12876     *
 12877     * @method update
 12878     */
 12879  
 12880    PopupButton.prototype.update = function update() {
 12881      var popup = this.createPopup();
 12882  
 12883      if (this.popup) {
 12884        this.removeChild(this.popup);
 12885      }
 12886  
 12887      this.popup = popup;
 12888      this.addChild(popup);
 12889  
 12890      if (this.items && this.items.length === 0) {
 12891        this.hide();
 12892      } else if (this.items && this.items.length > 1) {
 12893        this.show();
 12894      }
 12895    };
 12896  
 12897    /**
 12898     * Create popup - Override with specific functionality for component
 12899     *
 12900     * @return {Popup} The constructed popup
 12901     * @method createPopup
 12902     */
 12903  
 12904    PopupButton.prototype.createPopup = function createPopup() {};
 12905  
 12906    /**
 12907     * Create the component's DOM element
 12908     *
 12909     * @return {Element}
 12910     * @method createEl
 12911     */
 12912  
 12913    PopupButton.prototype.createEl = function createEl() {
 12914      return _ClickableComponent.prototype.createEl.call(this, 'div', {
 12915        className: this.buildCSSClass()
 12916      });
 12917    };
 12918  
 12919    /**
 12920     * Allow sub components to stack CSS class names
 12921     *
 12922     * @return {String} The constructed class name
 12923     * @method buildCSSClass
 12924     */
 12925  
 12926    PopupButton.prototype.buildCSSClass = function buildCSSClass() {
 12927      var menuButtonClass = 'vjs-menu-button';
 12928  
 12929      // If the inline option is passed, we want to use different styles altogether.
 12930      if (this.options_.inline === true) {
 12931        menuButtonClass += '-inline';
 12932      } else {
 12933        menuButtonClass += '-popup';
 12934      }
 12935  
 12936      return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
 12937    };
 12938  
 12939    return PopupButton;
 12940  })(_clickableComponentJs2['default']);
 12941  
 12942  _componentJs2['default'].registerComponent('PopupButton', PopupButton);
 12943  exports['default'] = PopupButton;
 12944  module.exports = exports['default'];
 12945  
 12946  },{"../clickable-component.js":65,"../component.js":67,"../utils/dom.js":134,"../utils/fn.js":136,"../utils/to-title-case.js":143,"./popup.js":113}],113:[function(_dereq_,module,exports){
 12947  /**
 12948   * @file popup.js
 12949   */
 12950  'use strict';
 12951  
 12952  exports.__esModule = true;
 12953  
 12954  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 12955  
 12956  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 12957  
 12958  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 12959  
 12960  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 12961  
 12962  var _componentJs = _dereq_('../component.js');
 12963  
 12964  var _componentJs2 = _interopRequireDefault(_componentJs);
 12965  
 12966  var _utilsDomJs = _dereq_('../utils/dom.js');
 12967  
 12968  var Dom = _interopRequireWildcard(_utilsDomJs);
 12969  
 12970  var _utilsFnJs = _dereq_('../utils/fn.js');
 12971  
 12972  var Fn = _interopRequireWildcard(_utilsFnJs);
 12973  
 12974  var _utilsEventsJs = _dereq_('../utils/events.js');
 12975  
 12976  var Events = _interopRequireWildcard(_utilsEventsJs);
 12977  
 12978  /**
 12979   * The Popup component is used to build pop up controls.
 12980   *
 12981   * @extends Component
 12982   * @class Popup
 12983   */
 12984  
 12985  var Popup = (function (_Component) {
 12986    _inherits(Popup, _Component);
 12987  
 12988    function Popup() {
 12989      _classCallCheck(this, Popup);
 12990  
 12991      _Component.apply(this, arguments);
 12992    }
 12993  
 12994    /**
 12995     * Add a popup item to the popup
 12996     *
 12997     * @param {Object|String} component Component or component type to add
 12998     * @method addItem
 12999     */
 13000  
 13001    Popup.prototype.addItem = function addItem(component) {
 13002      this.addChild(component);
 13003      component.on('click', Fn.bind(this, function () {
 13004        this.unlockShowing();
 13005      }));
 13006    };
 13007  
 13008    /**
 13009     * Create the component's DOM element
 13010     *
 13011     * @return {Element}
 13012     * @method createEl
 13013     */
 13014  
 13015    Popup.prototype.createEl = function createEl() {
 13016      var contentElType = this.options_.contentElType || 'ul';
 13017      this.contentEl_ = Dom.createEl(contentElType, {
 13018        className: 'vjs-menu-content'
 13019      });
 13020      var el = _Component.prototype.createEl.call(this, 'div', {
 13021        append: this.contentEl_,
 13022        className: 'vjs-menu'
 13023      });
 13024      el.appendChild(this.contentEl_);
 13025  
 13026      // Prevent clicks from bubbling up. Needed for Popup Buttons,
 13027      // where a click on the parent is significant
 13028      Events.on(el, 'click', function (event) {
 13029        event.preventDefault();
 13030        event.stopImmediatePropagation();
 13031      });
 13032  
 13033      return el;
 13034    };
 13035  
 13036    return Popup;
 13037  })(_componentJs2['default']);
 13038  
 13039  _componentJs2['default'].registerComponent('Popup', Popup);
 13040  exports['default'] = Popup;
 13041  module.exports = exports['default'];
 13042  
 13043  },{"../component.js":67,"../utils/dom.js":134,"../utils/events.js":135,"../utils/fn.js":136}],114:[function(_dereq_,module,exports){
 13044  /**
 13045   * @file poster-image.js
 13046   */
 13047  'use strict';
 13048  
 13049  exports.__esModule = true;
 13050  
 13051  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 13052  
 13053  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 13054  
 13055  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 13056  
 13057  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 13058  
 13059  var _clickableComponentJs = _dereq_('./clickable-component.js');
 13060  
 13061  var _clickableComponentJs2 = _interopRequireDefault(_clickableComponentJs);
 13062  
 13063  var _componentJs = _dereq_('./component.js');
 13064  
 13065  var _componentJs2 = _interopRequireDefault(_componentJs);
 13066  
 13067  var _utilsFnJs = _dereq_('./utils/fn.js');
 13068  
 13069  var Fn = _interopRequireWildcard(_utilsFnJs);
 13070  
 13071  var _utilsDomJs = _dereq_('./utils/dom.js');
 13072  
 13073  var Dom = _interopRequireWildcard(_utilsDomJs);
 13074  
 13075  var _utilsBrowserJs = _dereq_('./utils/browser.js');
 13076  
 13077  var browser = _interopRequireWildcard(_utilsBrowserJs);
 13078  
 13079  /**
 13080   * The component that handles showing the poster image.
 13081   *
 13082   * @param {Player|Object} player
 13083   * @param {Object=} options
 13084   * @extends Button
 13085   * @class PosterImage
 13086   */
 13087  
 13088  var PosterImage = (function (_ClickableComponent) {
 13089    _inherits(PosterImage, _ClickableComponent);
 13090  
 13091    function PosterImage(player, options) {
 13092      _classCallCheck(this, PosterImage);
 13093  
 13094      _ClickableComponent.call(this, player, options);
 13095  
 13096      this.update();
 13097      player.on('posterchange', Fn.bind(this, this.update));
 13098    }
 13099  
 13100    /**
 13101     * Clean up the poster image
 13102     *
 13103     * @method dispose
 13104     */
 13105  
 13106    PosterImage.prototype.dispose = function dispose() {
 13107      this.player().off('posterchange', this.update);
 13108      _ClickableComponent.prototype.dispose.call(this);
 13109    };
 13110  
 13111    /**
 13112     * Create the poster's image element
 13113     *
 13114     * @return {Element}
 13115     * @method createEl
 13116     */
 13117  
 13118    PosterImage.prototype.createEl = function createEl() {
 13119      var el = Dom.createEl('div', {
 13120        className: 'vjs-poster',
 13121  
 13122        // Don't want poster to be tabbable.
 13123        tabIndex: -1
 13124      });
 13125  
 13126      // To ensure the poster image resizes while maintaining its original aspect
 13127      // ratio, use a div with `background-size` when available. For browsers that
 13128      // do not support `background-size` (e.g. IE8), fall back on using a regular
 13129      // img element.
 13130      if (!browser.BACKGROUND_SIZE_SUPPORTED) {
 13131        this.fallbackImg_ = Dom.createEl('img');
 13132        el.appendChild(this.fallbackImg_);
 13133      }
 13134  
 13135      return el;
 13136    };
 13137  
 13138    /**
 13139     * Event handler for updates to the player's poster source
 13140     *
 13141     * @method update
 13142     */
 13143  
 13144    PosterImage.prototype.update = function update() {
 13145      var url = this.player().poster();
 13146  
 13147      this.setSrc(url);
 13148  
 13149      // If there's no poster source we should display:none on this component
 13150      // so it's not still clickable or right-clickable
 13151      if (url) {
 13152        this.show();
 13153      } else {
 13154        this.hide();
 13155      }
 13156    };
 13157  
 13158    /**
 13159     * Set the poster source depending on the display method
 13160     *
 13161     * @param {String} url The URL to the poster source
 13162     * @method setSrc
 13163     */
 13164  
 13165    PosterImage.prototype.setSrc = function setSrc(url) {
 13166      if (this.fallbackImg_) {
 13167        this.fallbackImg_.src = url;
 13168      } else {
 13169        var backgroundImage = '';
 13170        // Any falsey values should stay as an empty string, otherwise
 13171        // this will throw an extra error
 13172        if (url) {
 13173          backgroundImage = 'url("' + url + '")';
 13174        }
 13175  
 13176        this.el_.style.backgroundImage = backgroundImage;
 13177      }
 13178    };
 13179  
 13180    /**
 13181     * Event handler for clicks on the poster image
 13182     *
 13183     * @method handleClick
 13184     */
 13185  
 13186    PosterImage.prototype.handleClick = function handleClick() {
 13187      // We don't want a click to trigger playback when controls are disabled
 13188      // but CSS should be hiding the poster to prevent that from happening
 13189      if (this.player_.paused()) {
 13190        this.player_.play();
 13191      } else {
 13192        this.player_.pause();
 13193      }
 13194    };
 13195  
 13196    return PosterImage;
 13197  })(_clickableComponentJs2['default']);
 13198  
 13199  _componentJs2['default'].registerComponent('PosterImage', PosterImage);
 13200  exports['default'] = PosterImage;
 13201  module.exports = exports['default'];
 13202  
 13203  },{"./clickable-component.js":65,"./component.js":67,"./utils/browser.js":131,"./utils/dom.js":134,"./utils/fn.js":136}],115:[function(_dereq_,module,exports){
 13204  /**
 13205   * @file setup.js
 13206   *
 13207   * Functions for automatically setting up a player
 13208   * based on the data-setup attribute of the video tag
 13209   */
 13210  'use strict';
 13211  
 13212  exports.__esModule = true;
 13213  
 13214  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 13215  
 13216  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 13217  
 13218  var _utilsEventsJs = _dereq_('./utils/events.js');
 13219  
 13220  var Events = _interopRequireWildcard(_utilsEventsJs);
 13221  
 13222  var _globalDocument = _dereq_('global/document');
 13223  
 13224  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 13225  
 13226  var _globalWindow = _dereq_('global/window');
 13227  
 13228  var _globalWindow2 = _interopRequireDefault(_globalWindow);
 13229  
 13230  var _windowLoaded = false;
 13231  var videojs = undefined;
 13232  
 13233  // Automatically set up any tags that have a data-setup attribute
 13234  var autoSetup = function autoSetup() {
 13235    // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack*
 13236    // var vids = Array.prototype.slice.call(document.getElementsByTagName('video'));
 13237    // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio'));
 13238    // var mediaEls = vids.concat(audios);
 13239  
 13240    // Because IE8 doesn't support calling slice on a node list, we need to loop through each list of elements
 13241    // to build up a new, combined list of elements.
 13242    var vids = _globalDocument2['default'].getElementsByTagName('video');
 13243    var audios = _globalDocument2['default'].getElementsByTagName('audio');
 13244    var mediaEls = [];
 13245    if (vids && vids.length > 0) {
 13246      for (var i = 0, e = vids.length; i < e; i++) {
 13247        mediaEls.push(vids[i]);
 13248      }
 13249    }
 13250    if (audios && audios.length > 0) {
 13251      for (var i = 0, e = audios.length; i < e; i++) {
 13252        mediaEls.push(audios[i]);
 13253      }
 13254    }
 13255  
 13256    // Check if any media elements exist
 13257    if (mediaEls && mediaEls.length > 0) {
 13258  
 13259      for (var i = 0, e = mediaEls.length; i < e; i++) {
 13260        var mediaEl = mediaEls[i];
 13261  
 13262        // Check if element exists, has getAttribute func.
 13263        // IE seems to consider typeof el.getAttribute == 'object' instead of 'function' like expected, at least when loading the player immediately.
 13264        if (mediaEl && mediaEl.getAttribute) {
 13265  
 13266          // Make sure this player hasn't already been set up.
 13267          if (mediaEl['player'] === undefined) {
 13268            var options = mediaEl.getAttribute('data-setup');
 13269  
 13270            // Check if data-setup attr exists.
 13271            // We only auto-setup if they've added the data-setup attr.
 13272            if (options !== null) {
 13273              // Create new video.js instance.
 13274              var player = videojs(mediaEl);
 13275            }
 13276          }
 13277  
 13278          // If getAttribute isn't defined, we need to wait for the DOM.
 13279        } else {
 13280            autoSetupTimeout(1);
 13281            break;
 13282          }
 13283      }
 13284  
 13285      // No videos were found, so keep looping unless page is finished loading.
 13286    } else if (!_windowLoaded) {
 13287        autoSetupTimeout(1);
 13288      }
 13289  };
 13290  
 13291  // Pause to let the DOM keep processing
 13292  var autoSetupTimeout = function autoSetupTimeout(wait, vjs) {
 13293    if (vjs) {
 13294      videojs = vjs;
 13295    }
 13296  
 13297    setTimeout(autoSetup, wait);
 13298  };
 13299  
 13300  if (_globalDocument2['default'].readyState === 'complete') {
 13301    _windowLoaded = true;
 13302  } else {
 13303    Events.one(_globalWindow2['default'], 'load', function () {
 13304      _windowLoaded = true;
 13305    });
 13306  }
 13307  
 13308  var hasLoaded = function hasLoaded() {
 13309    return _windowLoaded;
 13310  };
 13311  
 13312  exports.autoSetup = autoSetup;
 13313  exports.autoSetupTimeout = autoSetupTimeout;
 13314  exports.hasLoaded = hasLoaded;
 13315  
 13316  },{"./utils/events.js":135,"global/document":1,"global/window":2}],116:[function(_dereq_,module,exports){
 13317  /**
 13318   * @file slider.js
 13319   */
 13320  'use strict';
 13321  
 13322  exports.__esModule = true;
 13323  
 13324  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 13325  
 13326  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 13327  
 13328  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 13329  
 13330  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 13331  
 13332  var _componentJs = _dereq_('../component.js');
 13333  
 13334  var _componentJs2 = _interopRequireDefault(_componentJs);
 13335  
 13336  var _utilsDomJs = _dereq_('../utils/dom.js');
 13337  
 13338  var Dom = _interopRequireWildcard(_utilsDomJs);
 13339  
 13340  var _objectAssign = _dereq_('object.assign');
 13341  
 13342  var _objectAssign2 = _interopRequireDefault(_objectAssign);
 13343  
 13344  /**
 13345   * The base functionality for sliders like the volume bar and seek bar
 13346   *
 13347   * @param {Player|Object} player
 13348   * @param {Object=} options
 13349   * @extends Component
 13350   * @class Slider
 13351   */
 13352  
 13353  var Slider = (function (_Component) {
 13354    _inherits(Slider, _Component);
 13355  
 13356    function Slider(player, options) {
 13357      _classCallCheck(this, Slider);
 13358  
 13359      _Component.call(this, player, options);
 13360  
 13361      // Set property names to bar to match with the child Slider class is looking for
 13362      this.bar = this.getChild(this.options_.barName);
 13363  
 13364      // Set a horizontal or vertical class on the slider depending on the slider type
 13365      this.vertical(!!this.options_.vertical);
 13366  
 13367      this.on('mousedown', this.handleMouseDown);
 13368      this.on('touchstart', this.handleMouseDown);
 13369      this.on('focus', this.handleFocus);
 13370      this.on('blur', this.handleBlur);
 13371      this.on('click', this.handleClick);
 13372  
 13373      this.on(player, 'controlsvisible', this.update);
 13374      this.on(player, this.playerEvent, this.update);
 13375    }
 13376  
 13377    /**
 13378     * Create the component's DOM element
 13379     *
 13380     * @param {String} type Type of element to create
 13381     * @param {Object=} props List of properties in Object form
 13382     * @return {Element}
 13383     * @method createEl
 13384     */
 13385  
 13386    Slider.prototype.createEl = function createEl(type) {
 13387      var props = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
 13388      var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
 13389  
 13390      // Add the slider element class to all sub classes
 13391      props.className = props.className + ' vjs-slider';
 13392      props = _objectAssign2['default']({
 13393        tabIndex: 0
 13394      }, props);
 13395  
 13396      attributes = _objectAssign2['default']({
 13397        'role': 'slider',
 13398        'aria-valuenow': 0,
 13399        'aria-valuemin': 0,
 13400        'aria-valuemax': 100,
 13401        tabIndex: 0
 13402      }, attributes);
 13403  
 13404      return _Component.prototype.createEl.call(this, type, props, attributes);
 13405    };
 13406  
 13407    /**
 13408     * Handle mouse down on slider
 13409     *
 13410     * @param {Object} event Mouse down event object
 13411     * @method handleMouseDown
 13412     */
 13413  
 13414    Slider.prototype.handleMouseDown = function handleMouseDown(event) {
 13415      var doc = this.bar.el_.ownerDocument;
 13416  
 13417      event.preventDefault();
 13418      Dom.blockTextSelection();
 13419  
 13420      this.addClass('vjs-sliding');
 13421      this.trigger('slideractive');
 13422  
 13423      this.on(doc, 'mousemove', this.handleMouseMove);
 13424      this.on(doc, 'mouseup', this.handleMouseUp);
 13425      this.on(doc, 'touchmove', this.handleMouseMove);
 13426      this.on(doc, 'touchend', this.handleMouseUp);
 13427  
 13428      this.handleMouseMove(event);
 13429    };
 13430  
 13431    /**
 13432     * To be overridden by a subclass
 13433     *
 13434     * @method handleMouseMove
 13435     */
 13436  
 13437    Slider.prototype.handleMouseMove = function handleMouseMove() {};
 13438  
 13439    /**
 13440     * Handle mouse up on Slider
 13441     *
 13442     * @method handleMouseUp
 13443     */
 13444  
 13445    Slider.prototype.handleMouseUp = function handleMouseUp() {
 13446      var doc = this.bar.el_.ownerDocument;
 13447  
 13448      Dom.unblockTextSelection();
 13449  
 13450      this.removeClass('vjs-sliding');
 13451      this.trigger('sliderinactive');
 13452  
 13453      this.off(doc, 'mousemove', this.handleMouseMove);
 13454      this.off(doc, 'mouseup', this.handleMouseUp);
 13455      this.off(doc, 'touchmove', this.handleMouseMove);
 13456      this.off(doc, 'touchend', this.handleMouseUp);
 13457  
 13458      this.update();
 13459    };
 13460  
 13461    /**
 13462     * Update slider
 13463     *
 13464     * @method update
 13465     */
 13466  
 13467    Slider.prototype.update = function update() {
 13468      // In VolumeBar init we have a setTimeout for update that pops and update to the end of the
 13469      // execution stack. The player is destroyed before then update will cause an error
 13470      if (!this.el_) return;
 13471  
 13472      // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.
 13473      // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.
 13474      // var progress =  (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration();
 13475      var progress = this.getPercent();
 13476      var bar = this.bar;
 13477  
 13478      // If there's no bar...
 13479      if (!bar) return;
 13480  
 13481      // Protect against no duration and other division issues
 13482      if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) {
 13483        progress = 0;
 13484      }
 13485  
 13486      // Convert to a percentage for setting
 13487      var percentage = (progress * 100).toFixed(2) + '%';
 13488  
 13489      // Set the new bar width or height
 13490      if (this.vertical()) {
 13491        bar.el().style.height = percentage;
 13492      } else {
 13493        bar.el().style.width = percentage;
 13494      }
 13495    };
 13496  
 13497    /**
 13498     * Calculate distance for slider
 13499     *
 13500     * @param {Object} event Event object
 13501     * @method calculateDistance
 13502     */
 13503  
 13504    Slider.prototype.calculateDistance = function calculateDistance(event) {
 13505      var position = Dom.getPointerPosition(this.el_, event);
 13506      if (this.vertical()) {
 13507        return position.y;
 13508      }
 13509      return position.x;
 13510    };
 13511  
 13512    /**
 13513     * Handle on focus for slider
 13514     *
 13515     * @method handleFocus
 13516     */
 13517  
 13518    Slider.prototype.handleFocus = function handleFocus() {
 13519      this.on(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
 13520    };
 13521  
 13522    /**
 13523     * Handle key press for slider
 13524     *
 13525     * @param {Object} event Event object
 13526     * @method handleKeyPress
 13527     */
 13528  
 13529    Slider.prototype.handleKeyPress = function handleKeyPress(event) {
 13530      if (event.which === 37 || event.which === 40) {
 13531        // Left and Down Arrows
 13532        event.preventDefault();
 13533        this.stepBack();
 13534      } else if (event.which === 38 || event.which === 39) {
 13535        // Up and Right Arrows
 13536        event.preventDefault();
 13537        this.stepForward();
 13538      }
 13539    };
 13540  
 13541    /**
 13542     * Handle on blur for slider
 13543     *
 13544     * @method handleBlur
 13545     */
 13546  
 13547    Slider.prototype.handleBlur = function handleBlur() {
 13548      this.off(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
 13549    };
 13550  
 13551    /**
 13552     * Listener for click events on slider, used to prevent clicks
 13553     *   from bubbling up to parent elements like button menus.
 13554     *
 13555     * @param {Object} event Event object
 13556     * @method handleClick
 13557     */
 13558  
 13559    Slider.prototype.handleClick = function handleClick(event) {
 13560      event.stopImmediatePropagation();
 13561      event.preventDefault();
 13562    };
 13563  
 13564    /**
 13565     * Get/set if slider is horizontal for vertical
 13566     *
 13567     * @param {Boolean} bool True if slider is vertical, false is horizontal
 13568     * @return {Boolean} True if slider is vertical, false is horizontal
 13569     * @method vertical
 13570     */
 13571  
 13572    Slider.prototype.vertical = function vertical(bool) {
 13573      if (bool === undefined) {
 13574        return this.vertical_ || false;
 13575      }
 13576  
 13577      this.vertical_ = !!bool;
 13578  
 13579      if (this.vertical_) {
 13580        this.addClass('vjs-slider-vertical');
 13581      } else {
 13582        this.addClass('vjs-slider-horizontal');
 13583      }
 13584  
 13585      return this;
 13586    };
 13587  
 13588    return Slider;
 13589  })(_componentJs2['default']);
 13590  
 13591  _componentJs2['default'].registerComponent('Slider', Slider);
 13592  exports['default'] = Slider;
 13593  module.exports = exports['default'];
 13594  
 13595  },{"../component.js":67,"../utils/dom.js":134,"object.assign":45}],117:[function(_dereq_,module,exports){
 13596  /**
 13597   * @file flash-rtmp.js
 13598   */
 13599  'use strict';
 13600  
 13601  exports.__esModule = true;
 13602  function FlashRtmpDecorator(Flash) {
 13603    Flash.streamingFormats = {
 13604      'rtmp/mp4': 'MP4',
 13605      'rtmp/flv': 'FLV'
 13606    };
 13607  
 13608    Flash.streamFromParts = function (connection, stream) {
 13609      return connection + '&' + stream;
 13610    };
 13611  
 13612    Flash.streamToParts = function (src) {
 13613      var parts = {
 13614        connection: '',
 13615        stream: ''
 13616      };
 13617  
 13618      if (!src) return parts;
 13619  
 13620      // Look for the normal URL separator we expect, '&'.
 13621      // If found, we split the URL into two pieces around the
 13622      // first '&'.
 13623      var connEnd = src.search(/&(?!\w+=)/);
 13624      var streamBegin = undefined;
 13625      if (connEnd !== -1) {
 13626        streamBegin = connEnd + 1;
 13627      } else {
 13628        // If there's not a '&', we use the last '/' as the delimiter.
 13629        connEnd = streamBegin = src.lastIndexOf('/') + 1;
 13630        if (connEnd === 0) {
 13631          // really, there's not a '/'?
 13632          connEnd = streamBegin = src.length;
 13633        }
 13634      }
 13635      parts.connection = src.substring(0, connEnd);
 13636      parts.stream = src.substring(streamBegin, src.length);
 13637  
 13638      return parts;
 13639    };
 13640  
 13641    Flash.isStreamingType = function (srcType) {
 13642      return srcType in Flash.streamingFormats;
 13643    };
 13644  
 13645    // RTMP has four variations, any string starting
 13646    // with one of these protocols should be valid
 13647    Flash.RTMP_RE = /^rtmp[set]?:\/\//i;
 13648  
 13649    Flash.isStreamingSrc = function (src) {
 13650      return Flash.RTMP_RE.test(src);
 13651    };
 13652  
 13653    /**
 13654     * A source handler for RTMP urls
 13655     * @type {Object}
 13656     */
 13657    Flash.rtmpSourceHandler = {};
 13658  
 13659    /**
 13660     * Check if Flash can play the given videotype
 13661     * @param  {String} type    The mimetype to check
 13662     * @return {String}         'probably', 'maybe', or '' (empty string)
 13663     */
 13664    Flash.rtmpSourceHandler.canPlayType = function (type) {
 13665      if (Flash.isStreamingType(type)) {
 13666        return 'maybe';
 13667      }
 13668  
 13669      return '';
 13670    };
 13671  
 13672    /**
 13673     * Check if Flash can handle the source natively
 13674     * @param  {Object} source  The source object
 13675     * @return {String}         'probably', 'maybe', or '' (empty string)
 13676     */
 13677    Flash.rtmpSourceHandler.canHandleSource = function (source) {
 13678      var can = Flash.rtmpSourceHandler.canPlayType(source.type);
 13679  
 13680      if (can) {
 13681        return can;
 13682      }
 13683  
 13684      if (Flash.isStreamingSrc(source.src)) {
 13685        return 'maybe';
 13686      }
 13687  
 13688      return '';
 13689    };
 13690  
 13691    /**
 13692     * Pass the source to the flash object
 13693     * Adaptive source handlers will have more complicated workflows before passing
 13694     * video data to the video element
 13695     * @param  {Object} source    The source object
 13696     * @param  {Flash} tech   The instance of the Flash tech
 13697     */
 13698    Flash.rtmpSourceHandler.handleSource = function (source, tech) {
 13699      var srcParts = Flash.streamToParts(source.src);
 13700  
 13701      tech['setRtmpConnection'](srcParts.connection);
 13702      tech['setRtmpStream'](srcParts.stream);
 13703    };
 13704  
 13705    // Register the native source handler
 13706    Flash.registerSourceHandler(Flash.rtmpSourceHandler);
 13707  
 13708    return Flash;
 13709  }
 13710  
 13711  exports['default'] = FlashRtmpDecorator;
 13712  module.exports = exports['default'];
 13713  
 13714  },{}],118:[function(_dereq_,module,exports){
 13715  /**
 13716   * @file flash.js
 13717   * VideoJS-SWF - Custom Flash Player with HTML5-ish API
 13718   * https://github.com/zencoder/video-js-swf
 13719   * Not using setupTriggers. Using global onEvent func to distribute events
 13720   */
 13721  
 13722  'use strict';
 13723  
 13724  exports.__esModule = true;
 13725  
 13726  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 13727  
 13728  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 13729  
 13730  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 13731  
 13732  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 13733  
 13734  var _tech = _dereq_('./tech');
 13735  
 13736  var _tech2 = _interopRequireDefault(_tech);
 13737  
 13738  var _utilsDomJs = _dereq_('../utils/dom.js');
 13739  
 13740  var Dom = _interopRequireWildcard(_utilsDomJs);
 13741  
 13742  var _utilsUrlJs = _dereq_('../utils/url.js');
 13743  
 13744  var Url = _interopRequireWildcard(_utilsUrlJs);
 13745  
 13746  var _utilsTimeRangesJs = _dereq_('../utils/time-ranges.js');
 13747  
 13748  var _flashRtmp = _dereq_('./flash-rtmp');
 13749  
 13750  var _flashRtmp2 = _interopRequireDefault(_flashRtmp);
 13751  
 13752  var _component = _dereq_('../component');
 13753  
 13754  var _component2 = _interopRequireDefault(_component);
 13755  
 13756  var _globalWindow = _dereq_('global/window');
 13757  
 13758  var _globalWindow2 = _interopRequireDefault(_globalWindow);
 13759  
 13760  var _objectAssign = _dereq_('object.assign');
 13761  
 13762  var _objectAssign2 = _interopRequireDefault(_objectAssign);
 13763  
 13764  var navigator = _globalWindow2['default'].navigator;
 13765  /**
 13766   * Flash Media Controller - Wrapper for fallback SWF API
 13767   *
 13768   * @param {Object=} options Object of option names and values
 13769   * @param {Function=} ready Ready callback function
 13770   * @extends Tech
 13771   * @class Flash
 13772   */
 13773  
 13774  var Flash = (function (_Tech) {
 13775    _inherits(Flash, _Tech);
 13776  
 13777    function Flash(options, ready) {
 13778      _classCallCheck(this, Flash);
 13779  
 13780      _Tech.call(this, options, ready);
 13781  
 13782      // Set the source when ready
 13783      if (options.source) {
 13784        this.ready(function () {
 13785          this.setSource(options.source);
 13786        }, true);
 13787      }
 13788  
 13789      // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers
 13790      // This allows resetting the playhead when we catch the reload
 13791      if (options.startTime) {
 13792        this.ready(function () {
 13793          this.load();
 13794          this.play();
 13795          this.currentTime(options.startTime);
 13796        }, true);
 13797      }
 13798  
 13799      // Add global window functions that the swf expects
 13800      // A 4.x workflow we weren't able to solve for in 5.0
 13801      // because of the need to hard code these functions
 13802      // into the swf for security reasons
 13803      _globalWindow2['default'].videojs = _globalWindow2['default'].videojs || {};
 13804      _globalWindow2['default'].videojs.Flash = _globalWindow2['default'].videojs.Flash || {};
 13805      _globalWindow2['default'].videojs.Flash.onReady = Flash.onReady;
 13806      _globalWindow2['default'].videojs.Flash.onEvent = Flash.onEvent;
 13807      _globalWindow2['default'].videojs.Flash.onError = Flash.onError;
 13808  
 13809      this.on('seeked', function () {
 13810        this.lastSeekTarget_ = undefined;
 13811      });
 13812    }
 13813  
 13814    // Create setters and getters for attributes
 13815  
 13816    /**
 13817     * Create the component's DOM element
 13818     *
 13819     * @return {Element}
 13820     * @method createEl
 13821     */
 13822  
 13823    Flash.prototype.createEl = function createEl() {
 13824      var options = this.options_;
 13825  
 13826      // If video.js is hosted locally you should also set the location
 13827      // for the hosted swf, which should be relative to the page (not video.js)
 13828      // Otherwise this adds a CDN url.
 13829      // The CDN also auto-adds a swf URL for that specific version.
 13830      if (!options.swf) {
 13831        options.swf = '//vjs.zencdn.net/swf/5.0.1/video-js.swf';
 13832      }
 13833  
 13834      // Generate ID for swf object
 13835      var objId = options.techId;
 13836  
 13837      // Merge default flashvars with ones passed in to init
 13838      var flashVars = _objectAssign2['default']({
 13839  
 13840        // SWF Callback Functions
 13841        'readyFunction': 'videojs.Flash.onReady',
 13842        'eventProxyFunction': 'videojs.Flash.onEvent',
 13843        'errorEventProxyFunction': 'videojs.Flash.onError',
 13844  
 13845        // Player Settings
 13846        'autoplay': options.autoplay,
 13847        'preload': options.preload,
 13848        'loop': options.loop,
 13849        'muted': options.muted
 13850  
 13851      }, options.flashVars);
 13852  
 13853      // Merge default parames with ones passed in
 13854      var params = _objectAssign2['default']({
 13855        'wmode': 'opaque', // Opaque is needed to overlay controls, but can affect playback performance
 13856        'bgcolor': '#000000' // Using bgcolor prevents a white flash when the object is loading
 13857      }, options.params);
 13858  
 13859      // Merge default attributes with ones passed in
 13860      var attributes = _objectAssign2['default']({
 13861        'id': objId,
 13862        'name': objId, // Both ID and Name needed or swf to identify itself
 13863        'class': 'vjs-tech'
 13864      }, options.attributes);
 13865  
 13866      this.el_ = Flash.embed(options.swf, flashVars, params, attributes);
 13867      this.el_.tech = this;
 13868  
 13869      return this.el_;
 13870    };
 13871  
 13872    /**
 13873     * Play for flash tech
 13874     *
 13875     * @method play
 13876     */
 13877  
 13878    Flash.prototype.play = function play() {
 13879      if (this.ended()) {
 13880        this.setCurrentTime(0);
 13881      }
 13882      this.el_.vjs_play();
 13883    };
 13884  
 13885    /**
 13886     * Pause for flash tech
 13887     *
 13888     * @method pause
 13889     */
 13890  
 13891    Flash.prototype.pause = function pause() {
 13892      this.el_.vjs_pause();
 13893    };
 13894  
 13895    /**
 13896     * Get/set video
 13897     *
 13898     * @param {Object=} src Source object
 13899     * @return {Object}
 13900     * @method src
 13901     */
 13902  
 13903    Flash.prototype.src = function src(_src) {
 13904      if (_src === undefined) {
 13905        return this.currentSrc();
 13906      }
 13907  
 13908      // Setting src through `src` not `setSrc` will be deprecated
 13909      return this.setSrc(_src);
 13910    };
 13911  
 13912    /**
 13913     * Set video
 13914     *
 13915     * @param {Object=} src Source object
 13916     * @deprecated
 13917     * @method setSrc
 13918     */
 13919  
 13920    Flash.prototype.setSrc = function setSrc(src) {
 13921      // Make sure source URL is absolute.
 13922      src = Url.getAbsoluteURL(src);
 13923      this.el_.vjs_src(src);
 13924  
 13925      // Currently the SWF doesn't autoplay if you load a source later.
 13926      // e.g. Load player w/ no source, wait 2s, set src.
 13927      if (this.autoplay()) {
 13928        var tech = this;
 13929        this.setTimeout(function () {
 13930          tech.play();
 13931        }, 0);
 13932      }
 13933    };
 13934  
 13935    /**
 13936     * Returns true if the tech is currently seeking.
 13937     * @return {boolean} true if seeking
 13938     */
 13939  
 13940    Flash.prototype.seeking = function seeking() {
 13941      return this.lastSeekTarget_ !== undefined;
 13942    };
 13943  
 13944    /**
 13945     * Set current time
 13946     *
 13947     * @param {Number} time Current time of video
 13948     * @method setCurrentTime
 13949     */
 13950  
 13951    Flash.prototype.setCurrentTime = function setCurrentTime(time) {
 13952      var seekable = this.seekable();
 13953      if (seekable.length) {
 13954        // clamp to the current seekable range
 13955        time = time > seekable.start(0) ? time : seekable.start(0);
 13956        time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1);
 13957  
 13958        this.lastSeekTarget_ = time;
 13959        this.trigger('seeking');
 13960        this.el_.vjs_setProperty('currentTime', time);
 13961        _Tech.prototype.setCurrentTime.call(this);
 13962      }
 13963    };
 13964  
 13965    /**
 13966     * Get current time
 13967     *
 13968     * @param {Number=} time Current time of video
 13969     * @return {Number} Current time
 13970     * @method currentTime
 13971     */
 13972  
 13973    Flash.prototype.currentTime = function currentTime(time) {
 13974      // when seeking make the reported time keep up with the requested time
 13975      // by reading the time we're seeking to
 13976      if (this.seeking()) {
 13977        return this.lastSeekTarget_ || 0;
 13978      }
 13979      return this.el_.vjs_getProperty('currentTime');
 13980    };
 13981  
 13982    /**
 13983     * Get current source
 13984     *
 13985     * @method currentSrc
 13986     */
 13987  
 13988    Flash.prototype.currentSrc = function currentSrc() {
 13989      if (this.currentSource_) {
 13990        return this.currentSource_.src;
 13991      } else {
 13992        return this.el_.vjs_getProperty('currentSrc');
 13993      }
 13994    };
 13995  
 13996    /**
 13997     * Load media into player
 13998     *
 13999     * @method load
 14000     */
 14001  
 14002    Flash.prototype.load = function load() {
 14003      this.el_.vjs_load();
 14004    };
 14005  
 14006    /**
 14007     * Get poster
 14008     *
 14009     * @method poster
 14010     */
 14011  
 14012    Flash.prototype.poster = function poster() {
 14013      this.el_.vjs_getProperty('poster');
 14014    };
 14015  
 14016    /**
 14017     * Poster images are not handled by the Flash tech so make this a no-op
 14018     *
 14019     * @method setPoster
 14020     */
 14021  
 14022    Flash.prototype.setPoster = function setPoster() {};
 14023  
 14024    /**
 14025     * Determine if can seek in media
 14026     *
 14027     * @return {TimeRangeObject}
 14028     * @method seekable
 14029     */
 14030  
 14031    Flash.prototype.seekable = function seekable() {
 14032      var duration = this.duration();
 14033      if (duration === 0) {
 14034        return _utilsTimeRangesJs.createTimeRange();
 14035      }
 14036      return _utilsTimeRangesJs.createTimeRange(0, duration);
 14037    };
 14038  
 14039    /**
 14040     * Get buffered time range
 14041     *
 14042     * @return {TimeRangeObject}
 14043     * @method buffered
 14044     */
 14045  
 14046    Flash.prototype.buffered = function buffered() {
 14047      var ranges = this.el_.vjs_getProperty('buffered');
 14048      if (ranges.length === 0) {
 14049        return _utilsTimeRangesJs.createTimeRange();
 14050      }
 14051      return _utilsTimeRangesJs.createTimeRange(ranges[0][0], ranges[0][1]);
 14052    };
 14053  
 14054    /**
 14055     * Get fullscreen support -
 14056     * Flash does not allow fullscreen through javascript
 14057     * so always returns false
 14058     *
 14059     * @return {Boolean} false
 14060     * @method supportsFullScreen
 14061     */
 14062  
 14063    Flash.prototype.supportsFullScreen = function supportsFullScreen() {
 14064      return false; // Flash does not allow fullscreen through javascript
 14065    };
 14066  
 14067    /**
 14068     * Request to enter fullscreen
 14069     * Flash does not allow fullscreen through javascript
 14070     * so always returns false
 14071     *
 14072     * @return {Boolean} false
 14073     * @method enterFullScreen
 14074     */
 14075  
 14076    Flash.prototype.enterFullScreen = function enterFullScreen() {
 14077      return false;
 14078    };
 14079  
 14080    return Flash;
 14081  })(_tech2['default']);
 14082  
 14083  var _api = Flash.prototype;
 14084  var _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(',');
 14085  var _readOnly = 'networkState,readyState,initialTime,duration,startOffsetTime,paused,ended,videoTracks,audioTracks,videoWidth,videoHeight'.split(',');
 14086  
 14087  function _createSetter(attr) {
 14088    var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
 14089    _api['set' + attrUpper] = function (val) {
 14090      return this.el_.vjs_setProperty(attr, val);
 14091    };
 14092  }
 14093  function _createGetter(attr) {
 14094    _api[attr] = function () {
 14095      return this.el_.vjs_getProperty(attr);
 14096    };
 14097  }
 14098  
 14099  // Create getter and setters for all read/write attributes
 14100  for (var i = 0; i < _readWrite.length; i++) {
 14101    _createGetter(_readWrite[i]);
 14102    _createSetter(_readWrite[i]);
 14103  }
 14104  
 14105  // Create getters for read-only attributes
 14106  for (var i = 0; i < _readOnly.length; i++) {
 14107    _createGetter(_readOnly[i]);
 14108  }
 14109  
 14110  /* Flash Support Testing -------------------------------------------------------- */
 14111  
 14112  Flash.isSupported = function () {
 14113    return Flash.version()[0] >= 10;
 14114    // return swfobject.hasFlashPlayerVersion('10');
 14115  };
 14116  
 14117  // Add Source Handler pattern functions to this tech
 14118  _tech2['default'].withSourceHandlers(Flash);
 14119  
 14120  /*
 14121   * The default native source handler.
 14122   * This simply passes the source to the video element. Nothing fancy.
 14123   *
 14124   * @param  {Object} source   The source object
 14125   * @param  {Flash} tech  The instance of the Flash tech
 14126   */
 14127  Flash.nativeSourceHandler = {};
 14128  
 14129  /**
 14130   * Check if Flash can play the given videotype
 14131   * @param  {String} type    The mimetype to check
 14132   * @return {String}         'probably', 'maybe', or '' (empty string)
 14133   */
 14134  Flash.nativeSourceHandler.canPlayType = function (type) {
 14135    if (type in Flash.formats) {
 14136      return 'maybe';
 14137    }
 14138  
 14139    return '';
 14140  };
 14141  
 14142  /*
 14143   * Check Flash can handle the source natively
 14144   *
 14145   * @param  {Object} source  The source object
 14146   * @return {String}         'probably', 'maybe', or '' (empty string)
 14147   */
 14148  Flash.nativeSourceHandler.canHandleSource = function (source) {
 14149    var type;
 14150  
 14151    function guessMimeType(src) {
 14152      var ext = Url.getFileExtension(src);
 14153      if (ext) {
 14154        return 'video/' + ext;
 14155      }
 14156      return '';
 14157    }
 14158  
 14159    if (!source.type) {
 14160      type = guessMimeType(source.src);
 14161    } else {
 14162      // Strip code information from the type because we don't get that specific
 14163      type = source.type.replace(/;.*/, '').toLowerCase();
 14164    }
 14165  
 14166    return Flash.nativeSourceHandler.canPlayType(type);
 14167  };
 14168  
 14169  /*
 14170   * Pass the source to the flash object
 14171   * Adaptive source handlers will have more complicated workflows before passing
 14172   * video data to the video element
 14173   *
 14174   * @param  {Object} source    The source object
 14175   * @param  {Flash} tech   The instance of the Flash tech
 14176   */
 14177  Flash.nativeSourceHandler.handleSource = function (source, tech) {
 14178    tech.setSrc(source.src);
 14179  };
 14180  
 14181  /*
 14182   * Clean up the source handler when disposing the player or switching sources..
 14183   * (no cleanup is needed when supporting the format natively)
 14184   */
 14185  Flash.nativeSourceHandler.dispose = function () {};
 14186  
 14187  // Register the native source handler
 14188  Flash.registerSourceHandler(Flash.nativeSourceHandler);
 14189  
 14190  Flash.formats = {
 14191    'video/flv': 'FLV',
 14192    'video/x-flv': 'FLV',
 14193    'video/mp4': 'MP4',
 14194    'video/m4v': 'MP4'
 14195  };
 14196  
 14197  Flash.onReady = function (currSwf) {
 14198    var el = Dom.getEl(currSwf);
 14199    var tech = el && el.tech;
 14200  
 14201    // if there is no el then the tech has been disposed
 14202    // and the tech element was removed from the player div
 14203    if (tech && tech.el()) {
 14204      // check that the flash object is really ready
 14205      Flash.checkReady(tech);
 14206    }
 14207  };
 14208  
 14209  // The SWF isn't always ready when it says it is. Sometimes the API functions still need to be added to the object.
 14210  // If it's not ready, we set a timeout to check again shortly.
 14211  Flash.checkReady = function (tech) {
 14212    // stop worrying if the tech has been disposed
 14213    if (!tech.el()) {
 14214      return;
 14215    }
 14216  
 14217    // check if API property exists
 14218    if (tech.el().vjs_getProperty) {
 14219      // tell tech it's ready
 14220      tech.triggerReady();
 14221    } else {
 14222      // wait longer
 14223      this.setTimeout(function () {
 14224        Flash['checkReady'](tech);
 14225      }, 50);
 14226    }
 14227  };
 14228  
 14229  // Trigger events from the swf on the player
 14230  Flash.onEvent = function (swfID, eventName) {
 14231    var tech = Dom.getEl(swfID).tech;
 14232    tech.trigger(eventName);
 14233  };
 14234  
 14235  // Log errors from the swf
 14236  Flash.onError = function (swfID, err) {
 14237    var tech = Dom.getEl(swfID).tech;
 14238  
 14239    // trigger MEDIA_ERR_SRC_NOT_SUPPORTED
 14240    if (err === 'srcnotfound') {
 14241      return tech.error(4);
 14242    }
 14243  
 14244    // trigger a custom error
 14245    tech.error('FLASH: ' + err);
 14246  };
 14247  
 14248  // Flash Version Check
 14249  Flash.version = function () {
 14250    var version = '0,0,0';
 14251  
 14252    // IE
 14253    try {
 14254      version = new _globalWindow2['default'].ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
 14255  
 14256      // other browsers
 14257    } catch (e) {
 14258      try {
 14259        if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) {
 14260          version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
 14261        }
 14262      } catch (err) {}
 14263    }
 14264    return version.split(',');
 14265  };
 14266  
 14267  // Flash embedding method. Only used in non-iframe mode
 14268  Flash.embed = function (swf, flashVars, params, attributes) {
 14269    var code = Flash.getEmbedCode(swf, flashVars, params, attributes);
 14270  
 14271    // Get element by embedding code and retrieving created element
 14272    var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0];
 14273  
 14274    return obj;
 14275  };
 14276  
 14277  Flash.getEmbedCode = function (swf, flashVars, params, attributes) {
 14278    var objTag = '<object type="application/x-shockwave-flash" ';
 14279    var flashVarsString = '';
 14280    var paramsString = '';
 14281    var attrsString = '';
 14282  
 14283    // Convert flash vars to string
 14284    if (flashVars) {
 14285      Object.getOwnPropertyNames(flashVars).forEach(function (key) {
 14286        flashVarsString += key + '=' + flashVars[key] + '&amp;';
 14287      });
 14288    }
 14289  
 14290    // Add swf, flashVars, and other default params
 14291    params = _objectAssign2['default']({
 14292      'movie': swf,
 14293      'flashvars': flashVarsString,
 14294      'allowScriptAccess': 'always', // Required to talk to swf
 14295      'allowNetworking': 'all' // All should be default, but having security issues.
 14296    }, params);
 14297  
 14298    // Create param tags string
 14299    Object.getOwnPropertyNames(params).forEach(function (key) {
 14300      paramsString += '<param name="' + key + '" value="' + params[key] + '" />';
 14301    });
 14302  
 14303    attributes = _objectAssign2['default']({
 14304      // Add swf to attributes (need both for IE and Others to work)
 14305      'data': swf,
 14306  
 14307      // Default to 100% width/height
 14308      'width': '100%',
 14309      'height': '100%'
 14310  
 14311    }, attributes);
 14312  
 14313    // Create Attributes string
 14314    Object.getOwnPropertyNames(attributes).forEach(function (key) {
 14315      attrsString += key + '="' + attributes[key] + '" ';
 14316    });
 14317  
 14318    return '' + objTag + attrsString + '>' + paramsString + '</object>';
 14319  };
 14320  
 14321  // Run Flash through the RTMP decorator
 14322  _flashRtmp2['default'](Flash);
 14323  
 14324  _component2['default'].registerComponent('Flash', Flash);
 14325  _tech2['default'].registerTech('Flash', Flash);
 14326  exports['default'] = Flash;
 14327  module.exports = exports['default'];
 14328  
 14329  },{"../component":67,"../utils/dom.js":134,"../utils/time-ranges.js":142,"../utils/url.js":144,"./flash-rtmp":117,"./tech":121,"global/window":2,"object.assign":45}],119:[function(_dereq_,module,exports){
 14330  /**
 14331   * @file html5.js
 14332   * HTML5 Media Controller - Wrapper for HTML5 Media API
 14333   */
 14334  
 14335  'use strict';
 14336  
 14337  exports.__esModule = true;
 14338  
 14339  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 14340  
 14341  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 14342  
 14343  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 14344  
 14345  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 14346  
 14347  var _techJs = _dereq_('./tech.js');
 14348  
 14349  var _techJs2 = _interopRequireDefault(_techJs);
 14350  
 14351  var _component = _dereq_('../component');
 14352  
 14353  var _component2 = _interopRequireDefault(_component);
 14354  
 14355  var _utilsDomJs = _dereq_('../utils/dom.js');
 14356  
 14357  var Dom = _interopRequireWildcard(_utilsDomJs);
 14358  
 14359  var _utilsUrlJs = _dereq_('../utils/url.js');
 14360  
 14361  var Url = _interopRequireWildcard(_utilsUrlJs);
 14362  
 14363  var _utilsFnJs = _dereq_('../utils/fn.js');
 14364  
 14365  var Fn = _interopRequireWildcard(_utilsFnJs);
 14366  
 14367  var _utilsLogJs = _dereq_('../utils/log.js');
 14368  
 14369  var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
 14370  
 14371  var _utilsBrowserJs = _dereq_('../utils/browser.js');
 14372  
 14373  var browser = _interopRequireWildcard(_utilsBrowserJs);
 14374  
 14375  var _globalDocument = _dereq_('global/document');
 14376  
 14377  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 14378  
 14379  var _globalWindow = _dereq_('global/window');
 14380  
 14381  var _globalWindow2 = _interopRequireDefault(_globalWindow);
 14382  
 14383  var _objectAssign = _dereq_('object.assign');
 14384  
 14385  var _objectAssign2 = _interopRequireDefault(_objectAssign);
 14386  
 14387  var _utilsMergeOptionsJs = _dereq_('../utils/merge-options.js');
 14388  
 14389  var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);
 14390  
 14391  /**
 14392   * HTML5 Media Controller - Wrapper for HTML5 Media API
 14393   *
 14394   * @param {Object=} options Object of option names and values
 14395   * @param {Function=} ready Ready callback function
 14396   * @extends Tech
 14397   * @class Html5
 14398   */
 14399  
 14400  var Html5 = (function (_Tech) {
 14401    _inherits(Html5, _Tech);
 14402  
 14403    function Html5(options, ready) {
 14404      _classCallCheck(this, Html5);
 14405  
 14406      _Tech.call(this, options, ready);
 14407  
 14408      var source = options.source;
 14409  
 14410      // Set the source if one is provided
 14411      // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted)
 14412      // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source
 14413      // anyway so the error gets fired.
 14414      if (source && (this.el_.currentSrc !== source.src || options.tag && options.tag.initNetworkState_ === 3)) {
 14415        this.setSource(source);
 14416      } else {
 14417        this.handleLateInit_(this.el_);
 14418      }
 14419  
 14420      if (this.el_.hasChildNodes()) {
 14421  
 14422        var nodes = this.el_.childNodes;
 14423        var nodesLength = nodes.length;
 14424        var removeNodes = [];
 14425  
 14426        while (nodesLength--) {
 14427          var node = nodes[nodesLength];
 14428          var nodeName = node.nodeName.toLowerCase();
 14429  
 14430          if (nodeName === 'track') {
 14431            if (!this.featuresNativeTextTracks) {
 14432              // Empty video tag tracks so the built-in player doesn't use them also.
 14433              // This may not be fast enough to stop HTML5 browsers from reading the tags
 14434              // so we'll need to turn off any default tracks if we're manually doing
 14435              // captions and subtitles. videoElement.textTracks
 14436              removeNodes.push(node);
 14437            } else {
 14438              // store HTMLTrackElement and TextTrack to remote list
 14439              this.remoteTextTrackEls().addTrackElement_(node);
 14440              this.remoteTextTracks().addTrack_(node.track);
 14441            }
 14442          }
 14443        }
 14444  
 14445        for (var i = 0; i < removeNodes.length; i++) {
 14446          this.el_.removeChild(removeNodes[i]);
 14447        }
 14448      }
 14449  
 14450      if (this.featuresNativeTextTracks) {
 14451        this.handleTextTrackChange_ = Fn.bind(this, this.handleTextTrackChange);
 14452        this.handleTextTrackAdd_ = Fn.bind(this, this.handleTextTrackAdd);
 14453        this.handleTextTrackRemove_ = Fn.bind(this, this.handleTextTrackRemove);
 14454        this.proxyNativeTextTracks_();
 14455      }
 14456  
 14457      // Determine if native controls should be used
 14458      // Our goal should be to get the custom controls on mobile solid everywhere
 14459      // so we can remove this all together. Right now this will block custom
 14460      // controls on touch enabled laptops like the Chrome Pixel
 14461      if (browser.TOUCH_ENABLED && options.nativeControlsForTouch === true || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) {
 14462        this.setControls(true);
 14463      }
 14464  
 14465      this.triggerReady();
 14466    }
 14467  
 14468    /* HTML5 Support Testing ---------------------------------------------------- */
 14469  
 14470    /*
 14471    * Element for testing browser HTML5 video capabilities
 14472    *
 14473    * @type {Element}
 14474    * @constant
 14475    * @private
 14476    */
 14477  
 14478    /**
 14479     * Dispose of html5 media element
 14480     *
 14481     * @method dispose
 14482     */
 14483  
 14484    Html5.prototype.dispose = function dispose() {
 14485      var tt = this.el().textTracks;
 14486      var emulatedTt = this.textTracks();
 14487  
 14488      // remove native event listeners
 14489      if (tt && tt.removeEventListener) {
 14490        tt.removeEventListener('change', this.handleTextTrackChange_);
 14491        tt.removeEventListener('addtrack', this.handleTextTrackAdd_);
 14492        tt.removeEventListener('removetrack', this.handleTextTrackRemove_);
 14493      }
 14494  
 14495      // clearout the emulated text track list.
 14496      var i = emulatedTt.length;
 14497  
 14498      while (i--) {
 14499        emulatedTt.removeTrack_(emulatedTt[i]);
 14500      }
 14501  
 14502      Html5.disposeMediaElement(this.el_);
 14503      _Tech.prototype.dispose.call(this);
 14504    };
 14505  
 14506    /**
 14507     * Create the component's DOM element
 14508     *
 14509     * @return {Element}
 14510     * @method createEl
 14511     */
 14512  
 14513    Html5.prototype.createEl = function createEl() {
 14514      var el = this.options_.tag;
 14515  
 14516      // Check if this browser supports moving the element into the box.
 14517      // On the iPhone video will break if you move the element,
 14518      // So we have to create a brand new element.
 14519      if (!el || this['movingMediaElementInDOM'] === false) {
 14520  
 14521        // If the original tag is still there, clone and remove it.
 14522        if (el) {
 14523          var clone = el.cloneNode(true);
 14524          el.parentNode.insertBefore(clone, el);
 14525          Html5.disposeMediaElement(el);
 14526          el = clone;
 14527        } else {
 14528          el = _globalDocument2['default'].createElement('video');
 14529  
 14530          // determine if native controls should be used
 14531          var tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag);
 14532          var attributes = _utilsMergeOptionsJs2['default']({}, tagAttributes);
 14533          if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) {
 14534            delete attributes.controls;
 14535          }
 14536  
 14537          Dom.setElAttributes(el, _objectAssign2['default'](attributes, {
 14538            id: this.options_.techId,
 14539            'class': 'vjs-tech'
 14540          }));
 14541        }
 14542      }
 14543  
 14544      // Update specific tag settings, in case they were overridden
 14545      var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted'];
 14546      for (var i = settingsAttrs.length - 1; i >= 0; i--) {
 14547        var attr = settingsAttrs[i];
 14548        var overwriteAttrs = {};
 14549        if (typeof this.options_[attr] !== 'undefined') {
 14550          overwriteAttrs[attr] = this.options_[attr];
 14551        }
 14552        Dom.setElAttributes(el, overwriteAttrs);
 14553      }
 14554  
 14555      return el;
 14556      // jenniisawesome = true;
 14557    };
 14558  
 14559    // If we're loading the playback object after it has started loading
 14560    // or playing the video (often with autoplay on) then the loadstart event
 14561    // has already fired and we need to fire it manually because many things
 14562    // rely on it.
 14563  
 14564    Html5.prototype.handleLateInit_ = function handleLateInit_(el) {
 14565      var _this = this;
 14566  
 14567      if (el.networkState === 0 || el.networkState === 3) {
 14568        // The video element hasn't started loading the source yet
 14569        // or didn't find a source
 14570        return;
 14571      }
 14572  
 14573      if (el.readyState === 0) {
 14574        var _ret = (function () {
 14575          // NetworkState is set synchronously BUT loadstart is fired at the
 14576          // end of the current stack, usually before setInterval(fn, 0).
 14577          // So at this point we know loadstart may have already fired or is
 14578          // about to fire, and either way the player hasn't seen it yet.
 14579          // We don't want to fire loadstart prematurely here and cause a
 14580          // double loadstart so we'll wait and see if it happens between now
 14581          // and the next loop, and fire it if not.
 14582          // HOWEVER, we also want to make sure it fires before loadedmetadata
 14583          // which could also happen between now and the next loop, so we'll
 14584          // watch for that also.
 14585          var loadstartFired = false;
 14586          var setLoadstartFired = function setLoadstartFired() {
 14587            loadstartFired = true;
 14588          };
 14589          _this.on('loadstart', setLoadstartFired);
 14590  
 14591          var triggerLoadstart = function triggerLoadstart() {
 14592            // We did miss the original loadstart. Make sure the player
 14593            // sees loadstart before loadedmetadata
 14594            if (!loadstartFired) {
 14595              this.trigger('loadstart');
 14596            }
 14597          };
 14598          _this.on('loadedmetadata', triggerLoadstart);
 14599  
 14600          _this.ready(function () {
 14601            this.off('loadstart', setLoadstartFired);
 14602            this.off('loadedmetadata', triggerLoadstart);
 14603  
 14604            if (!loadstartFired) {
 14605              // We did miss the original native loadstart. Fire it now.
 14606              this.trigger('loadstart');
 14607            }
 14608          });
 14609  
 14610          return {
 14611            v: undefined
 14612          };
 14613        })();
 14614  
 14615        if (typeof _ret === 'object') return _ret.v;
 14616      }
 14617  
 14618      // From here on we know that loadstart already fired and we missed it.
 14619      // The other readyState events aren't as much of a problem if we double
 14620      // them, so not going to go to as much trouble as loadstart to prevent
 14621      // that unless we find reason to.
 14622      var eventsToTrigger = ['loadstart'];
 14623  
 14624      // loadedmetadata: newly equal to HAVE_METADATA (1) or greater
 14625      eventsToTrigger.push('loadedmetadata');
 14626  
 14627      // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater
 14628      if (el.readyState >= 2) {
 14629        eventsToTrigger.push('loadeddata');
 14630      }
 14631  
 14632      // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater
 14633      if (el.readyState >= 3) {
 14634        eventsToTrigger.push('canplay');
 14635      }
 14636  
 14637      // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4)
 14638      if (el.readyState >= 4) {
 14639        eventsToTrigger.push('canplaythrough');
 14640      }
 14641  
 14642      // We still need to give the player time to add event listeners
 14643      this.ready(function () {
 14644        eventsToTrigger.forEach(function (type) {
 14645          this.trigger(type);
 14646        }, this);
 14647      });
 14648    };
 14649  
 14650    Html5.prototype.proxyNativeTextTracks_ = function proxyNativeTextTracks_() {
 14651      var tt = this.el().textTracks;
 14652  
 14653      if (tt) {
 14654        // Add tracks - if player is initialised after DOM loaded, textTracks
 14655        // will not trigger addtrack
 14656        for (var i = 0; i < tt.length; i++) {
 14657          this.textTracks().addTrack_(tt[i]);
 14658        }
 14659  
 14660        if (tt.addEventListener) {
 14661          tt.addEventListener('change', this.handleTextTrackChange_);
 14662          tt.addEventListener('addtrack', this.handleTextTrackAdd_);
 14663          tt.addEventListener('removetrack', this.handleTextTrackRemove_);
 14664        }
 14665      }
 14666    };
 14667  
 14668    Html5.prototype.handleTextTrackChange = function handleTextTrackChange(e) {
 14669      var tt = this.textTracks();
 14670      this.textTracks().trigger({
 14671        type: 'change',
 14672        target: tt,
 14673        currentTarget: tt,
 14674        srcElement: tt
 14675      });
 14676    };
 14677  
 14678    Html5.prototype.handleTextTrackAdd = function handleTextTrackAdd(e) {
 14679      this.textTracks().addTrack_(e.track);
 14680    };
 14681  
 14682    Html5.prototype.handleTextTrackRemove = function handleTextTrackRemove(e) {
 14683      this.textTracks().removeTrack_(e.track);
 14684    };
 14685  
 14686    /**
 14687     * Play for html5 tech
 14688     *
 14689     * @method play
 14690     */
 14691  
 14692    Html5.prototype.play = function play() {
 14693      this.el_.play();
 14694    };
 14695  
 14696    /**
 14697     * Pause for html5 tech
 14698     *
 14699     * @method pause
 14700     */
 14701  
 14702    Html5.prototype.pause = function pause() {
 14703      this.el_.pause();
 14704    };
 14705  
 14706    /**
 14707     * Paused for html5 tech
 14708     *
 14709     * @return {Boolean}
 14710     * @method paused
 14711     */
 14712  
 14713    Html5.prototype.paused = function paused() {
 14714      return this.el_.paused;
 14715    };
 14716  
 14717    /**
 14718     * Get current time
 14719     *
 14720     * @return {Number}
 14721     * @method currentTime
 14722     */
 14723  
 14724    Html5.prototype.currentTime = function currentTime() {
 14725      return this.el_.currentTime;
 14726    };
 14727  
 14728    /**
 14729     * Set current time
 14730     *
 14731     * @param {Number} seconds Current time of video
 14732     * @method setCurrentTime
 14733     */
 14734  
 14735    Html5.prototype.setCurrentTime = function setCurrentTime(seconds) {
 14736      try {
 14737        this.el_.currentTime = seconds;
 14738      } catch (e) {
 14739        _utilsLogJs2['default'](e, 'Video is not ready. (Video.js)');
 14740        // this.warning(VideoJS.warnings.videoNotReady);
 14741      }
 14742    };
 14743  
 14744    /**
 14745     * Get duration
 14746     *
 14747     * @return {Number}
 14748     * @method duration
 14749     */
 14750  
 14751    Html5.prototype.duration = function duration() {
 14752      return this.el_.duration || 0;
 14753    };
 14754  
 14755    /**
 14756     * Get a TimeRange object that represents the intersection
 14757     * of the time ranges for which the user agent has all
 14758     * relevant media
 14759     *
 14760     * @return {TimeRangeObject}
 14761     * @method buffered
 14762     */
 14763  
 14764    Html5.prototype.buffered = function buffered() {
 14765      return this.el_.buffered;
 14766    };
 14767  
 14768    /**
 14769     * Get volume level
 14770     *
 14771     * @return {Number}
 14772     * @method volume
 14773     */
 14774  
 14775    Html5.prototype.volume = function volume() {
 14776      return this.el_.volume;
 14777    };
 14778  
 14779    /**
 14780     * Set volume level
 14781     *
 14782     * @param {Number} percentAsDecimal Volume percent as a decimal
 14783     * @method setVolume
 14784     */
 14785  
 14786    Html5.prototype.setVolume = function setVolume(percentAsDecimal) {
 14787      this.el_.volume = percentAsDecimal;
 14788    };
 14789  
 14790    /**
 14791     * Get if muted
 14792     *
 14793     * @return {Boolean}
 14794     * @method muted
 14795     */
 14796  
 14797    Html5.prototype.muted = function muted() {
 14798      return this.el_.muted;
 14799    };
 14800  
 14801    /**
 14802     * Set muted
 14803     *
 14804     * @param {Boolean} If player is to be muted or note
 14805     * @method setMuted
 14806     */
 14807  
 14808    Html5.prototype.setMuted = function setMuted(muted) {
 14809      this.el_.muted = muted;
 14810    };
 14811  
 14812    /**
 14813     * Get player width
 14814     *
 14815     * @return {Number}
 14816     * @method width
 14817     */
 14818  
 14819    Html5.prototype.width = function width() {
 14820      return this.el_.offsetWidth;
 14821    };
 14822  
 14823    /**
 14824     * Get player height
 14825     *
 14826     * @return {Number}
 14827     * @method height
 14828     */
 14829  
 14830    Html5.prototype.height = function height() {
 14831      return this.el_.offsetHeight;
 14832    };
 14833  
 14834    /**
 14835     * Get if there is fullscreen support
 14836     *
 14837     * @return {Boolean}
 14838     * @method supportsFullScreen
 14839     */
 14840  
 14841    Html5.prototype.supportsFullScreen = function supportsFullScreen() {
 14842      if (typeof this.el_.webkitEnterFullScreen === 'function') {
 14843        var userAgent = _globalWindow2['default'].navigator.userAgent;
 14844        // Seems to be broken in Chromium/Chrome && Safari in Leopard
 14845        if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) {
 14846          return true;
 14847        }
 14848      }
 14849      return false;
 14850    };
 14851  
 14852    /**
 14853     * Request to enter fullscreen
 14854     *
 14855     * @method enterFullScreen
 14856     */
 14857  
 14858    Html5.prototype.enterFullScreen = function enterFullScreen() {
 14859      var video = this.el_;
 14860  
 14861      if ('webkitDisplayingFullscreen' in video) {
 14862        this.one('webkitbeginfullscreen', function () {
 14863          this.one('webkitendfullscreen', function () {
 14864            this.trigger('fullscreenchange', { isFullscreen: false });
 14865          });
 14866  
 14867          this.trigger('fullscreenchange', { isFullscreen: true });
 14868        });
 14869      }
 14870  
 14871      if (video.paused && video.networkState <= video.HAVE_METADATA) {
 14872        // attempt to prime the video element for programmatic access
 14873        // this isn't necessary on the desktop but shouldn't hurt
 14874        this.el_.play();
 14875  
 14876        // playing and pausing synchronously during the transition to fullscreen
 14877        // can get iOS ~6.1 devices into a play/pause loop
 14878        this.setTimeout(function () {
 14879          video.pause();
 14880          video.webkitEnterFullScreen();
 14881        }, 0);
 14882      } else {
 14883        video.webkitEnterFullScreen();
 14884      }
 14885    };
 14886  
 14887    /**
 14888     * Request to exit fullscreen
 14889     *
 14890     * @method exitFullScreen
 14891     */
 14892  
 14893    Html5.prototype.exitFullScreen = function exitFullScreen() {
 14894      this.el_.webkitExitFullScreen();
 14895    };
 14896  
 14897    /**
 14898     * Get/set video
 14899     *
 14900     * @param {Object=} src Source object
 14901     * @return {Object}
 14902     * @method src
 14903     */
 14904  
 14905    Html5.prototype.src = function src(_src) {
 14906      if (_src === undefined) {
 14907        return this.el_.src;
 14908      } else {
 14909        // Setting src through `src` instead of `setSrc` will be deprecated
 14910        this.setSrc(_src);
 14911      }
 14912    };
 14913  
 14914    /**
 14915     * Set video
 14916     *
 14917     * @param {Object} src Source object
 14918     * @deprecated
 14919     * @method setSrc
 14920     */
 14921  
 14922    Html5.prototype.setSrc = function setSrc(src) {
 14923      this.el_.src = src;
 14924    };
 14925  
 14926    /**
 14927     * Load media into player
 14928     *
 14929     * @method load
 14930     */
 14931  
 14932    Html5.prototype.load = function load() {
 14933      this.el_.load();
 14934    };
 14935  
 14936    /**
 14937     * Reset the tech. Removes all sources and calls `load`.
 14938     *
 14939     * @method reset
 14940     */
 14941  
 14942    Html5.prototype.reset = function reset() {
 14943      Html5.resetMediaElement(this.el_);
 14944    };
 14945  
 14946    /**
 14947     * Get current source
 14948     *
 14949     * @return {Object}
 14950     * @method currentSrc
 14951     */
 14952  
 14953    Html5.prototype.currentSrc = function currentSrc() {
 14954      if (this.currentSource_) {
 14955        return this.currentSource_.src;
 14956      } else {
 14957        return this.el_.currentSrc;
 14958      }
 14959    };
 14960  
 14961    /**
 14962     * Get poster
 14963     *
 14964     * @return {String}
 14965     * @method poster
 14966     */
 14967  
 14968    Html5.prototype.poster = function poster() {
 14969      return this.el_.poster;
 14970    };
 14971  
 14972    /**
 14973     * Set poster
 14974     *
 14975     * @param {String} val URL to poster image
 14976     * @method
 14977     */
 14978  
 14979    Html5.prototype.setPoster = function setPoster(val) {
 14980      this.el_.poster = val;
 14981    };
 14982  
 14983    /**
 14984     * Get preload attribute
 14985     *
 14986     * @return {String}
 14987     * @method preload
 14988     */
 14989  
 14990    Html5.prototype.preload = function preload() {
 14991      return this.el_.preload;
 14992    };
 14993  
 14994    /**
 14995     * Set preload attribute
 14996     *
 14997     * @param {String} val Value for preload attribute
 14998     * @method setPreload
 14999     */
 15000  
 15001    Html5.prototype.setPreload = function setPreload(val) {
 15002      this.el_.preload = val;
 15003    };
 15004  
 15005    /**
 15006     * Get autoplay attribute
 15007     *
 15008     * @return {String}
 15009     * @method autoplay
 15010     */
 15011  
 15012    Html5.prototype.autoplay = function autoplay() {
 15013      return this.el_.autoplay;
 15014    };
 15015  
 15016    /**
 15017     * Set autoplay attribute
 15018     *
 15019     * @param {String} val Value for preload attribute
 15020     * @method setAutoplay
 15021     */
 15022  
 15023    Html5.prototype.setAutoplay = function setAutoplay(val) {
 15024      this.el_.autoplay = val;
 15025    };
 15026  
 15027    /**
 15028     * Get controls attribute
 15029     *
 15030     * @return {String}
 15031     * @method controls
 15032     */
 15033  
 15034    Html5.prototype.controls = function controls() {
 15035      return this.el_.controls;
 15036    };
 15037  
 15038    /**
 15039     * Set controls attribute
 15040     *
 15041     * @param {String} val Value for controls attribute
 15042     * @method setControls
 15043     */
 15044  
 15045    Html5.prototype.setControls = function setControls(val) {
 15046      this.el_.controls = !!val;
 15047    };
 15048  
 15049    /**
 15050     * Get loop attribute
 15051     *
 15052     * @return {String}
 15053     * @method loop
 15054     */
 15055  
 15056    Html5.prototype.loop = function loop() {
 15057      return this.el_.loop;
 15058    };
 15059  
 15060    /**
 15061     * Set loop attribute
 15062     *
 15063     * @param {String} val Value for loop attribute
 15064     * @method setLoop
 15065     */
 15066  
 15067    Html5.prototype.setLoop = function setLoop(val) {
 15068      this.el_.loop = val;
 15069    };
 15070  
 15071    /**
 15072     * Get error value
 15073     *
 15074     * @return {String}
 15075     * @method error
 15076     */
 15077  
 15078    Html5.prototype.error = function error() {
 15079      return this.el_.error;
 15080    };
 15081  
 15082    /**
 15083     * Get whether or not the player is in the "seeking" state
 15084     *
 15085     * @return {Boolean}
 15086     * @method seeking
 15087     */
 15088  
 15089    Html5.prototype.seeking = function seeking() {
 15090      return this.el_.seeking;
 15091    };
 15092  
 15093    /**
 15094     * Get a TimeRanges object that represents the
 15095     * ranges of the media resource to which it is possible
 15096     * for the user agent to seek.
 15097     *
 15098     * @return {TimeRangeObject}
 15099     * @method seekable
 15100     */
 15101  
 15102    Html5.prototype.seekable = function seekable() {
 15103      return this.el_.seekable;
 15104    };
 15105  
 15106    /**
 15107     * Get if video ended
 15108     *
 15109     * @return {Boolean}
 15110     * @method ended
 15111     */
 15112  
 15113    Html5.prototype.ended = function ended() {
 15114      return this.el_.ended;
 15115    };
 15116  
 15117    /**
 15118     * Get the value of the muted content attribute
 15119     * This attribute has no dynamic effect, it only
 15120     * controls the default state of the element
 15121     *
 15122     * @return {Boolean}
 15123     * @method defaultMuted
 15124     */
 15125  
 15126    Html5.prototype.defaultMuted = function defaultMuted() {
 15127      return this.el_.defaultMuted;
 15128    };
 15129  
 15130    /**
 15131     * Get desired speed at which the media resource is to play
 15132     *
 15133     * @return {Number}
 15134     * @method playbackRate
 15135     */
 15136  
 15137    Html5.prototype.playbackRate = function playbackRate() {
 15138      return this.el_.playbackRate;
 15139    };
 15140  
 15141    /**
 15142     * Returns a TimeRanges object that represents the ranges of the
 15143     * media resource that the user agent has played.
 15144     * @return {TimeRangeObject} the range of points on the media
 15145     * timeline that has been reached through normal playback
 15146     * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-played
 15147     */
 15148  
 15149    Html5.prototype.played = function played() {
 15150      return this.el_.played;
 15151    };
 15152  
 15153    /**
 15154     * Set desired speed at which the media resource is to play
 15155     *
 15156     * @param {Number} val Speed at which the media resource is to play
 15157     * @method setPlaybackRate
 15158     */
 15159  
 15160    Html5.prototype.setPlaybackRate = function setPlaybackRate(val) {
 15161      this.el_.playbackRate = val;
 15162    };
 15163  
 15164    /**
 15165     * Get the current state of network activity for the element, from
 15166     * the list below
 15167     * NETWORK_EMPTY (numeric value 0)
 15168     * NETWORK_IDLE (numeric value 1)
 15169     * NETWORK_LOADING (numeric value 2)
 15170     * NETWORK_NO_SOURCE (numeric value 3)
 15171     *
 15172     * @return {Number}
 15173     * @method networkState
 15174     */
 15175  
 15176    Html5.prototype.networkState = function networkState() {
 15177      return this.el_.networkState;
 15178    };
 15179  
 15180    /**
 15181     * Get a value that expresses the current state of the element
 15182     * with respect to rendering the current playback position, from
 15183     * the codes in the list below
 15184     * HAVE_NOTHING (numeric value 0)
 15185     * HAVE_METADATA (numeric value 1)
 15186     * HAVE_CURRENT_DATA (numeric value 2)
 15187     * HAVE_FUTURE_DATA (numeric value 3)
 15188     * HAVE_ENOUGH_DATA (numeric value 4)
 15189     *
 15190     * @return {Number}
 15191     * @method readyState
 15192     */
 15193  
 15194    Html5.prototype.readyState = function readyState() {
 15195      return this.el_.readyState;
 15196    };
 15197  
 15198    /**
 15199     * Get width of video
 15200     *
 15201     * @return {Number}
 15202     * @method videoWidth
 15203     */
 15204  
 15205    Html5.prototype.videoWidth = function videoWidth() {
 15206      return this.el_.videoWidth;
 15207    };
 15208  
 15209    /**
 15210     * Get height of video
 15211     *
 15212     * @return {Number}
 15213     * @method videoHeight
 15214     */
 15215  
 15216    Html5.prototype.videoHeight = function videoHeight() {
 15217      return this.el_.videoHeight;
 15218    };
 15219  
 15220    /**
 15221     * Get text tracks
 15222     *
 15223     * @return {TextTrackList}
 15224     * @method textTracks
 15225     */
 15226  
 15227    Html5.prototype.textTracks = function textTracks() {
 15228      return _Tech.prototype.textTracks.call(this);
 15229    };
 15230  
 15231    /**
 15232     * Creates and returns a text track object
 15233     *
 15234     * @param {String} kind Text track kind (subtitles, captions, descriptions
 15235     *                                       chapters and metadata)
 15236     * @param {String=} label Label to identify the text track
 15237     * @param {String=} language Two letter language abbreviation
 15238     * @return {TextTrackObject}
 15239     * @method addTextTrack
 15240     */
 15241  
 15242    Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) {
 15243      if (!this['featuresNativeTextTracks']) {
 15244        return _Tech.prototype.addTextTrack.call(this, kind, label, language);
 15245      }
 15246  
 15247      return this.el_.addTextTrack(kind, label, language);
 15248    };
 15249  
 15250    /**
 15251     * Creates a remote text track object and returns a html track element
 15252     *
 15253     * @param {Object} options The object should contain values for
 15254     * kind, language, label and src (location of the WebVTT file)
 15255     * @return {HTMLTrackElement}
 15256     * @method addRemoteTextTrack
 15257     */
 15258  
 15259    Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack() {
 15260      var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
 15261  
 15262      if (!this['featuresNativeTextTracks']) {
 15263        return _Tech.prototype.addRemoteTextTrack.call(this, options);
 15264      }
 15265  
 15266      var htmlTrackElement = _globalDocument2['default'].createElement('track');
 15267  
 15268      if (options.kind) {
 15269        htmlTrackElement.kind = options.kind;
 15270      }
 15271      if (options.label) {
 15272        htmlTrackElement.label = options.label;
 15273      }
 15274      if (options.language || options.srclang) {
 15275        htmlTrackElement.srclang = options.language || options.srclang;
 15276      }
 15277      if (options['default']) {
 15278        htmlTrackElement['default'] = options['default'];
 15279      }
 15280      if (options.id) {
 15281        htmlTrackElement.id = options.id;
 15282      }
 15283      if (options.src) {
 15284        htmlTrackElement.src = options.src;
 15285      }
 15286  
 15287      this.el().appendChild(htmlTrackElement);
 15288  
 15289      // store HTMLTrackElement and TextTrack to remote list
 15290      this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
 15291      this.remoteTextTracks().addTrack_(htmlTrackElement.track);
 15292  
 15293      return htmlTrackElement;
 15294    };
 15295  
 15296    /**
 15297     * Remove remote text track from TextTrackList object
 15298     *
 15299     * @param {TextTrackObject} track Texttrack object to remove
 15300     * @method removeRemoteTextTrack
 15301     */
 15302  
 15303    Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
 15304      if (!this['featuresNativeTextTracks']) {
 15305        return _Tech.prototype.removeRemoteTextTrack.call(this, track);
 15306      }
 15307  
 15308      var tracks = undefined,
 15309          i = undefined;
 15310  
 15311      var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
 15312  
 15313      // remove HTMLTrackElement and TextTrack from remote list
 15314      this.remoteTextTrackEls().removeTrackElement_(trackElement);
 15315      this.remoteTextTracks().removeTrack_(track);
 15316  
 15317      tracks = this.$$('track');
 15318  
 15319      i = tracks.length;
 15320      while (i--) {
 15321        if (track === tracks[i] || track === tracks[i].track) {
 15322          this.el().removeChild(tracks[i]);
 15323        }
 15324      }
 15325    };
 15326  
 15327    return Html5;
 15328  })(_techJs2['default']);
 15329  
 15330  Html5.TEST_VID = _globalDocument2['default'].createElement('video');
 15331  var track = _globalDocument2['default'].createElement('track');
 15332  track.kind = 'captions';
 15333  track.srclang = 'en';
 15334  track.label = 'English';
 15335  Html5.TEST_VID.appendChild(track);
 15336  
 15337  /*
 15338   * Check if HTML5 video is supported by this browser/device
 15339   *
 15340   * @return {Boolean}
 15341   */
 15342  Html5.isSupported = function () {
 15343    // IE9 with no Media Player is a LIAR! (#984)
 15344    try {
 15345      Html5.TEST_VID['volume'] = 0.5;
 15346    } catch (e) {
 15347      return false;
 15348    }
 15349  
 15350    return !!Html5.TEST_VID.canPlayType;
 15351  };
 15352  
 15353  // Add Source Handler pattern functions to this tech
 15354  _techJs2['default'].withSourceHandlers(Html5);
 15355  
 15356  /*
 15357   * The default native source handler.
 15358   * This simply passes the source to the video element. Nothing fancy.
 15359   *
 15360   * @param  {Object} source   The source object
 15361   * @param  {Html5} tech  The instance of the HTML5 tech
 15362   */
 15363  Html5.nativeSourceHandler = {};
 15364  
 15365  /*
 15366   * Check if the video element can play the given videotype
 15367   *
 15368   * @param  {String} type    The mimetype to check
 15369   * @return {String}         'probably', 'maybe', or '' (empty string)
 15370   */
 15371  Html5.nativeSourceHandler.canPlayType = function (type) {
 15372    // IE9 on Windows 7 without MediaPlayer throws an error here
 15373    // https://github.com/videojs/video.js/issues/519
 15374    try {
 15375      return Html5.TEST_VID.canPlayType(type);
 15376    } catch (e) {
 15377      return '';
 15378    }
 15379  };
 15380  
 15381  /*
 15382   * Check if the video element can handle the source natively
 15383   *
 15384   * @param  {Object} source  The source object
 15385   * @return {String}         'probably', 'maybe', or '' (empty string)
 15386   */
 15387  Html5.nativeSourceHandler.canHandleSource = function (source) {
 15388    var match, ext;
 15389  
 15390    // If a type was provided we should rely on that
 15391    if (source.type) {
 15392      return Html5.nativeSourceHandler.canPlayType(source.type);
 15393    } else if (source.src) {
 15394      // If no type, fall back to checking 'video/[EXTENSION]'
 15395      ext = Url.getFileExtension(source.src);
 15396  
 15397      return Html5.nativeSourceHandler.canPlayType('video/' + ext);
 15398    }
 15399  
 15400    return '';
 15401  };
 15402  
 15403  /*
 15404   * Pass the source to the video element
 15405   * Adaptive source handlers will have more complicated workflows before passing
 15406   * video data to the video element
 15407   *
 15408   * @param  {Object} source    The source object
 15409   * @param  {Html5} tech   The instance of the Html5 tech
 15410   */
 15411  Html5.nativeSourceHandler.handleSource = function (source, tech) {
 15412    tech.setSrc(source.src);
 15413  };
 15414  
 15415  /*
 15416  * Clean up the source handler when disposing the player or switching sources..
 15417  * (no cleanup is needed when supporting the format natively)
 15418  */
 15419  Html5.nativeSourceHandler.dispose = function () {};
 15420  
 15421  // Register the native source handler
 15422  Html5.registerSourceHandler(Html5.nativeSourceHandler);
 15423  
 15424  /*
 15425   * Check if the volume can be changed in this browser/device.
 15426   * Volume cannot be changed in a lot of mobile devices.
 15427   * Specifically, it can't be changed from 1 on iOS.
 15428   *
 15429   * @return {Boolean}
 15430   */
 15431  Html5.canControlVolume = function () {
 15432    var volume = Html5.TEST_VID.volume;
 15433    Html5.TEST_VID.volume = volume / 2 + 0.1;
 15434    return volume !== Html5.TEST_VID.volume;
 15435  };
 15436  
 15437  /*
 15438   * Check if playbackRate is supported in this browser/device.
 15439   *
 15440   * @return {Number} [description]
 15441   */
 15442  Html5.canControlPlaybackRate = function () {
 15443    var playbackRate = Html5.TEST_VID.playbackRate;
 15444    Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1;
 15445    return playbackRate !== Html5.TEST_VID.playbackRate;
 15446  };
 15447  
 15448  /*
 15449   * Check to see if native text tracks are supported by this browser/device
 15450   *
 15451   * @return {Boolean}
 15452   */
 15453  Html5.supportsNativeTextTracks = function () {
 15454    var supportsTextTracks;
 15455  
 15456    // Figure out native text track support
 15457    // If mode is a number, we cannot change it because it'll disappear from view.
 15458    // Browsers with numeric modes include IE10 and older (<=2013) samsung android models.
 15459    // Firefox isn't playing nice either with modifying the mode
 15460    // TODO: Investigate firefox: https://github.com/videojs/video.js/issues/1862
 15461    supportsTextTracks = !!Html5.TEST_VID.textTracks;
 15462    if (supportsTextTracks && Html5.TEST_VID.textTracks.length > 0) {
 15463      supportsTextTracks = typeof Html5.TEST_VID.textTracks[0]['mode'] !== 'number';
 15464    }
 15465    if (supportsTextTracks && browser.IS_FIREFOX) {
 15466      supportsTextTracks = false;
 15467    }
 15468    if (supportsTextTracks && !('onremovetrack' in Html5.TEST_VID.textTracks)) {
 15469      supportsTextTracks = false;
 15470    }
 15471  
 15472    return supportsTextTracks;
 15473  };
 15474  
 15475  /**
 15476   * An array of events available on the Html5 tech.
 15477   *
 15478   * @private
 15479   * @type {Array}
 15480   */
 15481  Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'volumechange'];
 15482  
 15483  /*
 15484   * Set the tech's volume control support status
 15485   *
 15486   * @type {Boolean}
 15487   */
 15488  Html5.prototype['featuresVolumeControl'] = Html5.canControlVolume();
 15489  
 15490  /*
 15491   * Set the tech's playbackRate support status
 15492   *
 15493   * @type {Boolean}
 15494   */
 15495  Html5.prototype['featuresPlaybackRate'] = Html5.canControlPlaybackRate();
 15496  
 15497  /*
 15498   * Set the tech's status on moving the video element.
 15499   * In iOS, if you move a video element in the DOM, it breaks video playback.
 15500   *
 15501   * @type {Boolean}
 15502   */
 15503  Html5.prototype['movingMediaElementInDOM'] = !browser.IS_IOS;
 15504  
 15505  /*
 15506   * Set the the tech's fullscreen resize support status.
 15507   * HTML video is able to automatically resize when going to fullscreen.
 15508   * (No longer appears to be used. Can probably be removed.)
 15509   */
 15510  Html5.prototype['featuresFullscreenResize'] = true;
 15511  
 15512  /*
 15513   * Set the tech's progress event support status
 15514   * (this disables the manual progress events of the Tech)
 15515   */
 15516  Html5.prototype['featuresProgressEvents'] = true;
 15517  
 15518  /*
 15519   * Sets the tech's status on native text track support
 15520   *
 15521   * @type {Boolean}
 15522   */
 15523  Html5.prototype['featuresNativeTextTracks'] = Html5.supportsNativeTextTracks();
 15524  
 15525  // HTML5 Feature detection and Device Fixes --------------------------------- //
 15526  var canPlayType = undefined;
 15527  var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i;
 15528  var mp4RE = /^video\/mp4/i;
 15529  
 15530  Html5.patchCanPlayType = function () {
 15531    // Android 4.0 and above can play HLS to some extent but it reports being unable to do so
 15532    if (browser.ANDROID_VERSION >= 4.0) {
 15533      if (!canPlayType) {
 15534        canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType;
 15535      }
 15536  
 15537      Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
 15538        if (type && mpegurlRE.test(type)) {
 15539          return 'maybe';
 15540        }
 15541        return canPlayType.call(this, type);
 15542      };
 15543    }
 15544  
 15545    // Override Android 2.2 and less canPlayType method which is broken
 15546    if (browser.IS_OLD_ANDROID) {
 15547      if (!canPlayType) {
 15548        canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType;
 15549      }
 15550  
 15551      Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
 15552        if (type && mp4RE.test(type)) {
 15553          return 'maybe';
 15554        }
 15555        return canPlayType.call(this, type);
 15556      };
 15557    }
 15558  };
 15559  
 15560  Html5.unpatchCanPlayType = function () {
 15561    var r = Html5.TEST_VID.constructor.prototype.canPlayType;
 15562    Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType;
 15563    canPlayType = null;
 15564    return r;
 15565  };
 15566  
 15567  // by default, patch the video element
 15568  Html5.patchCanPlayType();
 15569  
 15570  Html5.disposeMediaElement = function (el) {
 15571    if (!el) {
 15572      return;
 15573    }
 15574  
 15575    if (el.parentNode) {
 15576      el.parentNode.removeChild(el);
 15577    }
 15578  
 15579    // remove any child track or source nodes to prevent their loading
 15580    while (el.hasChildNodes()) {
 15581      el.removeChild(el.firstChild);
 15582    }
 15583  
 15584    // remove any src reference. not setting `src=''` because that causes a warning
 15585    // in firefox
 15586    el.removeAttribute('src');
 15587  
 15588    // force the media element to update its loading state by calling load()
 15589    // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793)
 15590    if (typeof el.load === 'function') {
 15591      // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
 15592      (function () {
 15593        try {
 15594          el.load();
 15595        } catch (e) {
 15596          // not supported
 15597        }
 15598      })();
 15599    }
 15600  };
 15601  
 15602  Html5.resetMediaElement = function (el) {
 15603    if (!el) {
 15604      return;
 15605    }
 15606  
 15607    var sources = el.querySelectorAll('source');
 15608    var i = sources.length;
 15609    while (i--) {
 15610      el.removeChild(sources[i]);
 15611    }
 15612  
 15613    // remove any src reference.
 15614    // not setting `src=''` because that throws an error
 15615    el.removeAttribute('src');
 15616  
 15617    if (typeof el.load === 'function') {
 15618      // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
 15619      (function () {
 15620        try {
 15621          el.load();
 15622        } catch (e) {}
 15623      })();
 15624    }
 15625  };
 15626  
 15627  _component2['default'].registerComponent('Html5', Html5);
 15628  _techJs2['default'].registerTech('Html5', Html5);
 15629  exports['default'] = Html5;
 15630  module.exports = exports['default'];
 15631  
 15632  },{"../component":67,"../utils/browser.js":131,"../utils/dom.js":134,"../utils/fn.js":136,"../utils/log.js":139,"../utils/merge-options.js":140,"../utils/url.js":144,"./tech.js":121,"global/document":1,"global/window":2,"object.assign":45}],120:[function(_dereq_,module,exports){
 15633  /**
 15634   * @file loader.js
 15635   */
 15636  'use strict';
 15637  
 15638  exports.__esModule = true;
 15639  
 15640  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 15641  
 15642  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 15643  
 15644  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 15645  
 15646  var _componentJs = _dereq_('../component.js');
 15647  
 15648  var _componentJs2 = _interopRequireDefault(_componentJs);
 15649  
 15650  var _techJs = _dereq_('./tech.js');
 15651  
 15652  var _techJs2 = _interopRequireDefault(_techJs);
 15653  
 15654  var _globalWindow = _dereq_('global/window');
 15655  
 15656  var _globalWindow2 = _interopRequireDefault(_globalWindow);
 15657  
 15658  var _utilsToTitleCaseJs = _dereq_('../utils/to-title-case.js');
 15659  
 15660  var _utilsToTitleCaseJs2 = _interopRequireDefault(_utilsToTitleCaseJs);
 15661  
 15662  /**
 15663   * The Media Loader is the component that decides which playback technology to load
 15664   * when the player is initialized.
 15665   *
 15666   * @param {Object} player  Main Player
 15667   * @param {Object=} options Object of option names and values
 15668   * @param {Function=} ready    Ready callback function
 15669   * @extends Component
 15670   * @class MediaLoader
 15671   */
 15672  
 15673  var MediaLoader = (function (_Component) {
 15674    _inherits(MediaLoader, _Component);
 15675  
 15676    function MediaLoader(player, options, ready) {
 15677      _classCallCheck(this, MediaLoader);
 15678  
 15679      _Component.call(this, player, options, ready);
 15680  
 15681      // If there are no sources when the player is initialized,
 15682      // load the first supported playback technology.
 15683  
 15684      if (!options.playerOptions['sources'] || options.playerOptions['sources'].length === 0) {
 15685        for (var i = 0, j = options.playerOptions['techOrder']; i < j.length; i++) {
 15686          var techName = _utilsToTitleCaseJs2['default'](j[i]);
 15687          var tech = _techJs2['default'].getTech(techName);
 15688          // Support old behavior of techs being registered as components.
 15689          // Remove once that deprecated behavior is removed.
 15690          if (!techName) {
 15691            tech = _componentJs2['default'].getComponent(techName);
 15692          }
 15693  
 15694          // Check if the browser supports this technology
 15695          if (tech && tech.isSupported()) {
 15696            player.loadTech_(techName);
 15697            break;
 15698          }
 15699        }
 15700      } else {
 15701        // // Loop through playback technologies (HTML5, Flash) and check for support.
 15702        // // Then load the best source.
 15703        // // A few assumptions here:
 15704        // //   All playback technologies respect preload false.
 15705        player.src(options.playerOptions['sources']);
 15706      }
 15707    }
 15708  
 15709    return MediaLoader;
 15710  })(_componentJs2['default']);
 15711  
 15712  _componentJs2['default'].registerComponent('MediaLoader', MediaLoader);
 15713  exports['default'] = MediaLoader;
 15714  module.exports = exports['default'];
 15715  
 15716  },{"../component.js":67,"../utils/to-title-case.js":143,"./tech.js":121,"global/window":2}],121:[function(_dereq_,module,exports){
 15717  /**
 15718   * @file tech.js
 15719   * Media Technology Controller - Base class for media playback
 15720   * technology controllers like Flash and HTML5
 15721   */
 15722  
 15723  'use strict';
 15724  
 15725  exports.__esModule = true;
 15726  
 15727  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 15728  
 15729  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 15730  
 15731  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 15732  
 15733  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 15734  
 15735  var _component = _dereq_('../component');
 15736  
 15737  var _component2 = _interopRequireDefault(_component);
 15738  
 15739  var _tracksHtmlTrackElement = _dereq_('../tracks/html-track-element');
 15740  
 15741  var _tracksHtmlTrackElement2 = _interopRequireDefault(_tracksHtmlTrackElement);
 15742  
 15743  var _tracksHtmlTrackElementList = _dereq_('../tracks/html-track-element-list');
 15744  
 15745  var _tracksHtmlTrackElementList2 = _interopRequireDefault(_tracksHtmlTrackElementList);
 15746  
 15747  var _utilsMergeOptionsJs = _dereq_('../utils/merge-options.js');
 15748  
 15749  var _utilsMergeOptionsJs2 = _interopRequireDefault(_utilsMergeOptionsJs);
 15750  
 15751  var _tracksTextTrack = _dereq_('../tracks/text-track');
 15752  
 15753  var _tracksTextTrack2 = _interopRequireDefault(_tracksTextTrack);
 15754  
 15755  var _tracksTextTrackList = _dereq_('../tracks/text-track-list');
 15756  
 15757  var _tracksTextTrackList2 = _interopRequireDefault(_tracksTextTrackList);
 15758  
 15759  var _utilsFnJs = _dereq_('../utils/fn.js');
 15760  
 15761  var Fn = _interopRequireWildcard(_utilsFnJs);
 15762  
 15763  var _utilsLogJs = _dereq_('../utils/log.js');
 15764  
 15765  var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
 15766  
 15767  var _utilsTimeRangesJs = _dereq_('../utils/time-ranges.js');
 15768  
 15769  var _utilsBufferJs = _dereq_('../utils/buffer.js');
 15770  
 15771  var _mediaErrorJs = _dereq_('../media-error.js');
 15772  
 15773  var _mediaErrorJs2 = _interopRequireDefault(_mediaErrorJs);
 15774  
 15775  var _globalWindow = _dereq_('global/window');
 15776  
 15777  var _globalWindow2 = _interopRequireDefault(_globalWindow);
 15778  
 15779  var _globalDocument = _dereq_('global/document');
 15780  
 15781  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 15782  
 15783  /**
 15784   * Base class for media (HTML5 Video, Flash) controllers
 15785   *
 15786   * @param {Object=} options Options object
 15787   * @param {Function=} ready Ready callback function
 15788   * @extends Component
 15789   * @class Tech
 15790   */
 15791  
 15792  var Tech = (function (_Component) {
 15793    _inherits(Tech, _Component);
 15794  
 15795    function Tech() {
 15796      var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
 15797      var ready = arguments.length <= 1 || arguments[1] === undefined ? function () {} : arguments[1];
 15798  
 15799      _classCallCheck(this, Tech);
 15800  
 15801      // we don't want the tech to report user activity automatically.
 15802      // This is done manually in addControlsListeners
 15803      options.reportTouchActivity = false;
 15804      _Component.call(this, null, options, ready);
 15805  
 15806      // keep track of whether the current source has played at all to
 15807      // implement a very limited played()
 15808      this.hasStarted_ = false;
 15809      this.on('playing', function () {
 15810        this.hasStarted_ = true;
 15811      });
 15812      this.on('loadstart', function () {
 15813        this.hasStarted_ = false;
 15814      });
 15815  
 15816      this.textTracks_ = options.textTracks;
 15817  
 15818      // Manually track progress in cases where the browser/flash player doesn't report it.
 15819      if (!this.featuresProgressEvents) {
 15820        this.manualProgressOn();
 15821      }
 15822  
 15823      // Manually track timeupdates in cases where the browser/flash player doesn't report it.
 15824      if (!this.featuresTimeupdateEvents) {
 15825        this.manualTimeUpdatesOn();
 15826      }
 15827  
 15828      if (options.nativeCaptions === false || options.nativeTextTracks === false) {
 15829        this.featuresNativeTextTracks = false;
 15830      }
 15831  
 15832      if (!this.featuresNativeTextTracks) {
 15833        this.on('ready', this.emulateTextTracks);
 15834      }
 15835  
 15836      this.initTextTrackListeners();
 15837  
 15838      // Turn on component tap events
 15839      this.emitTapEvents();
 15840    }
 15841  
 15842    /*
 15843     * List of associated text tracks
 15844     *
 15845     * @type {Array}
 15846     * @private
 15847     */
 15848  
 15849    /* Fallbacks for unsupported event types
 15850    ================================================================================ */
 15851    // Manually trigger progress events based on changes to the buffered amount
 15852    // Many flash players and older HTML5 browsers don't send progress or progress-like events
 15853    /**
 15854     * Turn on progress events
 15855     *
 15856     * @method manualProgressOn
 15857     */
 15858  
 15859    Tech.prototype.manualProgressOn = function manualProgressOn() {
 15860      this.on('durationchange', this.onDurationChange);
 15861  
 15862      this.manualProgress = true;
 15863  
 15864      // Trigger progress watching when a source begins loading
 15865      this.one('ready', this.trackProgress);
 15866    };
 15867  
 15868    /**
 15869     * Turn off progress events
 15870     *
 15871     * @method manualProgressOff
 15872     */
 15873  
 15874    Tech.prototype.manualProgressOff = function manualProgressOff() {
 15875      this.manualProgress = false;
 15876      this.stopTrackingProgress();
 15877  
 15878      this.off('durationchange', this.onDurationChange);
 15879    };
 15880  
 15881    /**
 15882     * Track progress
 15883     *
 15884     * @method trackProgress
 15885     */
 15886  
 15887    Tech.prototype.trackProgress = function trackProgress() {
 15888      this.stopTrackingProgress();
 15889      this.progressInterval = this.setInterval(Fn.bind(this, function () {
 15890        // Don't trigger unless buffered amount is greater than last time
 15891  
 15892        var numBufferedPercent = this.bufferedPercent();
 15893  
 15894        if (this.bufferedPercent_ !== numBufferedPercent) {
 15895          this.trigger('progress');
 15896        }
 15897  
 15898        this.bufferedPercent_ = numBufferedPercent;
 15899  
 15900        if (numBufferedPercent === 1) {
 15901          this.stopTrackingProgress();
 15902        }
 15903      }), 500);
 15904    };
 15905  
 15906    /**
 15907     * Update duration
 15908     *
 15909     * @method onDurationChange
 15910     */
 15911  
 15912    Tech.prototype.onDurationChange = function onDurationChange() {
 15913      this.duration_ = this.duration();
 15914    };
 15915  
 15916    /**
 15917     * Create and get TimeRange object for buffering
 15918     *
 15919     * @return {TimeRangeObject}
 15920     * @method buffered
 15921     */
 15922  
 15923    Tech.prototype.buffered = function buffered() {
 15924      return _utilsTimeRangesJs.createTimeRange(0, 0);
 15925    };
 15926  
 15927    /**
 15928     * Get buffered percent
 15929     *
 15930     * @return {Number}
 15931     * @method bufferedPercent
 15932     */
 15933  
 15934    Tech.prototype.bufferedPercent = function bufferedPercent() {
 15935      return _utilsBufferJs.bufferedPercent(this.buffered(), this.duration_);
 15936    };
 15937  
 15938    /**
 15939     * Stops tracking progress by clearing progress interval
 15940     *
 15941     * @method stopTrackingProgress
 15942     */
 15943  
 15944    Tech.prototype.stopTrackingProgress = function stopTrackingProgress() {
 15945      this.clearInterval(this.progressInterval);
 15946    };
 15947  
 15948    /*! Time Tracking -------------------------------------------------------------- */
 15949    /**
 15950     * Set event listeners for on play and pause and tracking current time
 15951     *
 15952     * @method manualTimeUpdatesOn
 15953     */
 15954  
 15955    Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() {
 15956      this.manualTimeUpdates = true;
 15957  
 15958      this.on('play', this.trackCurrentTime);
 15959      this.on('pause', this.stopTrackingCurrentTime);
 15960    };
 15961  
 15962    /**
 15963     * Remove event listeners for on play and pause and tracking current time
 15964     *
 15965     * @method manualTimeUpdatesOff
 15966     */
 15967  
 15968    Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() {
 15969      this.manualTimeUpdates = false;
 15970      this.stopTrackingCurrentTime();
 15971      this.off('play', this.trackCurrentTime);
 15972      this.off('pause', this.stopTrackingCurrentTime);
 15973    };
 15974  
 15975    /**
 15976     * Tracks current time
 15977     *
 15978     * @method trackCurrentTime
 15979     */
 15980  
 15981    Tech.prototype.trackCurrentTime = function trackCurrentTime() {
 15982      if (this.currentTimeInterval) {
 15983        this.stopTrackingCurrentTime();
 15984      }
 15985      this.currentTimeInterval = this.setInterval(function () {
 15986        this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
 15987      }, 250); // 42 = 24 fps // 250 is what Webkit uses // FF uses 15
 15988    };
 15989  
 15990    /**
 15991     * Turn off play progress tracking (when paused or dragging)
 15992     *
 15993     * @method stopTrackingCurrentTime
 15994     */
 15995  
 15996    Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() {
 15997      this.clearInterval(this.currentTimeInterval);
 15998  
 15999      // #1002 - if the video ends right before the next timeupdate would happen,
 16000      // the progress bar won't make it all the way to the end
 16001      this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
 16002    };
 16003  
 16004    /**
 16005     * Turn off any manual progress or timeupdate tracking
 16006     *
 16007     * @method dispose
 16008     */
 16009  
 16010    Tech.prototype.dispose = function dispose() {
 16011      // clear out text tracks because we can't reuse them between techs
 16012      var textTracks = this.textTracks();
 16013  
 16014      if (textTracks) {
 16015        var i = textTracks.length;
 16016        while (i--) {
 16017          this.removeRemoteTextTrack(textTracks[i]);
 16018        }
 16019      }
 16020  
 16021      // Turn off any manual progress or timeupdate tracking
 16022      if (this.manualProgress) {
 16023        this.manualProgressOff();
 16024      }
 16025  
 16026      if (this.manualTimeUpdates) {
 16027        this.manualTimeUpdatesOff();
 16028      }
 16029  
 16030      _Component.prototype.dispose.call(this);
 16031    };
 16032  
 16033    /**
 16034     * Reset the tech. Removes all sources and resets readyState.
 16035     *
 16036     * @method reset
 16037     */
 16038  
 16039    Tech.prototype.reset = function reset() {};
 16040  
 16041    /**
 16042     * When invoked without an argument, returns a MediaError object
 16043     * representing the current error state of the player or null if
 16044     * there is no error. When invoked with an argument, set the current
 16045     * error state of the player.
 16046     * @param {MediaError=} err    Optional an error object
 16047     * @return {MediaError}        the current error object or null
 16048     * @method error
 16049     */
 16050  
 16051    Tech.prototype.error = function error(err) {
 16052      if (err !== undefined) {
 16053        if (err instanceof _mediaErrorJs2['default']) {
 16054          this.error_ = err;
 16055        } else {
 16056          this.error_ = new _mediaErrorJs2['default'](err);
 16057        }
 16058        this.trigger('error');
 16059      }
 16060      return this.error_;
 16061    };
 16062  
 16063    /**
 16064     * Return the time ranges that have been played through for the
 16065     * current source. This implementation is incomplete. It does not
 16066     * track the played time ranges, only whether the source has played
 16067     * at all or not.
 16068     * @return {TimeRangeObject} a single time range if this video has
 16069     * played or an empty set of ranges if not.
 16070     * @method played
 16071     */
 16072  
 16073    Tech.prototype.played = function played() {
 16074      if (this.hasStarted_) {
 16075        return _utilsTimeRangesJs.createTimeRange(0, 0);
 16076      }
 16077      return _utilsTimeRangesJs.createTimeRange();
 16078    };
 16079  
 16080    /**
 16081     * Set current time
 16082     *
 16083     * @method setCurrentTime
 16084     */
 16085  
 16086    Tech.prototype.setCurrentTime = function setCurrentTime() {
 16087      // improve the accuracy of manual timeupdates
 16088      if (this.manualTimeUpdates) {
 16089        this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
 16090      }
 16091    };
 16092  
 16093    /**
 16094     * Initialize texttrack listeners
 16095     *
 16096     * @method initTextTrackListeners
 16097     */
 16098  
 16099    Tech.prototype.initTextTrackListeners = function initTextTrackListeners() {
 16100      var textTrackListChanges = Fn.bind(this, function () {
 16101        this.trigger('texttrackchange');
 16102      });
 16103  
 16104      var tracks = this.textTracks();
 16105  
 16106      if (!tracks) return;
 16107  
 16108      tracks.addEventListener('removetrack', textTrackListChanges);
 16109      tracks.addEventListener('addtrack', textTrackListChanges);
 16110  
 16111      this.on('dispose', Fn.bind(this, function () {
 16112        tracks.removeEventListener('removetrack', textTrackListChanges);
 16113        tracks.removeEventListener('addtrack', textTrackListChanges);
 16114      }));
 16115    };
 16116  
 16117    /**
 16118     * Emulate texttracks
 16119     *
 16120     * @method emulateTextTracks
 16121     */
 16122  
 16123    Tech.prototype.emulateTextTracks = function emulateTextTracks() {
 16124      var _this = this;
 16125  
 16126      var tracks = this.textTracks();
 16127      if (!tracks) {
 16128        return;
 16129      }
 16130  
 16131      if (!_globalWindow2['default']['WebVTT'] && this.el().parentNode != null) {
 16132        (function () {
 16133          var script = _globalDocument2['default'].createElement('script');
 16134          script.src = _this.options_['vtt.js'] || 'https://cdn.rawgit.com/gkatsev/vtt.js/vjs-v0.12.1/dist/vtt.min.js';
 16135          script.onload = function () {
 16136            _this.trigger('vttjsloaded');
 16137          };
 16138          script.onerror = function () {
 16139            _this.trigger('vttjserror');
 16140          };
 16141          _this.on('dispose', function () {
 16142            script.onload = null;
 16143            script.onerror = null;
 16144          });
 16145          _this.el().parentNode.appendChild(script);
 16146          _globalWindow2['default']['WebVTT'] = true;
 16147        })();
 16148      }
 16149  
 16150      var updateDisplay = function updateDisplay() {
 16151        return _this.trigger('texttrackchange');
 16152      };
 16153      var textTracksChanges = function textTracksChanges() {
 16154        updateDisplay();
 16155  
 16156        for (var i = 0; i < tracks.length; i++) {
 16157          var track = tracks[i];
 16158          track.removeEventListener('cuechange', updateDisplay);
 16159          if (track.mode === 'showing') {
 16160            track.addEventListener('cuechange', updateDisplay);
 16161          }
 16162        }
 16163      };
 16164  
 16165      textTracksChanges();
 16166      tracks.addEventListener('change', textTracksChanges);
 16167  
 16168      this.on('dispose', function () {
 16169        tracks.removeEventListener('change', textTracksChanges);
 16170      });
 16171    };
 16172  
 16173    /*
 16174     * Provide default methods for text tracks.
 16175     *
 16176     * Html5 tech overrides these.
 16177     */
 16178  
 16179    /**
 16180     * Get texttracks
 16181     *
 16182     * @returns {TextTrackList}
 16183     * @method textTracks
 16184     */
 16185  
 16186    Tech.prototype.textTracks = function textTracks() {
 16187      this.textTracks_ = this.textTracks_ || new _tracksTextTrackList2['default']();
 16188      return this.textTracks_;
 16189    };
 16190  
 16191    /**
 16192     * Get remote texttracks
 16193     *
 16194     * @returns {TextTrackList}
 16195     * @method remoteTextTracks
 16196     */
 16197  
 16198    Tech.prototype.remoteTextTracks = function remoteTextTracks() {
 16199      this.remoteTextTracks_ = this.remoteTextTracks_ || new _tracksTextTrackList2['default']();
 16200      return this.remoteTextTracks_;
 16201    };
 16202  
 16203    /**
 16204     * Get remote htmltrackelements
 16205     *
 16206     * @returns {HTMLTrackElementList}
 16207     * @method remoteTextTrackEls
 16208     */
 16209  
 16210    Tech.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
 16211      this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new _tracksHtmlTrackElementList2['default']();
 16212      return this.remoteTextTrackEls_;
 16213    };
 16214  
 16215    /**
 16216     * Creates and returns a remote text track object
 16217     *
 16218     * @param {String} kind Text track kind (subtitles, captions, descriptions
 16219     *                                       chapters and metadata)
 16220     * @param {String=} label Label to identify the text track
 16221     * @param {String=} language Two letter language abbreviation
 16222     * @return {TextTrackObject}
 16223     * @method addTextTrack
 16224     */
 16225  
 16226    Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) {
 16227      if (!kind) {
 16228        throw new Error('TextTrack kind is required but was not provided');
 16229      }
 16230  
 16231      return createTrackHelper(this, kind, label, language);
 16232    };
 16233  
 16234    /**
 16235     * Creates a remote text track object and returns a emulated html track element
 16236     *
 16237     * @param {Object} options The object should contain values for
 16238     * kind, language, label and src (location of the WebVTT file)
 16239     * @return {HTMLTrackElement}
 16240     * @method addRemoteTextTrack
 16241     */
 16242  
 16243    Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack(options) {
 16244      var track = _utilsMergeOptionsJs2['default'](options, {
 16245        tech: this
 16246      });
 16247  
 16248      var htmlTrackElement = new _tracksHtmlTrackElement2['default'](track);
 16249  
 16250      // store HTMLTrackElement and TextTrack to remote list
 16251      this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
 16252      this.remoteTextTracks().addTrack_(htmlTrackElement.track);
 16253  
 16254      // must come after remoteTextTracks()
 16255      this.textTracks().addTrack_(htmlTrackElement.track);
 16256  
 16257      return htmlTrackElement;
 16258    };
 16259  
 16260    /**
 16261     * Remove remote texttrack
 16262     *
 16263     * @param {TextTrackObject} track Texttrack to remove
 16264     * @method removeRemoteTextTrack
 16265     */
 16266  
 16267    Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
 16268      this.textTracks().removeTrack_(track);
 16269  
 16270      var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
 16271  
 16272      // remove HTMLTrackElement and TextTrack from remote list
 16273      this.remoteTextTrackEls().removeTrackElement_(trackElement);
 16274      this.remoteTextTracks().removeTrack_(track);
 16275    };
 16276  
 16277    /**
 16278     * Provide a default setPoster method for techs
 16279     * Poster support for techs should be optional, so we don't want techs to
 16280     * break if they don't have a way to set a poster.
 16281     *
 16282     * @method setPoster
 16283     */
 16284  
 16285    Tech.prototype.setPoster = function setPoster() {};
 16286  
 16287    /*
 16288     * Check if the tech can support the given type
 16289     *
 16290     * The base tech does not support any type, but source handlers might
 16291     * overwrite this.
 16292     *
 16293     * @param  {String} type    The mimetype to check
 16294     * @return {String}         'probably', 'maybe', or '' (empty string)
 16295     */
 16296  
 16297    Tech.prototype.canPlayType = function canPlayType() {
 16298      return '';
 16299    };
 16300  
 16301    /*
 16302     * Return whether the argument is a Tech or not.
 16303     * Can be passed either a Class like `Html5` or a instance like `player.tech_`
 16304     *
 16305     * @param {Object} component An item to check
 16306     * @return {Boolean}         Whether it is a tech or not
 16307     */
 16308  
 16309    Tech.isTech = function isTech(component) {
 16310      return component.prototype instanceof Tech || component instanceof Tech || component === Tech;
 16311    };
 16312  
 16313    /**
 16314     * Registers a Tech
 16315     *
 16316     * @param {String} name Name of the Tech to register
 16317     * @param {Object} tech The tech to register
 16318     * @static
 16319     * @method registerComponent
 16320     */
 16321  
 16322    Tech.registerTech = function registerTech(name, tech) {
 16323      if (!Tech.techs_) {
 16324        Tech.techs_ = {};
 16325      }
 16326  
 16327      if (!Tech.isTech(tech)) {
 16328        throw new Error('Tech ' + name + ' must be a Tech');
 16329      }
 16330  
 16331      Tech.techs_[name] = tech;
 16332      return tech;
 16333    };
 16334  
 16335    /**
 16336     * Gets a component by name
 16337     *
 16338     * @param {String} name Name of the component to get
 16339     * @return {Component}
 16340     * @static
 16341     * @method getComponent
 16342     */
 16343  
 16344    Tech.getTech = function getTech(name) {
 16345      if (Tech.techs_ && Tech.techs_[name]) {
 16346        return Tech.techs_[name];
 16347      }
 16348  
 16349      if (_globalWindow2['default'] && _globalWindow2['default'].videojs && _globalWindow2['default'].videojs[name]) {
 16350        _utilsLogJs2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)');
 16351        return _globalWindow2['default'].videojs[name];
 16352      }
 16353    };
 16354  
 16355    return Tech;
 16356  })(_component2['default']);
 16357  
 16358  Tech.prototype.textTracks_;
 16359  
 16360  var createTrackHelper = function createTrackHelper(self, kind, label, language) {
 16361    var options = arguments.length <= 4 || arguments[4] === undefined ? {} : arguments[4];
 16362  
 16363    var tracks = self.textTracks();
 16364  
 16365    options.kind = kind;
 16366  
 16367    if (label) {
 16368      options.label = label;
 16369    }
 16370    if (language) {
 16371      options.language = language;
 16372    }
 16373    options.tech = self;
 16374  
 16375    var track = new _tracksTextTrack2['default'](options);
 16376    tracks.addTrack_(track);
 16377  
 16378    return track;
 16379  };
 16380  
 16381  Tech.prototype.featuresVolumeControl = true;
 16382  
 16383  // Resizing plugins using request fullscreen reloads the plugin
 16384  Tech.prototype.featuresFullscreenResize = false;
 16385  Tech.prototype.featuresPlaybackRate = false;
 16386  
 16387  // Optional events that we can manually mimic with timers
 16388  // currently not triggered by video-js-swf
 16389  Tech.prototype.featuresProgressEvents = false;
 16390  Tech.prototype.featuresTimeupdateEvents = false;
 16391  
 16392  Tech.prototype.featuresNativeTextTracks = false;
 16393  
 16394  /*
 16395   * A functional mixin for techs that want to use the Source Handler pattern.
 16396   *
 16397   * ##### EXAMPLE:
 16398   *
 16399   *   Tech.withSourceHandlers.call(MyTech);
 16400   *
 16401   */
 16402  Tech.withSourceHandlers = function (_Tech) {
 16403    /*
 16404     * Register a source handler
 16405     * Source handlers are scripts for handling specific formats.
 16406     * The source handler pattern is used for adaptive formats (HLS, DASH) that
 16407     * manually load video data and feed it into a Source Buffer (Media Source Extensions)
 16408     * @param  {Function} handler  The source handler
 16409     * @param  {Boolean}  first    Register it before any existing handlers
 16410     */
 16411    _Tech.registerSourceHandler = function (handler, index) {
 16412      var handlers = _Tech.sourceHandlers;
 16413  
 16414      if (!handlers) {
 16415        handlers = _Tech.sourceHandlers = [];
 16416      }
 16417  
 16418      if (index === undefined) {
 16419        // add to the end of the list
 16420        index = handlers.length;
 16421      }
 16422  
 16423      handlers.splice(index, 0, handler);
 16424    };
 16425  
 16426    /*
 16427     * Check if the tech can support the given type
 16428     * @param  {String} type    The mimetype to check
 16429     * @return {String}         'probably', 'maybe', or '' (empty string)
 16430     */
 16431    _Tech.canPlayType = function (type) {
 16432      var handlers = _Tech.sourceHandlers || [];
 16433      var can = undefined;
 16434  
 16435      for (var i = 0; i < handlers.length; i++) {
 16436        can = handlers[i].canPlayType(type);
 16437  
 16438        if (can) {
 16439          return can;
 16440        }
 16441      }
 16442  
 16443      return '';
 16444    };
 16445  
 16446    /*
 16447     * Return the first source handler that supports the source
 16448     * TODO: Answer question: should 'probably' be prioritized over 'maybe'
 16449     * @param  {Object} source The source object
 16450     * @returns {Object}       The first source handler that supports the source
 16451     * @returns {null}         Null if no source handler is found
 16452     */
 16453    _Tech.selectSourceHandler = function (source) {
 16454      var handlers = _Tech.sourceHandlers || [];
 16455      var can = undefined;
 16456  
 16457      for (var i = 0; i < handlers.length; i++) {
 16458        can = handlers[i].canHandleSource(source);
 16459  
 16460        if (can) {
 16461          return handlers[i];
 16462        }
 16463      }
 16464  
 16465      return null;
 16466    };
 16467  
 16468    /*
 16469     * Check if the tech can support the given source
 16470     * @param  {Object} srcObj  The source object
 16471     * @return {String}         'probably', 'maybe', or '' (empty string)
 16472     */
 16473    _Tech.canPlaySource = function (srcObj) {
 16474      var sh = _Tech.selectSourceHandler(srcObj);
 16475  
 16476      if (sh) {
 16477        return sh.canHandleSource(srcObj);
 16478      }
 16479  
 16480      return '';
 16481    };
 16482  
 16483    /*
 16484     * When using a source handler, prefer its implementation of
 16485     * any function normally provided by the tech.
 16486     */
 16487    var deferrable = ['seekable', 'duration'];
 16488  
 16489    deferrable.forEach(function (fnName) {
 16490      var originalFn = this[fnName];
 16491  
 16492      if (typeof originalFn !== 'function') {
 16493        return;
 16494      }
 16495  
 16496      this[fnName] = function () {
 16497        if (this.sourceHandler_ && this.sourceHandler_[fnName]) {
 16498          return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments);
 16499        }
 16500        return originalFn.apply(this, arguments);
 16501      };
 16502    }, _Tech.prototype);
 16503  
 16504    /*
 16505     * Create a function for setting the source using a source object
 16506     * and source handlers.
 16507     * Should never be called unless a source handler was found.
 16508     * @param {Object} source  A source object with src and type keys
 16509     * @return {Tech} self
 16510     */
 16511    _Tech.prototype.setSource = function (source) {
 16512      var sh = _Tech.selectSourceHandler(source);
 16513  
 16514      if (!sh) {
 16515        // Fall back to a native source hander when unsupported sources are
 16516        // deliberately set
 16517        if (_Tech.nativeSourceHandler) {
 16518          sh = _Tech.nativeSourceHandler;
 16519        } else {
 16520          _utilsLogJs2['default'].error('No source hander found for the current source.');
 16521        }
 16522      }
 16523  
 16524      // Dispose any existing source handler
 16525      this.disposeSourceHandler();
 16526      this.off('dispose', this.disposeSourceHandler);
 16527  
 16528      this.currentSource_ = source;
 16529      this.sourceHandler_ = sh.handleSource(source, this);
 16530      this.on('dispose', this.disposeSourceHandler);
 16531  
 16532      return this;
 16533    };
 16534  
 16535    /*
 16536     * Clean up any existing source handler
 16537     */
 16538    _Tech.prototype.disposeSourceHandler = function () {
 16539      if (this.sourceHandler_ && this.sourceHandler_.dispose) {
 16540        this.sourceHandler_.dispose();
 16541      }
 16542    };
 16543  };
 16544  
 16545  _component2['default'].registerComponent('Tech', Tech);
 16546  // Old name for Tech
 16547  _component2['default'].registerComponent('MediaTechController', Tech);
 16548  Tech.registerTech('Tech', Tech);
 16549  exports['default'] = Tech;
 16550  module.exports = exports['default'];
 16551  
 16552  },{"../component":67,"../media-error.js":105,"../tracks/html-track-element":123,"../tracks/html-track-element-list":122,"../tracks/text-track":130,"../tracks/text-track-list":128,"../utils/buffer.js":132,"../utils/fn.js":136,"../utils/log.js":139,"../utils/merge-options.js":140,"../utils/time-ranges.js":142,"global/document":1,"global/window":2}],122:[function(_dereq_,module,exports){
 16553  /**
 16554   * @file html-track-element-list.js
 16555   */
 16556  
 16557  'use strict';
 16558  
 16559  exports.__esModule = true;
 16560  
 16561  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 16562  
 16563  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 16564  
 16565  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 16566  
 16567  var _utilsBrowserJs = _dereq_('../utils/browser.js');
 16568  
 16569  var browser = _interopRequireWildcard(_utilsBrowserJs);
 16570  
 16571  var _globalDocument = _dereq_('global/document');
 16572  
 16573  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 16574  
 16575  var HtmlTrackElementList = (function () {
 16576    function HtmlTrackElementList() {
 16577      var trackElements = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
 16578  
 16579      _classCallCheck(this, HtmlTrackElementList);
 16580  
 16581      var list = this;
 16582  
 16583      if (browser.IS_IE8) {
 16584        list = _globalDocument2['default'].createElement('custom');
 16585  
 16586        for (var prop in HtmlTrackElementList.prototype) {
 16587          if (prop !== 'constructor') {
 16588            list[prop] = HtmlTrackElementList.prototype[prop];
 16589          }
 16590        }
 16591      }
 16592  
 16593      list.trackElements_ = [];
 16594  
 16595      Object.defineProperty(list, 'length', {
 16596        get: function get() {
 16597          return this.trackElements_.length;
 16598        }
 16599      });
 16600  
 16601      for (var i = 0, _length = trackElements.length; i < _length; i++) {
 16602        list.addTrackElement_(trackElements[i]);
 16603      }
 16604  
 16605      if (browser.IS_IE8) {
 16606        return list;
 16607      }
 16608    }
 16609  
 16610    HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) {
 16611      this.trackElements_.push(trackElement);
 16612    };
 16613  
 16614    HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) {
 16615      var trackElement_ = undefined;
 16616  
 16617      for (var i = 0, _length2 = this.trackElements_.length; i < _length2; i++) {
 16618        if (track === this.trackElements_[i].track) {
 16619          trackElement_ = this.trackElements_[i];
 16620  
 16621          break;
 16622        }
 16623      }
 16624  
 16625      return trackElement_;
 16626    };
 16627  
 16628    HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) {
 16629      for (var i = 0, _length3 = this.trackElements_.length; i < _length3; i++) {
 16630        if (trackElement === this.trackElements_[i]) {
 16631          this.trackElements_.splice(i, 1);
 16632  
 16633          break;
 16634        }
 16635      }
 16636    };
 16637  
 16638    return HtmlTrackElementList;
 16639  })();
 16640  
 16641  exports['default'] = HtmlTrackElementList;
 16642  module.exports = exports['default'];
 16643  
 16644  },{"../utils/browser.js":131,"global/document":1}],123:[function(_dereq_,module,exports){
 16645  /**
 16646   * @file html-track-element.js
 16647   */
 16648  
 16649  'use strict';
 16650  
 16651  exports.__esModule = true;
 16652  
 16653  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 16654  
 16655  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 16656  
 16657  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 16658  
 16659  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 16660  
 16661  var _utilsBrowserJs = _dereq_('../utils/browser.js');
 16662  
 16663  var browser = _interopRequireWildcard(_utilsBrowserJs);
 16664  
 16665  var _globalDocument = _dereq_('global/document');
 16666  
 16667  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 16668  
 16669  var _eventTarget = _dereq_('../event-target');
 16670  
 16671  var _eventTarget2 = _interopRequireDefault(_eventTarget);
 16672  
 16673  var _tracksTextTrack = _dereq_('../tracks/text-track');
 16674  
 16675  var _tracksTextTrack2 = _interopRequireDefault(_tracksTextTrack);
 16676  
 16677  var NONE = 0;
 16678  var LOADING = 1;
 16679  var LOADED = 2;
 16680  var ERROR = 3;
 16681  
 16682  /**
 16683   * https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement
 16684   *
 16685   * interface HTMLTrackElement : HTMLElement {
 16686   *   attribute DOMString kind;
 16687   *   attribute DOMString src;
 16688   *   attribute DOMString srclang;
 16689   *   attribute DOMString label;
 16690   *   attribute boolean default;
 16691   *
 16692   *   const unsigned short NONE = 0;
 16693   *   const unsigned short LOADING = 1;
 16694   *   const unsigned short LOADED = 2;
 16695   *   const unsigned short ERROR = 3;
 16696   *   readonly attribute unsigned short readyState;
 16697   *
 16698   *   readonly attribute TextTrack track;
 16699   * };
 16700   *
 16701   * @param {Object} options TextTrack configuration
 16702   * @class HTMLTrackElement
 16703   */
 16704  
 16705  var HTMLTrackElement = (function (_EventTarget) {
 16706    _inherits(HTMLTrackElement, _EventTarget);
 16707  
 16708    function HTMLTrackElement() {
 16709      var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
 16710  
 16711      _classCallCheck(this, HTMLTrackElement);
 16712  
 16713      _EventTarget.call(this);
 16714  
 16715      var readyState = undefined,
 16716          trackElement = this;
 16717  
 16718      if (browser.IS_IE8) {
 16719        trackElement = _globalDocument2['default'].createElement('custom');
 16720  
 16721        for (var prop in HTMLTrackElement.prototype) {
 16722          if (prop !== 'constructor') {
 16723            trackElement[prop] = HTMLTrackElement.prototype[prop];
 16724          }
 16725        }
 16726      }
 16727  
 16728      var track = new _tracksTextTrack2['default'](options);
 16729  
 16730      trackElement.kind = track.kind;
 16731      trackElement.src = track.src;
 16732      trackElement.srclang = track.language;
 16733      trackElement.label = track.label;
 16734      trackElement['default'] = track['default'];
 16735  
 16736      Object.defineProperty(trackElement, 'readyState', {
 16737        get: function get() {
 16738          return readyState;
 16739        }
 16740      });
 16741  
 16742      Object.defineProperty(trackElement, 'track', {
 16743        get: function get() {
 16744          return track;
 16745        }
 16746      });
 16747  
 16748      readyState = NONE;
 16749  
 16750      track.addEventListener('loadeddata', function () {
 16751        readyState = LOADED;
 16752  
 16753        trackElement.trigger({
 16754          type: 'load',
 16755          target: trackElement
 16756        });
 16757      });
 16758  
 16759      if (browser.IS_IE8) {
 16760        return trackElement;
 16761      }
 16762    }
 16763  
 16764    return HTMLTrackElement;
 16765  })(_eventTarget2['default']);
 16766  
 16767  HTMLTrackElement.prototype.allowedEvents_ = {
 16768    load: 'load'
 16769  };
 16770  
 16771  HTMLTrackElement.NONE = NONE;
 16772  HTMLTrackElement.LOADING = LOADING;
 16773  HTMLTrackElement.LOADED = LOADED;
 16774  HTMLTrackElement.ERROR = ERROR;
 16775  
 16776  exports['default'] = HTMLTrackElement;
 16777  module.exports = exports['default'];
 16778  
 16779  },{"../event-target":101,"../tracks/text-track":130,"../utils/browser.js":131,"global/document":1}],124:[function(_dereq_,module,exports){
 16780  /**
 16781   * @file text-track-cue-list.js
 16782   */
 16783  'use strict';
 16784  
 16785  exports.__esModule = true;
 16786  
 16787  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 16788  
 16789  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 16790  
 16791  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 16792  
 16793  var _utilsBrowserJs = _dereq_('../utils/browser.js');
 16794  
 16795  var browser = _interopRequireWildcard(_utilsBrowserJs);
 16796  
 16797  var _globalDocument = _dereq_('global/document');
 16798  
 16799  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 16800  
 16801  /**
 16802   * A List of text track cues as defined in:
 16803   * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist
 16804   *
 16805   * interface TextTrackCueList {
 16806   *   readonly attribute unsigned long length;
 16807   *   getter TextTrackCue (unsigned long index);
 16808   *   TextTrackCue? getCueById(DOMString id);
 16809   * };
 16810   *
 16811   * @param {Array} cues A list of cues to be initialized with
 16812   * @class TextTrackCueList
 16813   */
 16814  
 16815  var TextTrackCueList = (function () {
 16816    function TextTrackCueList(cues) {
 16817      _classCallCheck(this, TextTrackCueList);
 16818  
 16819      var list = this;
 16820  
 16821      if (browser.IS_IE8) {
 16822        list = _globalDocument2['default'].createElement('custom');
 16823  
 16824        for (var prop in TextTrackCueList.prototype) {
 16825          if (prop !== 'constructor') {
 16826            list[prop] = TextTrackCueList.prototype[prop];
 16827          }
 16828        }
 16829      }
 16830  
 16831      TextTrackCueList.prototype.setCues_.call(list, cues);
 16832  
 16833      Object.defineProperty(list, 'length', {
 16834        get: function get() {
 16835          return this.length_;
 16836        }
 16837      });
 16838  
 16839      if (browser.IS_IE8) {
 16840        return list;
 16841      }
 16842    }
 16843  
 16844    /**
 16845     * A setter for cues in this list
 16846     *
 16847     * @param {Array} cues an array of cues
 16848     * @method setCues_
 16849     * @private
 16850     */
 16851  
 16852    TextTrackCueList.prototype.setCues_ = function setCues_(cues) {
 16853      var oldLength = this.length || 0;
 16854      var i = 0;
 16855      var l = cues.length;
 16856  
 16857      this.cues_ = cues;
 16858      this.length_ = cues.length;
 16859  
 16860      var defineProp = function defineProp(index) {
 16861        if (!('' + index in this)) {
 16862          Object.defineProperty(this, '' + index, {
 16863            get: function get() {
 16864              return this.cues_[index];
 16865            }
 16866          });
 16867        }
 16868      };
 16869  
 16870      if (oldLength < l) {
 16871        i = oldLength;
 16872  
 16873        for (; i < l; i++) {
 16874          defineProp.call(this, i);
 16875        }
 16876      }
 16877    };
 16878  
 16879    /**
 16880     * Get a cue that is currently in the Cue list by id
 16881     *
 16882     * @param {String} id
 16883     * @method getCueById
 16884     * @return {Object} a single cue
 16885     */
 16886  
 16887    TextTrackCueList.prototype.getCueById = function getCueById(id) {
 16888      var result = null;
 16889  
 16890      for (var i = 0, l = this.length; i < l; i++) {
 16891        var cue = this[i];
 16892  
 16893        if (cue.id === id) {
 16894          result = cue;
 16895          break;
 16896        }
 16897      }
 16898  
 16899      return result;
 16900    };
 16901  
 16902    return TextTrackCueList;
 16903  })();
 16904  
 16905  exports['default'] = TextTrackCueList;
 16906  module.exports = exports['default'];
 16907  
 16908  },{"../utils/browser.js":131,"global/document":1}],125:[function(_dereq_,module,exports){
 16909  /**
 16910   * @file text-track-display.js
 16911   */
 16912  'use strict';
 16913  
 16914  exports.__esModule = true;
 16915  
 16916  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 16917  
 16918  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 16919  
 16920  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 16921  
 16922  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 16923  
 16924  var _component = _dereq_('../component');
 16925  
 16926  var _component2 = _interopRequireDefault(_component);
 16927  
 16928  var _menuMenuJs = _dereq_('../menu/menu.js');
 16929  
 16930  var _menuMenuJs2 = _interopRequireDefault(_menuMenuJs);
 16931  
 16932  var _menuMenuItemJs = _dereq_('../menu/menu-item.js');
 16933  
 16934  var _menuMenuItemJs2 = _interopRequireDefault(_menuMenuItemJs);
 16935  
 16936  var _menuMenuButtonJs = _dereq_('../menu/menu-button.js');
 16937  
 16938  var _menuMenuButtonJs2 = _interopRequireDefault(_menuMenuButtonJs);
 16939  
 16940  var _utilsFnJs = _dereq_('../utils/fn.js');
 16941  
 16942  var Fn = _interopRequireWildcard(_utilsFnJs);
 16943  
 16944  var _globalDocument = _dereq_('global/document');
 16945  
 16946  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 16947  
 16948  var _globalWindow = _dereq_('global/window');
 16949  
 16950  var _globalWindow2 = _interopRequireDefault(_globalWindow);
 16951  
 16952  var darkGray = '#222';
 16953  var lightGray = '#ccc';
 16954  var fontMap = {
 16955    monospace: 'monospace',
 16956    sansSerif: 'sans-serif',
 16957    serif: 'serif',
 16958    monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace',
 16959    monospaceSerif: '"Courier New", monospace',
 16960    proportionalSansSerif: 'sans-serif',
 16961    proportionalSerif: 'serif',
 16962    casual: '"Comic Sans MS", Impact, fantasy',
 16963    script: '"Monotype Corsiva", cursive',
 16964    smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif'
 16965  };
 16966  
 16967  /**
 16968   * The component for displaying text track cues
 16969   *
 16970   * @param {Object} player  Main Player
 16971   * @param {Object=} options Object of option names and values
 16972   * @param {Function=} ready    Ready callback function
 16973   * @extends Component
 16974   * @class TextTrackDisplay
 16975   */
 16976  
 16977  var TextTrackDisplay = (function (_Component) {
 16978    _inherits(TextTrackDisplay, _Component);
 16979  
 16980    function TextTrackDisplay(player, options, ready) {
 16981      _classCallCheck(this, TextTrackDisplay);
 16982  
 16983      _Component.call(this, player, options, ready);
 16984  
 16985      player.on('loadstart', Fn.bind(this, this.toggleDisplay));
 16986      player.on('texttrackchange', Fn.bind(this, this.updateDisplay));
 16987  
 16988      // This used to be called during player init, but was causing an error
 16989      // if a track should show by default and the display hadn't loaded yet.
 16990      // Should probably be moved to an external track loader when we support
 16991      // tracks that don't need a display.
 16992      player.ready(Fn.bind(this, function () {
 16993        if (player.tech_ && player.tech_['featuresNativeTextTracks']) {
 16994          this.hide();
 16995          return;
 16996        }
 16997  
 16998        player.on('fullscreenchange', Fn.bind(this, this.updateDisplay));
 16999  
 17000        var tracks = this.options_.playerOptions['tracks'] || [];
 17001        for (var i = 0; i < tracks.length; i++) {
 17002          var track = tracks[i];
 17003          this.player_.addRemoteTextTrack(track);
 17004        }
 17005      }));
 17006    }
 17007  
 17008    /**
 17009    * Add cue HTML to display
 17010    *
 17011    * @param {Number} color Hex number for color, like #f0e
 17012    * @param {Number} opacity Value for opacity,0.0 - 1.0
 17013    * @return {RGBAColor} In the form 'rgba(255, 0, 0, 0.3)'
 17014    * @method constructColor
 17015    */
 17016  
 17017    /**
 17018     * Toggle display texttracks
 17019     *
 17020     * @method toggleDisplay
 17021     */
 17022  
 17023    TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() {
 17024      if (this.player_.tech_ && this.player_.tech_['featuresNativeTextTracks']) {
 17025        this.hide();
 17026      } else {
 17027        this.show();
 17028      }
 17029    };
 17030  
 17031    /**
 17032     * Create the component's DOM element
 17033     *
 17034     * @return {Element}
 17035     * @method createEl
 17036     */
 17037  
 17038    TextTrackDisplay.prototype.createEl = function createEl() {
 17039      return _Component.prototype.createEl.call(this, 'div', {
 17040        className: 'vjs-text-track-display'
 17041      }, {
 17042        'aria-live': 'assertive',
 17043        'aria-atomic': 'true'
 17044      });
 17045    };
 17046  
 17047    /**
 17048     * Clear display texttracks
 17049     *
 17050     * @method clearDisplay
 17051     */
 17052  
 17053    TextTrackDisplay.prototype.clearDisplay = function clearDisplay() {
 17054      if (typeof _globalWindow2['default']['WebVTT'] === 'function') {
 17055        _globalWindow2['default']['WebVTT']['processCues'](_globalWindow2['default'], [], this.el_);
 17056      }
 17057    };
 17058  
 17059    /**
 17060     * Update display texttracks
 17061     *
 17062     * @method updateDisplay
 17063     */
 17064  
 17065    TextTrackDisplay.prototype.updateDisplay = function updateDisplay() {
 17066      var tracks = this.player_.textTracks();
 17067  
 17068      this.clearDisplay();
 17069  
 17070      if (!tracks) {
 17071        return;
 17072      }
 17073  
 17074      // Track display prioritization model: if multiple tracks are 'showing',
 17075      //  display the first 'subtitles' or 'captions' track which is 'showing',
 17076      //  otherwise display the first 'descriptions' track which is 'showing'
 17077  
 17078      var descriptionsTrack = null;
 17079      var captionsSubtitlesTrack = null;
 17080  
 17081      var i = tracks.length;
 17082      while (i--) {
 17083        var track = tracks[i];
 17084        if (track['mode'] === 'showing') {
 17085          if (track['kind'] === 'descriptions') {
 17086            descriptionsTrack = track;
 17087          } else {
 17088            captionsSubtitlesTrack = track;
 17089          }
 17090        }
 17091      }
 17092  
 17093      if (captionsSubtitlesTrack) {
 17094        this.updateForTrack(captionsSubtitlesTrack);
 17095      } else if (descriptionsTrack) {
 17096        this.updateForTrack(descriptionsTrack);
 17097      }
 17098    };
 17099  
 17100    /**
 17101     * Add texttrack to texttrack list
 17102     *
 17103     * @param {TextTrackObject} track Texttrack object to be added to list
 17104     * @method updateForTrack
 17105     */
 17106  
 17107    TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) {
 17108      if (typeof _globalWindow2['default']['WebVTT'] !== 'function' || !track['activeCues']) {
 17109        return;
 17110      }
 17111  
 17112      var overrides = this.player_['textTrackSettings'].getValues();
 17113  
 17114      var cues = [];
 17115      for (var _i = 0; _i < track['activeCues'].length; _i++) {
 17116        cues.push(track['activeCues'][_i]);
 17117      }
 17118  
 17119      _globalWindow2['default']['WebVTT']['processCues'](_globalWindow2['default'], cues, this.el_);
 17120  
 17121      var i = cues.length;
 17122      while (i--) {
 17123        var cue = cues[i];
 17124        if (!cue) {
 17125          continue;
 17126        }
 17127  
 17128        var cueDiv = cue.displayState;
 17129        if (overrides.color) {
 17130          cueDiv.firstChild.style.color = overrides.color;
 17131        }
 17132        if (overrides.textOpacity) {
 17133          tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity));
 17134        }
 17135        if (overrides.backgroundColor) {
 17136          cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor;
 17137        }
 17138        if (overrides.backgroundOpacity) {
 17139          tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity));
 17140        }
 17141        if (overrides.windowColor) {
 17142          if (overrides.windowOpacity) {
 17143            tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity));
 17144          } else {
 17145            cueDiv.style.backgroundColor = overrides.windowColor;
 17146          }
 17147        }
 17148        if (overrides.edgeStyle) {
 17149          if (overrides.edgeStyle === 'dropshadow') {
 17150            cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray;
 17151          } else if (overrides.edgeStyle === 'raised') {
 17152            cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray;
 17153          } else if (overrides.edgeStyle === 'depressed') {
 17154            cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray;
 17155          } else if (overrides.edgeStyle === 'uniform') {
 17156            cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray;
 17157          }
 17158        }
 17159        if (overrides.fontPercent && overrides.fontPercent !== 1) {
 17160          var fontSize = _globalWindow2['default'].parseFloat(cueDiv.style.fontSize);
 17161          cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px';
 17162          cueDiv.style.height = 'auto';
 17163          cueDiv.style.top = 'auto';
 17164          cueDiv.style.bottom = '2px';
 17165        }
 17166        if (overrides.fontFamily && overrides.fontFamily !== 'default') {
 17167          if (overrides.fontFamily === 'small-caps') {
 17168            cueDiv.firstChild.style.fontVariant = 'small-caps';
 17169          } else {
 17170            cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily];
 17171          }
 17172        }
 17173      }
 17174    };
 17175  
 17176    return TextTrackDisplay;
 17177  })(_component2['default']);
 17178  
 17179  function constructColor(color, opacity) {
 17180    return 'rgba(' +
 17181    // color looks like "#f0e"
 17182    parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')';
 17183  }
 17184  
 17185  /**
 17186   * Try to update style
 17187   * Some style changes will throw an error, particularly in IE8. Those should be noops.
 17188   *
 17189   * @param {Element} el The element to be styles
 17190   * @param {CSSProperty} style The CSS property to be styled
 17191   * @param {CSSStyle} rule The actual style to be applied to the property
 17192   * @method tryUpdateStyle
 17193   */
 17194  function tryUpdateStyle(el, style, rule) {
 17195    //
 17196    try {
 17197      el.style[style] = rule;
 17198    } catch (e) {}
 17199  }
 17200  
 17201  _component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay);
 17202  exports['default'] = TextTrackDisplay;
 17203  module.exports = exports['default'];
 17204  
 17205  },{"../component":67,"../menu/menu-button.js":106,"../menu/menu-item.js":107,"../menu/menu.js":108,"../utils/fn.js":136,"global/document":1,"global/window":2}],126:[function(_dereq_,module,exports){
 17206  /**
 17207   * @file text-track-enums.js
 17208   */
 17209  
 17210  /**
 17211   * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode
 17212   *
 17213   * enum TextTrackMode { "disabled",  "hidden",  "showing" };
 17214   */
 17215  'use strict';
 17216  
 17217  exports.__esModule = true;
 17218  var TextTrackMode = {
 17219    disabled: 'disabled',
 17220    hidden: 'hidden',
 17221    showing: 'showing'
 17222  };
 17223  
 17224  /**
 17225   * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackkind
 17226   *
 17227   * enum TextTrackKind {
 17228   *   "subtitles",
 17229   *   "captions",
 17230   *   "descriptions",
 17231   *   "chapters",
 17232   *   "metadata"
 17233   * };
 17234   */
 17235  var TextTrackKind = {
 17236    subtitles: 'subtitles',
 17237    captions: 'captions',
 17238    descriptions: 'descriptions',
 17239    chapters: 'chapters',
 17240    metadata: 'metadata'
 17241  };
 17242  
 17243  /* jshint ignore:start */
 17244  // we ignore jshint here because it does not see
 17245  // TextTrackMode or TextTrackKind as defined here somehow...
 17246  exports.TextTrackMode = TextTrackMode;
 17247  exports.TextTrackKind = TextTrackKind;
 17248  
 17249  /* jshint ignore:end */
 17250  
 17251  },{}],127:[function(_dereq_,module,exports){
 17252  /**
 17253   * Utilities for capturing text track state and re-creating tracks
 17254   * based on a capture.
 17255   *
 17256   * @file text-track-list-converter.js
 17257   */
 17258  
 17259  /**
 17260   * Examine a single text track and return a JSON-compatible javascript
 17261   * object that represents the text track's state.
 17262   * @param track {TextTrackObject} the text track to query
 17263   * @return {Object} a serializable javascript representation of the
 17264   * @private
 17265   */
 17266  'use strict';
 17267  
 17268  exports.__esModule = true;
 17269  var trackToJson_ = function trackToJson_(track) {
 17270    var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) {
 17271      if (track[prop]) {
 17272        acc[prop] = track[prop];
 17273      }
 17274  
 17275      return acc;
 17276    }, {
 17277      cues: track.cues && Array.prototype.map.call(track.cues, function (cue) {
 17278        return {
 17279          startTime: cue.startTime,
 17280          endTime: cue.endTime,
 17281          text: cue.text,
 17282          id: cue.id
 17283        };
 17284      })
 17285    });
 17286  
 17287    return ret;
 17288  };
 17289  
 17290  /**
 17291   * Examine a tech and return a JSON-compatible javascript array that
 17292   * represents the state of all text tracks currently configured. The
 17293   * return array is compatible with `jsonToTextTracks`.
 17294   * @param tech {tech} the tech object to query
 17295   * @return {Array} a serializable javascript representation of the
 17296   * @function textTracksToJson
 17297   */
 17298  var textTracksToJson = function textTracksToJson(tech) {
 17299  
 17300    var trackEls = tech.$$('track');
 17301  
 17302    var trackObjs = Array.prototype.map.call(trackEls, function (t) {
 17303      return t.track;
 17304    });
 17305    var tracks = Array.prototype.map.call(trackEls, function (trackEl) {
 17306      var json = trackToJson_(trackEl.track);
 17307      if (trackEl.src) {
 17308        json.src = trackEl.src;
 17309      }
 17310      return json;
 17311    });
 17312  
 17313    return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) {
 17314      return trackObjs.indexOf(track) === -1;
 17315    }).map(trackToJson_));
 17316  };
 17317  
 17318  /**
 17319   * Creates a set of remote text tracks on a tech based on an array of
 17320   * javascript text track representations.
 17321   * @param json {Array} an array of text track representation objects,
 17322   * like those that would be produced by `textTracksToJson`
 17323   * @param tech {tech} the tech to create text tracks on
 17324   * @function jsonToTextTracks
 17325   */
 17326  var jsonToTextTracks = function jsonToTextTracks(json, tech) {
 17327    json.forEach(function (track) {
 17328      var addedTrack = tech.addRemoteTextTrack(track).track;
 17329      if (!track.src && track.cues) {
 17330        track.cues.forEach(function (cue) {
 17331          return addedTrack.addCue(cue);
 17332        });
 17333      }
 17334    });
 17335  
 17336    return tech.textTracks();
 17337  };
 17338  
 17339  exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ };
 17340  module.exports = exports['default'];
 17341  
 17342  },{}],128:[function(_dereq_,module,exports){
 17343  /**
 17344   * @file text-track-list.js
 17345   */
 17346  'use strict';
 17347  
 17348  exports.__esModule = true;
 17349  
 17350  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 17351  
 17352  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 17353  
 17354  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 17355  
 17356  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 17357  
 17358  var _eventTarget = _dereq_('../event-target');
 17359  
 17360  var _eventTarget2 = _interopRequireDefault(_eventTarget);
 17361  
 17362  var _utilsFnJs = _dereq_('../utils/fn.js');
 17363  
 17364  var Fn = _interopRequireWildcard(_utilsFnJs);
 17365  
 17366  var _utilsBrowserJs = _dereq_('../utils/browser.js');
 17367  
 17368  var browser = _interopRequireWildcard(_utilsBrowserJs);
 17369  
 17370  var _globalDocument = _dereq_('global/document');
 17371  
 17372  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 17373  
 17374  /**
 17375   * A text track list as defined in:
 17376   * https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist
 17377   *
 17378   * interface TextTrackList : EventTarget {
 17379   *   readonly attribute unsigned long length;
 17380   *   getter TextTrack (unsigned long index);
 17381   *   TextTrack? getTrackById(DOMString id);
 17382   *
 17383   *   attribute EventHandler onchange;
 17384   *   attribute EventHandler onaddtrack;
 17385   *   attribute EventHandler onremovetrack;
 17386   * };
 17387   *
 17388   * @param {Track[]} tracks A list of tracks to initialize the list with
 17389   * @extends EventTarget
 17390   * @class TextTrackList
 17391   */
 17392  
 17393  var TextTrackList = (function (_EventTarget) {
 17394    _inherits(TextTrackList, _EventTarget);
 17395  
 17396    function TextTrackList() {
 17397      var tracks = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
 17398  
 17399      _classCallCheck(this, TextTrackList);
 17400  
 17401      _EventTarget.call(this);
 17402      var list = this;
 17403  
 17404      if (browser.IS_IE8) {
 17405        list = _globalDocument2['default'].createElement('custom');
 17406  
 17407        for (var prop in TextTrackList.prototype) {
 17408          if (prop !== 'constructor') {
 17409            list[prop] = TextTrackList.prototype[prop];
 17410          }
 17411        }
 17412      }
 17413  
 17414      list.tracks_ = [];
 17415  
 17416      Object.defineProperty(list, 'length', {
 17417        get: function get() {
 17418          return this.tracks_.length;
 17419        }
 17420      });
 17421  
 17422      for (var i = 0; i < tracks.length; i++) {
 17423        list.addTrack_(tracks[i]);
 17424      }
 17425  
 17426      if (browser.IS_IE8) {
 17427        return list;
 17428      }
 17429    }
 17430  
 17431    /**
 17432     * change - One or more tracks in the track list have been enabled or disabled.
 17433     * addtrack - A track has been added to the track list.
 17434     * removetrack - A track has been removed from the track list.
 17435     */
 17436  
 17437    /**
 17438     * Add TextTrack from TextTrackList
 17439     *
 17440     * @param {TextTrack} track
 17441     * @method addTrack_
 17442     * @private
 17443     */
 17444  
 17445    TextTrackList.prototype.addTrack_ = function addTrack_(track) {
 17446      var index = this.tracks_.length;
 17447  
 17448      if (!('' + index in this)) {
 17449        Object.defineProperty(this, index, {
 17450          get: function get() {
 17451            return this.tracks_[index];
 17452          }
 17453        });
 17454      }
 17455  
 17456      track.addEventListener('modechange', Fn.bind(this, function () {
 17457        this.trigger('change');
 17458      }));
 17459  
 17460      // Do not add duplicate tracks
 17461      if (this.tracks_.indexOf(track) === -1) {
 17462        this.tracks_.push(track);
 17463        this.trigger({
 17464          track: track,
 17465          type: 'addtrack'
 17466        });
 17467      }
 17468    };
 17469  
 17470    /**
 17471     * Remove TextTrack from TextTrackList
 17472     * NOTE: Be mindful of what is passed in as it may be a HTMLTrackElement
 17473     *
 17474     * @param {TextTrack} rtrack
 17475     * @method removeTrack_
 17476     * @private
 17477     */
 17478  
 17479    TextTrackList.prototype.removeTrack_ = function removeTrack_(rtrack) {
 17480      var track = undefined;
 17481  
 17482      for (var i = 0, l = this.length; i < l; i++) {
 17483        if (this[i] === rtrack) {
 17484          track = this[i];
 17485          if (track.off) {
 17486            track.off();
 17487          }
 17488  
 17489          this.tracks_.splice(i, 1);
 17490  
 17491          break;
 17492        }
 17493      }
 17494  
 17495      if (!track) {
 17496        return;
 17497      }
 17498  
 17499      this.trigger({
 17500        track: track,
 17501        type: 'removetrack'
 17502      });
 17503    };
 17504  
 17505    /**
 17506     * Get a TextTrack from TextTrackList by a tracks id
 17507     *
 17508     * @param {String} id - the id of the track to get
 17509     * @method getTrackById
 17510     * @return {TextTrack}
 17511     * @private
 17512     */
 17513  
 17514    TextTrackList.prototype.getTrackById = function getTrackById(id) {
 17515      var result = null;
 17516  
 17517      for (var i = 0, l = this.length; i < l; i++) {
 17518        var track = this[i];
 17519  
 17520        if (track.id === id) {
 17521          result = track;
 17522          break;
 17523        }
 17524      }
 17525  
 17526      return result;
 17527    };
 17528  
 17529    return TextTrackList;
 17530  })(_eventTarget2['default']);
 17531  
 17532  TextTrackList.prototype.allowedEvents_ = {
 17533    change: 'change',
 17534    addtrack: 'addtrack',
 17535    removetrack: 'removetrack'
 17536  };
 17537  
 17538  // emulate attribute EventHandler support to allow for feature detection
 17539  for (var _event in TextTrackList.prototype.allowedEvents_) {
 17540    TextTrackList.prototype['on' + _event] = null;
 17541  }
 17542  
 17543  exports['default'] = TextTrackList;
 17544  module.exports = exports['default'];
 17545  
 17546  },{"../event-target":101,"../utils/browser.js":131,"../utils/fn.js":136,"global/document":1}],129:[function(_dereq_,module,exports){
 17547  /**
 17548   * @file text-track-settings.js
 17549   */
 17550  'use strict';
 17551  
 17552  exports.__esModule = true;
 17553  
 17554  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 17555  
 17556  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 17557  
 17558  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 17559  
 17560  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 17561  
 17562  var _component = _dereq_('../component');
 17563  
 17564  var _component2 = _interopRequireDefault(_component);
 17565  
 17566  var _utilsEventsJs = _dereq_('../utils/events.js');
 17567  
 17568  var Events = _interopRequireWildcard(_utilsEventsJs);
 17569  
 17570  var _utilsFnJs = _dereq_('../utils/fn.js');
 17571  
 17572  var Fn = _interopRequireWildcard(_utilsFnJs);
 17573  
 17574  var _utilsLogJs = _dereq_('../utils/log.js');
 17575  
 17576  var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
 17577  
 17578  var _safeJsonParseTuple = _dereq_('safe-json-parse/tuple');
 17579  
 17580  var _safeJsonParseTuple2 = _interopRequireDefault(_safeJsonParseTuple);
 17581  
 17582  var _globalWindow = _dereq_('global/window');
 17583  
 17584  var _globalWindow2 = _interopRequireDefault(_globalWindow);
 17585  
 17586  /**
 17587   * Manipulate settings of texttracks
 17588   *
 17589   * @param {Object} player  Main Player
 17590   * @param {Object=} options Object of option names and values
 17591   * @extends Component
 17592   * @class TextTrackSettings
 17593   */
 17594  
 17595  var TextTrackSettings = (function (_Component) {
 17596    _inherits(TextTrackSettings, _Component);
 17597  
 17598    function TextTrackSettings(player, options) {
 17599      _classCallCheck(this, TextTrackSettings);
 17600  
 17601      _Component.call(this, player, options);
 17602      this.hide();
 17603  
 17604      // Grab `persistTextTrackSettings` from the player options if not passed in child options
 17605      if (options.persistTextTrackSettings === undefined) {
 17606        this.options_.persistTextTrackSettings = this.options_.playerOptions.persistTextTrackSettings;
 17607      }
 17608  
 17609      Events.on(this.$('.vjs-done-button'), 'click', Fn.bind(this, function () {
 17610        this.saveSettings();
 17611        this.hide();
 17612      }));
 17613  
 17614      Events.on(this.$('.vjs-default-button'), 'click', Fn.bind(this, function () {
 17615        this.$('.vjs-fg-color > select').selectedIndex = 0;
 17616        this.$('.vjs-bg-color > select').selectedIndex = 0;
 17617        this.$('.window-color > select').selectedIndex = 0;
 17618        this.$('.vjs-text-opacity > select').selectedIndex = 0;
 17619        this.$('.vjs-bg-opacity > select').selectedIndex = 0;
 17620        this.$('.vjs-window-opacity > select').selectedIndex = 0;
 17621        this.$('.vjs-edge-style select').selectedIndex = 0;
 17622        this.$('.vjs-font-family select').selectedIndex = 0;
 17623        this.$('.vjs-font-percent select').selectedIndex = 2;
 17624        this.updateDisplay();
 17625      }));
 17626  
 17627      Events.on(this.$('.vjs-fg-color > select'), 'change', Fn.bind(this, this.updateDisplay));
 17628      Events.on(this.$('.vjs-bg-color > select'), 'change', Fn.bind(this, this.updateDisplay));
 17629      Events.on(this.$('.window-color > select'), 'change', Fn.bind(this, this.updateDisplay));
 17630      Events.on(this.$('.vjs-text-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
 17631      Events.on(this.$('.vjs-bg-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
 17632      Events.on(this.$('.vjs-window-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
 17633      Events.on(this.$('.vjs-font-percent select'), 'change', Fn.bind(this, this.updateDisplay));
 17634      Events.on(this.$('.vjs-edge-style select'), 'change', Fn.bind(this, this.updateDisplay));
 17635      Events.on(this.$('.vjs-font-family select'), 'change', Fn.bind(this, this.updateDisplay));
 17636  
 17637      if (this.options_.persistTextTrackSettings) {
 17638        this.restoreSettings();
 17639      }
 17640    }
 17641  
 17642    /**
 17643     * Create the component's DOM element
 17644     *
 17645     * @return {Element}
 17646     * @method createEl
 17647     */
 17648  
 17649    TextTrackSettings.prototype.createEl = function createEl() {
 17650      return _Component.prototype.createEl.call(this, 'div', {
 17651        className: 'vjs-caption-settings vjs-modal-overlay',
 17652        innerHTML: captionOptionsMenuTemplate()
 17653      });
 17654    };
 17655  
 17656    /**
 17657     * Get texttrack settings
 17658     * Settings are
 17659     * .vjs-edge-style
 17660     * .vjs-font-family
 17661     * .vjs-fg-color
 17662     * .vjs-text-opacity
 17663     * .vjs-bg-color
 17664     * .vjs-bg-opacity
 17665     * .window-color
 17666     * .vjs-window-opacity
 17667     *
 17668     * @return {Object}
 17669     * @method getValues
 17670     */
 17671  
 17672    TextTrackSettings.prototype.getValues = function getValues() {
 17673      var textEdge = getSelectedOptionValue(this.$('.vjs-edge-style select'));
 17674      var fontFamily = getSelectedOptionValue(this.$('.vjs-font-family select'));
 17675      var fgColor = getSelectedOptionValue(this.$('.vjs-fg-color > select'));
 17676      var textOpacity = getSelectedOptionValue(this.$('.vjs-text-opacity > select'));
 17677      var bgColor = getSelectedOptionValue(this.$('.vjs-bg-color > select'));
 17678      var bgOpacity = getSelectedOptionValue(this.$('.vjs-bg-opacity > select'));
 17679      var windowColor = getSelectedOptionValue(this.$('.window-color > select'));
 17680      var windowOpacity = getSelectedOptionValue(this.$('.vjs-window-opacity > select'));
 17681      var fontPercent = _globalWindow2['default']['parseFloat'](getSelectedOptionValue(this.$('.vjs-font-percent > select')));
 17682  
 17683      var result = {
 17684        'backgroundOpacity': bgOpacity,
 17685        'textOpacity': textOpacity,
 17686        'windowOpacity': windowOpacity,
 17687        'edgeStyle': textEdge,
 17688        'fontFamily': fontFamily,
 17689        'color': fgColor,
 17690        'backgroundColor': bgColor,
 17691        'windowColor': windowColor,
 17692        'fontPercent': fontPercent
 17693      };
 17694      for (var _name in result) {
 17695        if (result[_name] === '' || result[_name] === 'none' || _name === 'fontPercent' && result[_name] === 1.00) {
 17696          delete result[_name];
 17697        }
 17698      }
 17699      return result;
 17700    };
 17701  
 17702    /**
 17703     * Set texttrack settings
 17704     * Settings are
 17705     * .vjs-edge-style
 17706     * .vjs-font-family
 17707     * .vjs-fg-color
 17708     * .vjs-text-opacity
 17709     * .vjs-bg-color
 17710     * .vjs-bg-opacity
 17711     * .window-color
 17712     * .vjs-window-opacity
 17713     *
 17714     * @param {Object} values Object with texttrack setting values
 17715     * @method setValues
 17716     */
 17717  
 17718    TextTrackSettings.prototype.setValues = function setValues(values) {
 17719      setSelectedOption(this.$('.vjs-edge-style select'), values.edgeStyle);
 17720      setSelectedOption(this.$('.vjs-font-family select'), values.fontFamily);
 17721      setSelectedOption(this.$('.vjs-fg-color > select'), values.color);
 17722      setSelectedOption(this.$('.vjs-text-opacity > select'), values.textOpacity);
 17723      setSelectedOption(this.$('.vjs-bg-color > select'), values.backgroundColor);
 17724      setSelectedOption(this.$('.vjs-bg-opacity > select'), values.backgroundOpacity);
 17725      setSelectedOption(this.$('.window-color > select'), values.windowColor);
 17726      setSelectedOption(this.$('.vjs-window-opacity > select'), values.windowOpacity);
 17727  
 17728      var fontPercent = values.fontPercent;
 17729  
 17730      if (fontPercent) {
 17731        fontPercent = fontPercent.toFixed(2);
 17732      }
 17733  
 17734      setSelectedOption(this.$('.vjs-font-percent > select'), fontPercent);
 17735    };
 17736  
 17737    /**
 17738     * Restore texttrack settings
 17739     *
 17740     * @method restoreSettings
 17741     */
 17742  
 17743    TextTrackSettings.prototype.restoreSettings = function restoreSettings() {
 17744      var err = undefined,
 17745          values = undefined;
 17746  
 17747      try {
 17748        var _safeParseTuple = _safeJsonParseTuple2['default'](_globalWindow2['default'].localStorage.getItem('vjs-text-track-settings'));
 17749  
 17750        err = _safeParseTuple[0];
 17751        values = _safeParseTuple[1];
 17752  
 17753        if (err) {
 17754          _utilsLogJs2['default'].error(err);
 17755        }
 17756      } catch (e) {
 17757        _utilsLogJs2['default'].warn(e);
 17758      }
 17759  
 17760      if (values) {
 17761        this.setValues(values);
 17762      }
 17763    };
 17764  
 17765    /**
 17766     * Save texttrack settings to local storage
 17767     *
 17768     * @method saveSettings
 17769     */
 17770  
 17771    TextTrackSettings.prototype.saveSettings = function saveSettings() {
 17772      if (!this.options_.persistTextTrackSettings) {
 17773        return;
 17774      }
 17775  
 17776      var values = this.getValues();
 17777      try {
 17778        if (Object.getOwnPropertyNames(values).length > 0) {
 17779          _globalWindow2['default'].localStorage.setItem('vjs-text-track-settings', JSON.stringify(values));
 17780        } else {
 17781          _globalWindow2['default'].localStorage.removeItem('vjs-text-track-settings');
 17782        }
 17783      } catch (e) {
 17784        _utilsLogJs2['default'].warn(e);
 17785      }
 17786    };
 17787  
 17788    /**
 17789     * Update display of texttrack settings
 17790     *
 17791     * @method updateDisplay
 17792     */
 17793  
 17794    TextTrackSettings.prototype.updateDisplay = function updateDisplay() {
 17795      var ttDisplay = this.player_.getChild('textTrackDisplay');
 17796      if (ttDisplay) {
 17797        ttDisplay.updateDisplay();
 17798      }
 17799    };
 17800  
 17801    return TextTrackSettings;
 17802  })(_component2['default']);
 17803  
 17804  _component2['default'].registerComponent('TextTrackSettings', TextTrackSettings);
 17805  
 17806  function getSelectedOptionValue(target) {
 17807    var selectedOption = undefined;
 17808    // not all browsers support selectedOptions, so, fallback to options
 17809    if (target.selectedOptions) {
 17810      selectedOption = target.selectedOptions[0];
 17811    } else if (target.options) {
 17812      selectedOption = target.options[target.options.selectedIndex];
 17813    }
 17814  
 17815    return selectedOption.value;
 17816  }
 17817  
 17818  function setSelectedOption(target, value) {
 17819    if (!value) {
 17820      return;
 17821    }
 17822  
 17823    var i = undefined;
 17824    for (i = 0; i < target.options.length; i++) {
 17825      var option = target.options[i];
 17826      if (option.value === value) {
 17827        break;
 17828      }
 17829    }
 17830  
 17831    target.selectedIndex = i;
 17832  }
 17833  
 17834  function captionOptionsMenuTemplate() {
 17835    var template = '<div class="vjs-tracksettings">\n      <div class="vjs-tracksettings-colors">\n        <div class="vjs-fg-color vjs-tracksetting">\n            <label class="vjs-label">Foreground</label>\n            <select>\n              <option value="">---</option>\n              <option value="#FFF">White</option>\n              <option value="#000">Black</option>\n              <option value="#F00">Red</option>\n              <option value="#0F0">Green</option>\n              <option value="#00F">Blue</option>\n              <option value="#FF0">Yellow</option>\n              <option value="#F0F">Magenta</option>\n              <option value="#0FF">Cyan</option>\n            </select>\n            <span class="vjs-text-opacity vjs-opacity">\n              <select>\n                <option value="">---</option>\n                <option value="1">Opaque</option>\n                <option value="0.5">Semi-Opaque</option>\n              </select>\n            </span>\n        </div> <!-- vjs-fg-color -->\n        <div class="vjs-bg-color vjs-tracksetting">\n            <label class="vjs-label">Background</label>\n            <select>\n              <option value="">---</option>\n              <option value="#FFF">White</option>\n              <option value="#000">Black</option>\n              <option value="#F00">Red</option>\n              <option value="#0F0">Green</option>\n              <option value="#00F">Blue</option>\n              <option value="#FF0">Yellow</option>\n              <option value="#F0F">Magenta</option>\n              <option value="#0FF">Cyan</option>\n            </select>\n            <span class="vjs-bg-opacity vjs-opacity">\n                <select>\n                  <option value="">---</option>\n                  <option value="1">Opaque</option>\n                  <option value="0.5">Semi-Transparent</option>\n                  <option value="0">Transparent</option>\n                </select>\n            </span>\n        </div> <!-- vjs-bg-color -->\n        <div class="window-color vjs-tracksetting">\n            <label class="vjs-label">Window</label>\n            <select>\n              <option value="">---</option>\n              <option value="#FFF">White</option>\n              <option value="#000">Black</option>\n              <option value="#F00">Red</option>\n              <option value="#0F0">Green</option>\n              <option value="#00F">Blue</option>\n              <option value="#FF0">Yellow</option>\n              <option value="#F0F">Magenta</option>\n              <option value="#0FF">Cyan</option>\n            </select>\n            <span class="vjs-window-opacity vjs-opacity">\n                <select>\n                  <option value="">---</option>\n                  <option value="1">Opaque</option>\n                  <option value="0.5">Semi-Transparent</option>\n                  <option value="0">Transparent</option>\n                </select>\n            </span>\n        </div> <!-- vjs-window-color -->\n      </div> <!-- vjs-tracksettings -->\n      <div class="vjs-tracksettings-font">\n        <div class="vjs-font-percent vjs-tracksetting">\n          <label class="vjs-label">Font Size</label>\n          <select>\n            <option value="0.50">50%</option>\n            <option value="0.75">75%</option>\n            <option value="1.00" selected>100%</option>\n            <option value="1.25">125%</option>\n            <option value="1.50">150%</option>\n            <option value="1.75">175%</option>\n            <option value="2.00">200%</option>\n            <option value="3.00">300%</option>\n            <option value="4.00">400%</option>\n          </select>\n        </div> <!-- vjs-font-percent -->\n        <div class="vjs-edge-style vjs-tracksetting">\n          <label class="vjs-label">Text Edge Style</label>\n          <select>\n            <option value="none">None</option>\n            <option value="raised">Raised</option>\n            <option value="depressed">Depressed</option>\n            <option value="uniform">Uniform</option>\n            <option value="dropshadow">Dropshadow</option>\n          </select>\n        </div> <!-- vjs-edge-style -->\n        <div class="vjs-font-family vjs-tracksetting">\n          <label class="vjs-label">Font Family</label>\n          <select>\n            <option value="">Default</option>\n            <option value="monospaceSerif">Monospace Serif</option>\n            <option value="proportionalSerif">Proportional Serif</option>\n            <option value="monospaceSansSerif">Monospace Sans-Serif</option>\n            <option value="proportionalSansSerif">Proportional Sans-Serif</option>\n            <option value="casual">Casual</option>\n            <option value="script">Script</option>\n            <option value="small-caps">Small Caps</option>\n          </select>\n        </div> <!-- vjs-font-family -->\n      </div>\n    </div>\n    <div class="vjs-tracksettings-controls">\n      <button class="vjs-default-button">Defaults</button>\n      <button class="vjs-done-button">Done</button>\n    </div>';
 17836  
 17837    return template;
 17838  }
 17839  
 17840  exports['default'] = TextTrackSettings;
 17841  module.exports = exports['default'];
 17842  
 17843  },{"../component":67,"../utils/events.js":135,"../utils/fn.js":136,"../utils/log.js":139,"global/window":2,"safe-json-parse/tuple":54}],130:[function(_dereq_,module,exports){
 17844  /**
 17845   * @file text-track.js
 17846   */
 17847  'use strict';
 17848  
 17849  exports.__esModule = true;
 17850  
 17851  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 17852  
 17853  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 17854  
 17855  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 17856  
 17857  function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 17858  
 17859  var _textTrackCueList = _dereq_('./text-track-cue-list');
 17860  
 17861  var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList);
 17862  
 17863  var _utilsFnJs = _dereq_('../utils/fn.js');
 17864  
 17865  var Fn = _interopRequireWildcard(_utilsFnJs);
 17866  
 17867  var _utilsGuidJs = _dereq_('../utils/guid.js');
 17868  
 17869  var Guid = _interopRequireWildcard(_utilsGuidJs);
 17870  
 17871  var _utilsBrowserJs = _dereq_('../utils/browser.js');
 17872  
 17873  var browser = _interopRequireWildcard(_utilsBrowserJs);
 17874  
 17875  var _textTrackEnums = _dereq_('./text-track-enums');
 17876  
 17877  var TextTrackEnum = _interopRequireWildcard(_textTrackEnums);
 17878  
 17879  var _utilsLogJs = _dereq_('../utils/log.js');
 17880  
 17881  var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
 17882  
 17883  var _eventTarget = _dereq_('../event-target');
 17884  
 17885  var _eventTarget2 = _interopRequireDefault(_eventTarget);
 17886  
 17887  var _globalDocument = _dereq_('global/document');
 17888  
 17889  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 17890  
 17891  var _globalWindow = _dereq_('global/window');
 17892  
 17893  var _globalWindow2 = _interopRequireDefault(_globalWindow);
 17894  
 17895  var _utilsUrlJs = _dereq_('../utils/url.js');
 17896  
 17897  var _xhr = _dereq_('xhr');
 17898  
 17899  var _xhr2 = _interopRequireDefault(_xhr);
 17900  
 17901  /**
 17902   * takes a webvtt file contents and parses it into cues
 17903   *
 17904   * @param {String} srcContent webVTT file contents
 17905   * @param {Track} track track to addcues to
 17906   */
 17907  var parseCues = function parseCues(srcContent, track) {
 17908    var parser = new _globalWindow2['default'].WebVTT.Parser(_globalWindow2['default'], _globalWindow2['default'].vttjs, _globalWindow2['default'].WebVTT.StringDecoder());
 17909  
 17910    parser.oncue = function (cue) {
 17911      track.addCue(cue);
 17912    };
 17913  
 17914    parser.onparsingerror = function (error) {
 17915      _utilsLogJs2['default'].error(error);
 17916    };
 17917  
 17918    parser.onflush = function () {
 17919      track.trigger({
 17920        type: 'loadeddata',
 17921        target: track
 17922      });
 17923    };
 17924  
 17925    parser.parse(srcContent);
 17926    parser.flush();
 17927  };
 17928  
 17929  /**
 17930   * load a track from a  specifed url
 17931   *
 17932   * @param {String} src url to load track from
 17933   * @param {Track} track track to addcues to
 17934   */
 17935  var loadTrack = function loadTrack(src, track) {
 17936    var opts = {
 17937      uri: src
 17938    };
 17939    var crossOrigin = _utilsUrlJs.isCrossOrigin(src);
 17940  
 17941    if (crossOrigin) {
 17942      opts.cors = crossOrigin;
 17943    }
 17944  
 17945    _xhr2['default'](opts, Fn.bind(this, function (err, response, responseBody) {
 17946      if (err) {
 17947        return _utilsLogJs2['default'].error(err, response);
 17948      }
 17949  
 17950      track.loaded_ = true;
 17951  
 17952      // Make sure that vttjs has loaded, otherwise, wait till it finished loading
 17953      // NOTE: this is only used for the alt/video.novtt.js build
 17954      if (typeof _globalWindow2['default'].WebVTT !== 'function') {
 17955        if (track.tech_) {
 17956          (function () {
 17957            var loadHandler = function loadHandler() {
 17958              return parseCues(responseBody, track);
 17959            };
 17960            track.tech_.on('vttjsloaded', loadHandler);
 17961            track.tech_.on('vttjserror', function () {
 17962              _utilsLogJs2['default'].error('vttjs failed to load, stopping trying to process ' + track.src);
 17963              track.tech_.off('vttjsloaded', loadHandler);
 17964            });
 17965          })();
 17966        }
 17967      } else {
 17968        parseCues(responseBody, track);
 17969      }
 17970    }));
 17971  };
 17972  
 17973  /**
 17974   * A single text track as defined in:
 17975   * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack
 17976   *
 17977   * interface TextTrack : EventTarget {
 17978   *   readonly attribute TextTrackKind kind;
 17979   *   readonly attribute DOMString label;
 17980   *   readonly attribute DOMString language;
 17981   *
 17982   *   readonly attribute DOMString id;
 17983   *   readonly attribute DOMString inBandMetadataTrackDispatchType;
 17984   *
 17985   *   attribute TextTrackMode mode;
 17986   *
 17987   *   readonly attribute TextTrackCueList? cues;
 17988   *   readonly attribute TextTrackCueList? activeCues;
 17989   *
 17990   *   void addCue(TextTrackCue cue);
 17991   *   void removeCue(TextTrackCue cue);
 17992   *
 17993   *   attribute EventHandler oncuechange;
 17994   * };
 17995   *
 17996   * @param {Object=} options Object of option names and values
 17997   * @extends EventTarget
 17998   * @class TextTrack
 17999   */
 18000  
 18001  var TextTrack = (function (_EventTarget) {
 18002    _inherits(TextTrack, _EventTarget);
 18003  
 18004    function TextTrack() {
 18005      var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
 18006  
 18007      _classCallCheck(this, TextTrack);
 18008  
 18009      _EventTarget.call(this);
 18010      if (!options.tech) {
 18011        throw new Error('A tech was not provided.');
 18012      }
 18013  
 18014      var tt = this;
 18015  
 18016      if (browser.IS_IE8) {
 18017        tt = _globalDocument2['default'].createElement('custom');
 18018  
 18019        for (var prop in TextTrack.prototype) {
 18020          if (prop !== 'constructor') {
 18021            tt[prop] = TextTrack.prototype[prop];
 18022          }
 18023        }
 18024      }
 18025  
 18026      tt.tech_ = options.tech;
 18027  
 18028      var mode = TextTrackEnum.TextTrackMode[options.mode] || 'disabled';
 18029      var kind = TextTrackEnum.TextTrackKind[options.kind] || 'subtitles';
 18030      var label = options.label || '';
 18031      var language = options.language || options.srclang || '';
 18032      var id = options.id || 'vjs_text_track_' + Guid.newGUID();
 18033  
 18034      if (kind === 'metadata' || kind === 'chapters') {
 18035        mode = 'hidden';
 18036      }
 18037  
 18038      tt.cues_ = [];
 18039      tt.activeCues_ = [];
 18040  
 18041      var cues = new _textTrackCueList2['default'](tt.cues_);
 18042      var activeCues = new _textTrackCueList2['default'](tt.activeCues_);
 18043      var changed = false;
 18044      var timeupdateHandler = Fn.bind(tt, function () {
 18045        this.activeCues;
 18046        if (changed) {
 18047          this.trigger('cuechange');
 18048          changed = false;
 18049        }
 18050      });
 18051  
 18052      if (mode !== 'disabled') {
 18053        tt.tech_.on('timeupdate', timeupdateHandler);
 18054      }
 18055  
 18056      Object.defineProperty(tt, 'kind', {
 18057        get: function get() {
 18058          return kind;
 18059        },
 18060        set: function set() {}
 18061      });
 18062  
 18063      Object.defineProperty(tt, 'label', {
 18064        get: function get() {
 18065          return label;
 18066        },
 18067        set: function set() {}
 18068      });
 18069  
 18070      Object.defineProperty(tt, 'language', {
 18071        get: function get() {
 18072          return language;
 18073        },
 18074        set: function set() {}
 18075      });
 18076  
 18077      Object.defineProperty(tt, 'id', {
 18078        get: function get() {
 18079          return id;
 18080        },
 18081        set: function set() {}
 18082      });
 18083  
 18084      Object.defineProperty(tt, 'mode', {
 18085        get: function get() {
 18086          return mode;
 18087        },
 18088        set: function set(newMode) {
 18089          if (!TextTrackEnum.TextTrackMode[newMode]) {
 18090            return;
 18091          }
 18092          mode = newMode;
 18093          if (mode === 'showing') {
 18094            this.tech_.on('timeupdate', timeupdateHandler);
 18095          }
 18096          this.trigger('modechange');
 18097        }
 18098      });
 18099  
 18100      Object.defineProperty(tt, 'cues', {
 18101        get: function get() {
 18102          if (!this.loaded_) {
 18103            return null;
 18104          }
 18105  
 18106          return cues;
 18107        },
 18108        set: function set() {}
 18109      });
 18110  
 18111      Object.defineProperty(tt, 'activeCues', {
 18112        get: function get() {
 18113          if (!this.loaded_) {
 18114            return null;
 18115          }
 18116  
 18117          // nothing to do
 18118          if (this.cues.length === 0) {
 18119            return activeCues;
 18120          }
 18121  
 18122          var ct = this.tech_.currentTime();
 18123          var active = [];
 18124  
 18125          for (var i = 0, l = this.cues.length; i < l; i++) {
 18126            var cue = this.cues[i];
 18127  
 18128            if (cue.startTime <= ct && cue.endTime >= ct) {
 18129              active.push(cue);
 18130            } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) {
 18131              active.push(cue);
 18132            }
 18133          }
 18134  
 18135          changed = false;
 18136  
 18137          if (active.length !== this.activeCues_.length) {
 18138            changed = true;
 18139          } else {
 18140            for (var i = 0; i < active.length; i++) {
 18141              if (this.activeCues_.indexOf(active[i]) === -1) {
 18142                changed = true;
 18143              }
 18144            }
 18145          }
 18146  
 18147          this.activeCues_ = active;
 18148          activeCues.setCues_(this.activeCues_);
 18149  
 18150          return activeCues;
 18151        },
 18152        set: function set() {}
 18153      });
 18154  
 18155      if (options.src) {
 18156        tt.src = options.src;
 18157        loadTrack(options.src, tt);
 18158      } else {
 18159        tt.loaded_ = true;
 18160      }
 18161  
 18162      if (browser.IS_IE8) {
 18163        return tt;
 18164      }
 18165    }
 18166  
 18167    /**
 18168     * cuechange - One or more cues in the track have become active or stopped being active.
 18169     */
 18170  
 18171    /**
 18172     * add a cue to the internal list of cues
 18173     *
 18174     * @param {Object} cue the cue to add to our internal list
 18175     * @method addCue
 18176     */
 18177  
 18178    TextTrack.prototype.addCue = function addCue(cue) {
 18179      var tracks = this.tech_.textTracks();
 18180  
 18181      if (tracks) {
 18182        for (var i = 0; i < tracks.length; i++) {
 18183          if (tracks[i] !== this) {
 18184            tracks[i].removeCue(cue);
 18185          }
 18186        }
 18187      }
 18188  
 18189      this.cues_.push(cue);
 18190      this.cues.setCues_(this.cues_);
 18191    };
 18192  
 18193    /**
 18194     * remvoe a cue from our internal list
 18195     *
 18196     * @param {Object} removeCue the cue to remove from our internal list
 18197     * @method removeCue
 18198     */
 18199  
 18200    TextTrack.prototype.removeCue = function removeCue(_removeCue) {
 18201      var removed = false;
 18202  
 18203      for (var i = 0, l = this.cues_.length; i < l; i++) {
 18204        var cue = this.cues_[i];
 18205  
 18206        if (cue === _removeCue) {
 18207          this.cues_.splice(i, 1);
 18208          removed = true;
 18209        }
 18210      }
 18211  
 18212      if (removed) {
 18213        this.cues.setCues_(this.cues_);
 18214      }
 18215    };
 18216  
 18217    return TextTrack;
 18218  })(_eventTarget2['default']);
 18219  
 18220  TextTrack.prototype.allowedEvents_ = {
 18221    cuechange: 'cuechange'
 18222  };
 18223  
 18224  exports['default'] = TextTrack;
 18225  module.exports = exports['default'];
 18226  
 18227  },{"../event-target":101,"../utils/browser.js":131,"../utils/fn.js":136,"../utils/guid.js":138,"../utils/log.js":139,"../utils/url.js":144,"./text-track-cue-list":124,"./text-track-enums":126,"global/document":1,"global/window":2,"xhr":56}],131:[function(_dereq_,module,exports){
 18228  /**
 18229   * @file browser.js
 18230   */
 18231  'use strict';
 18232  
 18233  exports.__esModule = true;
 18234  
 18235  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 18236  
 18237  var _globalDocument = _dereq_('global/document');
 18238  
 18239  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 18240  
 18241  var _globalWindow = _dereq_('global/window');
 18242  
 18243  var _globalWindow2 = _interopRequireDefault(_globalWindow);
 18244  
 18245  var USER_AGENT = _globalWindow2['default'].navigator.userAgent;
 18246  var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT);
 18247  var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null;
 18248  
 18249  /*
 18250   * Device is an iPhone
 18251   *
 18252   * @type {Boolean}
 18253   * @constant
 18254   * @private
 18255   */
 18256  var IS_IPAD = /iPad/i.test(USER_AGENT);
 18257  
 18258  exports.IS_IPAD = IS_IPAD;
 18259  // The Facebook app's UIWebView identifies as both an iPhone and iPad, so
 18260  // to identify iPhones, we need to exclude iPads.
 18261  // http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/
 18262  var IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD;
 18263  exports.IS_IPHONE = IS_IPHONE;
 18264  var IS_IPOD = /iPod/i.test(USER_AGENT);
 18265  exports.IS_IPOD = IS_IPOD;
 18266  var IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;
 18267  
 18268  exports.IS_IOS = IS_IOS;
 18269  var IOS_VERSION = (function () {
 18270    var match = USER_AGENT.match(/OS (\d+)_/i);
 18271    if (match && match[1]) {
 18272      return match[1];
 18273    }
 18274  })();
 18275  
 18276  exports.IOS_VERSION = IOS_VERSION;
 18277  var IS_ANDROID = /Android/i.test(USER_AGENT);
 18278  exports.IS_ANDROID = IS_ANDROID;
 18279  var ANDROID_VERSION = (function () {
 18280    // This matches Android Major.Minor.Patch versions
 18281    // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
 18282    var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i),
 18283        major,
 18284        minor;
 18285  
 18286    if (!match) {
 18287      return null;
 18288    }
 18289  
 18290    major = match[1] && parseFloat(match[1]);
 18291    minor = match[2] && parseFloat(match[2]);
 18292  
 18293    if (major && minor) {
 18294      return parseFloat(match[1] + '.' + match[2]);
 18295    } else if (major) {
 18296      return major;
 18297    } else {
 18298      return null;
 18299    }
 18300  })();
 18301  exports.ANDROID_VERSION = ANDROID_VERSION;
 18302  // Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser
 18303  var IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3;
 18304  exports.IS_OLD_ANDROID = IS_OLD_ANDROID;
 18305  var IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537;
 18306  
 18307  exports.IS_NATIVE_ANDROID = IS_NATIVE_ANDROID;
 18308  var IS_FIREFOX = /Firefox/i.test(USER_AGENT);
 18309  exports.IS_FIREFOX = IS_FIREFOX;
 18310  var IS_CHROME = /Chrome/i.test(USER_AGENT);
 18311  exports.IS_CHROME = IS_CHROME;
 18312  var IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT);
 18313  
 18314  exports.IS_IE8 = IS_IE8;
 18315  var TOUCH_ENABLED = !!('ontouchstart' in _globalWindow2['default'] || _globalWindow2['default'].DocumentTouch && _globalDocument2['default'] instanceof _globalWindow2['default'].DocumentTouch);
 18316  exports.TOUCH_ENABLED = TOUCH_ENABLED;
 18317  var BACKGROUND_SIZE_SUPPORTED = ('backgroundSize' in _globalDocument2['default'].createElement('video').style);
 18318  exports.BACKGROUND_SIZE_SUPPORTED = BACKGROUND_SIZE_SUPPORTED;
 18319  
 18320  },{"global/document":1,"global/window":2}],132:[function(_dereq_,module,exports){
 18321  /**
 18322   * @file buffer.js
 18323   */
 18324  'use strict';
 18325  
 18326  exports.__esModule = true;
 18327  exports.bufferedPercent = bufferedPercent;
 18328  
 18329  var _timeRangesJs = _dereq_('./time-ranges.js');
 18330  
 18331  /**
 18332   * Compute how much your video has been buffered
 18333   *
 18334   * @param  {Object} Buffered object
 18335   * @param  {Number} Total duration
 18336   * @return {Number} Percent buffered of the total duration
 18337   * @private
 18338   * @function bufferedPercent
 18339   */
 18340  
 18341  function bufferedPercent(buffered, duration) {
 18342    var bufferedDuration = 0,
 18343        start,
 18344        end;
 18345  
 18346    if (!duration) {
 18347      return 0;
 18348    }
 18349  
 18350    if (!buffered || !buffered.length) {
 18351      buffered = _timeRangesJs.createTimeRange(0, 0);
 18352    }
 18353  
 18354    for (var i = 0; i < buffered.length; i++) {
 18355      start = buffered.start(i);
 18356      end = buffered.end(i);
 18357  
 18358      // buffered end can be bigger than duration by a very small fraction
 18359      if (end > duration) {
 18360        end = duration;
 18361      }
 18362  
 18363      bufferedDuration += end - start;
 18364    }
 18365  
 18366    return bufferedDuration / duration;
 18367  }
 18368  
 18369  },{"./time-ranges.js":142}],133:[function(_dereq_,module,exports){
 18370  'use strict';
 18371  
 18372  exports.__esModule = true;
 18373  
 18374  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 18375  
 18376  var _logJs = _dereq_('./log.js');
 18377  
 18378  var _logJs2 = _interopRequireDefault(_logJs);
 18379  
 18380  /**
 18381   * Object containing the default behaviors for available handler methods.
 18382   *
 18383   * @private
 18384   * @type {Object}
 18385   */
 18386  var defaultBehaviors = {
 18387    get: function get(obj, key) {
 18388      return obj[key];
 18389    },
 18390    set: function set(obj, key, value) {
 18391      obj[key] = value;
 18392      return true;
 18393    }
 18394  };
 18395  
 18396  /**
 18397   * Expose private objects publicly using a Proxy to log deprecation warnings.
 18398   *
 18399   * Browsers that do not support Proxy objects will simply return the `target`
 18400   * object, so it can be directly exposed.
 18401   *
 18402   * @param {Object} target The target object.
 18403   * @param {Object} messages Messages to display from a Proxy. Only operations
 18404   *                          with an associated message will be proxied.
 18405   * @param {String} [messages.get]
 18406   * @param {String} [messages.set]
 18407   * @return {Object} A Proxy if supported or the `target` argument.
 18408   */
 18409  
 18410  exports['default'] = function (target) {
 18411    var messages = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
 18412  
 18413    if (typeof Proxy === 'function') {
 18414      var _ret = (function () {
 18415        var handler = {};
 18416  
 18417        // Build a handler object based on those keys that have both messages
 18418        // and default behaviors.
 18419        Object.keys(messages).forEach(function (key) {
 18420          if (defaultBehaviors.hasOwnProperty(key)) {
 18421            handler[key] = function () {
 18422              _logJs2['default'].warn(messages[key]);
 18423              return defaultBehaviors[key].apply(this, arguments);
 18424            };
 18425          }
 18426        });
 18427  
 18428        return {
 18429          v: new Proxy(target, handler)
 18430        };
 18431      })();
 18432  
 18433      if (typeof _ret === 'object') return _ret.v;
 18434    }
 18435    return target;
 18436  };
 18437  
 18438  module.exports = exports['default'];
 18439  
 18440  },{"./log.js":139}],134:[function(_dereq_,module,exports){
 18441  /**
 18442   * @file dom.js
 18443   */
 18444  'use strict';
 18445  
 18446  exports.__esModule = true;
 18447  exports.getEl = getEl;
 18448  exports.createEl = createEl;
 18449  exports.textContent = textContent;
 18450  exports.insertElFirst = insertElFirst;
 18451  exports.getElData = getElData;
 18452  exports.hasElData = hasElData;
 18453  exports.removeElData = removeElData;
 18454  exports.hasElClass = hasElClass;
 18455  exports.addElClass = addElClass;
 18456  exports.removeElClass = removeElClass;
 18457  exports.toggleElClass = toggleElClass;
 18458  exports.setElAttributes = setElAttributes;
 18459  exports.getElAttributes = getElAttributes;
 18460  exports.blockTextSelection = blockTextSelection;
 18461  exports.unblockTextSelection = unblockTextSelection;
 18462  exports.findElPosition = findElPosition;
 18463  exports.getPointerPosition = getPointerPosition;
 18464  exports.isEl = isEl;
 18465  exports.isTextNode = isTextNode;
 18466  exports.emptyEl = emptyEl;
 18467  exports.normalizeContent = normalizeContent;
 18468  exports.appendContent = appendContent;
 18469  exports.insertContent = insertContent;
 18470  
 18471  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 ', '.']);
 18472  
 18473  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 18474  
 18475  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 18476  
 18477  function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
 18478  
 18479  var _globalDocument = _dereq_('global/document');
 18480  
 18481  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 18482  
 18483  var _globalWindow = _dereq_('global/window');
 18484  
 18485  var _globalWindow2 = _interopRequireDefault(_globalWindow);
 18486  
 18487  var _guidJs = _dereq_('./guid.js');
 18488  
 18489  var Guid = _interopRequireWildcard(_guidJs);
 18490  
 18491  var _logJs = _dereq_('./log.js');
 18492  
 18493  var _logJs2 = _interopRequireDefault(_logJs);
 18494  
 18495  var _tsml = _dereq_('tsml');
 18496  
 18497  var _tsml2 = _interopRequireDefault(_tsml);
 18498  
 18499  /**
 18500   * Detect if a value is a string with any non-whitespace characters.
 18501   *
 18502   * @param  {String} str
 18503   * @return {Boolean}
 18504   */
 18505  function isNonBlankString(str) {
 18506    return typeof str === 'string' && /\S/.test(str);
 18507  }
 18508  
 18509  /**
 18510   * Throws an error if the passed string has whitespace. This is used by
 18511   * class methods to be relatively consistent with the classList API.
 18512   *
 18513   * @param  {String} str
 18514   * @return {Boolean}
 18515   */
 18516  function throwIfWhitespace(str) {
 18517    if (/\s/.test(str)) {
 18518      throw new Error('class has illegal whitespace characters');
 18519    }
 18520  }
 18521  
 18522  /**
 18523   * Produce a regular expression for matching a class name.
 18524   *
 18525   * @param  {String} className
 18526   * @return {RegExp}
 18527   */
 18528  function classRegExp(className) {
 18529    return new RegExp('(^|\\s)' + className + '($|\\s)');
 18530  }
 18531  
 18532  /**
 18533   * Creates functions to query the DOM using a given method.
 18534   *
 18535   * @function createQuerier
 18536   * @private
 18537   * @param  {String} method
 18538   * @return {Function}
 18539   */
 18540  function createQuerier(method) {
 18541    return function (selector, context) {
 18542      if (!isNonBlankString(selector)) {
 18543        return _globalDocument2['default'][method](null);
 18544      }
 18545      if (isNonBlankString(context)) {
 18546        context = _globalDocument2['default'].querySelector(context);
 18547      }
 18548      return (isEl(context) ? context : _globalDocument2['default'])[method](selector);
 18549    };
 18550  }
 18551  
 18552  /**
 18553   * Shorthand for document.getElementById()
 18554   * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs.
 18555   *
 18556   * @param  {String} id  Element ID
 18557   * @return {Element}    Element with supplied ID
 18558   * @function getEl
 18559   */
 18560  
 18561  function getEl(id) {
 18562    if (id.indexOf('#') === 0) {
 18563      id = id.slice(1);
 18564    }
 18565  
 18566    return _globalDocument2['default'].getElementById(id);
 18567  }
 18568  
 18569  /**
 18570   * Creates an element and applies properties.
 18571   *
 18572   * @param  {String} [tagName='div'] Name of tag to be created.
 18573   * @param  {Object} [properties={}] Element properties to be applied.
 18574   * @param  {Object} [attributes={}] Element attributes to be applied.
 18575   * @return {Element}
 18576   * @function createEl
 18577   */
 18578  
 18579  function createEl() {
 18580    var tagName = arguments.length <= 0 || arguments[0] === undefined ? 'div' : arguments[0];
 18581    var properties = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
 18582    var attributes = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
 18583  
 18584    var el = _globalDocument2['default'].createElement(tagName);
 18585  
 18586    Object.getOwnPropertyNames(properties).forEach(function (propName) {
 18587      var val = properties[propName];
 18588  
 18589      // See #2176
 18590      // We originally were accepting both properties and attributes in the
 18591      // same object, but that doesn't work so well.
 18592      if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') {
 18593        _logJs2['default'].warn(_tsml2['default'](_templateObject, propName, val));
 18594        el.setAttribute(propName, val);
 18595      } else {
 18596        el[propName] = val;
 18597      }
 18598    });
 18599  
 18600    Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
 18601      var val = attributes[attrName];
 18602      el.setAttribute(attrName, attributes[attrName]);
 18603    });
 18604  
 18605    return el;
 18606  }
 18607  
 18608  /**
 18609   * Injects text into an element, replacing any existing contents entirely.
 18610   *
 18611   * @param  {Element} el
 18612   * @param  {String} text
 18613   * @return {Element}
 18614   * @function textContent
 18615   */
 18616  
 18617  function textContent(el, text) {
 18618    if (typeof el.textContent === 'undefined') {
 18619      el.innerText = text;
 18620    } else {
 18621      el.textContent = text;
 18622    }
 18623  }
 18624  
 18625  /**
 18626   * Insert an element as the first child node of another
 18627   *
 18628   * @param  {Element} child   Element to insert
 18629   * @param  {Element} parent Element to insert child into
 18630   * @private
 18631   * @function insertElFirst
 18632   */
 18633  
 18634  function insertElFirst(child, parent) {
 18635    if (parent.firstChild) {
 18636      parent.insertBefore(child, parent.firstChild);
 18637    } else {
 18638      parent.appendChild(child);
 18639    }
 18640  }
 18641  
 18642  /**
 18643   * Element Data Store. Allows for binding data to an element without putting it directly on the element.
 18644   * Ex. Event listeners are stored here.
 18645   * (also from jsninja.com, slightly modified and updated for closure compiler)
 18646   *
 18647   * @type {Object}
 18648   * @private
 18649   */
 18650  var elData = {};
 18651  
 18652  /*
 18653   * Unique attribute name to store an element's guid in
 18654   *
 18655   * @type {String}
 18656   * @constant
 18657   * @private
 18658   */
 18659  var elIdAttr = 'vdata' + new Date().getTime();
 18660  
 18661  /**
 18662   * Returns the cache object where data for an element is stored
 18663   *
 18664   * @param  {Element} el Element to store data for.
 18665   * @return {Object}
 18666   * @function getElData
 18667   */
 18668  
 18669  function getElData(el) {
 18670    var id = el[elIdAttr];
 18671  
 18672    if (!id) {
 18673      id = el[elIdAttr] = Guid.newGUID();
 18674    }
 18675  
 18676    if (!elData[id]) {
 18677      elData[id] = {};
 18678    }
 18679  
 18680    return elData[id];
 18681  }
 18682  
 18683  /**
 18684   * Returns whether or not an element has cached data
 18685   *
 18686   * @param  {Element} el A dom element
 18687   * @return {Boolean}
 18688   * @private
 18689   * @function hasElData
 18690   */
 18691  
 18692  function hasElData(el) {
 18693    var id = el[elIdAttr];
 18694  
 18695    if (!id) {
 18696      return false;
 18697    }
 18698  
 18699    return !!Object.getOwnPropertyNames(elData[id]).length;
 18700  }
 18701  
 18702  /**
 18703   * Delete data for the element from the cache and the guid attr from getElementById
 18704   *
 18705   * @param  {Element} el Remove data for an element
 18706   * @private
 18707   * @function removeElData
 18708   */
 18709  
 18710  function removeElData(el) {
 18711    var id = el[elIdAttr];
 18712  
 18713    if (!id) {
 18714      return;
 18715    }
 18716  
 18717    // Remove all stored data
 18718    delete elData[id];
 18719  
 18720    // Remove the elIdAttr property from the DOM node
 18721    try {
 18722      delete el[elIdAttr];
 18723    } catch (e) {
 18724      if (el.removeAttribute) {
 18725        el.removeAttribute(elIdAttr);
 18726      } else {
 18727        // IE doesn't appear to support removeAttribute on the document element
 18728        el[elIdAttr] = null;
 18729      }
 18730    }
 18731  }
 18732  
 18733  /**
 18734   * Check if an element has a CSS class
 18735   *
 18736   * @function hasElClass
 18737   * @param {Element} element Element to check
 18738   * @param {String} classToCheck Classname to check
 18739   */
 18740  
 18741  function hasElClass(element, classToCheck) {
 18742    if (element.classList) {
 18743      return element.classList.contains(classToCheck);
 18744    } else {
 18745      throwIfWhitespace(classToCheck);
 18746      return classRegExp(classToCheck).test(element.className);
 18747    }
 18748  }
 18749  
 18750  /**
 18751   * Add a CSS class name to an element
 18752   *
 18753   * @function addElClass
 18754   * @param {Element} element    Element to add class name to
 18755   * @param {String} classToAdd Classname to add
 18756   */
 18757  
 18758  function addElClass(element, classToAdd) {
 18759    if (element.classList) {
 18760      element.classList.add(classToAdd);
 18761  
 18762      // Don't need to `throwIfWhitespace` here because `hasElClass` will do it
 18763      // in the case of classList not being supported.
 18764    } else if (!hasElClass(element, classToAdd)) {
 18765        element.className = (element.className + ' ' + classToAdd).trim();
 18766      }
 18767  
 18768    return element;
 18769  }
 18770  
 18771  /**
 18772   * Remove a CSS class name from an element
 18773   *
 18774   * @function removeElClass
 18775   * @param {Element} element    Element to remove from class name
 18776   * @param {String} classToRemove Classname to remove
 18777   */
 18778  
 18779  function removeElClass(element, classToRemove) {
 18780    if (element.classList) {
 18781      element.classList.remove(classToRemove);
 18782    } else {
 18783      throwIfWhitespace(classToRemove);
 18784      element.className = element.className.split(/\s+/).filter(function (c) {
 18785        return c !== classToRemove;
 18786      }).join(' ');
 18787    }
 18788  
 18789    return element;
 18790  }
 18791  
 18792  /**
 18793   * Adds or removes a CSS class name on an element depending on an optional
 18794   * condition or the presence/absence of the class name.
 18795   *
 18796   * @function toggleElClass
 18797   * @param    {Element} element
 18798   * @param    {String} classToToggle
 18799   * @param    {Boolean|Function} [predicate]
 18800   *           Can be a function that returns a Boolean. If `true`, the class
 18801   *           will be added; if `false`, the class will be removed. If not
 18802   *           given, the class will be added if not present and vice versa.
 18803   */
 18804  
 18805  function toggleElClass(element, classToToggle, predicate) {
 18806  
 18807    // This CANNOT use `classList` internally because IE does not support the
 18808    // second parameter to the `classList.toggle()` method! Which is fine because
 18809    // `classList` will be used by the add/remove functions.
 18810    var has = hasElClass(element, classToToggle);
 18811  
 18812    if (typeof predicate === 'function') {
 18813      predicate = predicate(element, classToToggle);
 18814    }
 18815  
 18816    if (typeof predicate !== 'boolean') {
 18817      predicate = !has;
 18818    }
 18819  
 18820    // If the necessary class operation matches the current state of the
 18821    // element, no action is required.
 18822    if (predicate === has) {
 18823      return;
 18824    }
 18825  
 18826    if (predicate) {
 18827      addElClass(element, classToToggle);
 18828    } else {
 18829      removeElClass(element, classToToggle);
 18830    }
 18831  
 18832    return element;
 18833  }
 18834  
 18835  /**
 18836   * Apply attributes to an HTML element.
 18837   *
 18838   * @param  {Element} el         Target element.
 18839   * @param  {Object=} attributes Element attributes to be applied.
 18840   * @private
 18841   * @function setElAttributes
 18842   */
 18843  
 18844  function setElAttributes(el, attributes) {
 18845    Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
 18846      var attrValue = attributes[attrName];
 18847  
 18848      if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
 18849        el.removeAttribute(attrName);
 18850      } else {
 18851        el.setAttribute(attrName, attrValue === true ? '' : attrValue);
 18852      }
 18853    });
 18854  }
 18855  
 18856  /**
 18857   * Get an element's attribute values, as defined on the HTML tag
 18858   * Attributes are not the same as properties. They're defined on the tag
 18859   * or with setAttribute (which shouldn't be used with HTML)
 18860   * This will return true or false for boolean attributes.
 18861   *
 18862   * @param  {Element} tag Element from which to get tag attributes
 18863   * @return {Object}
 18864   * @private
 18865   * @function getElAttributes
 18866   */
 18867  
 18868  function getElAttributes(tag) {
 18869    var obj, knownBooleans, attrs, attrName, attrVal;
 18870  
 18871    obj = {};
 18872  
 18873    // known boolean attributes
 18874    // we can check for matching boolean properties, but older browsers
 18875    // won't know about HTML5 boolean attributes that we still read from
 18876    knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ',';
 18877  
 18878    if (tag && tag.attributes && tag.attributes.length > 0) {
 18879      attrs = tag.attributes;
 18880  
 18881      for (var i = attrs.length - 1; i >= 0; i--) {
 18882        attrName = attrs[i].name;
 18883        attrVal = attrs[i].value;
 18884  
 18885        // check for known booleans
 18886        // the matching element property will return a value for typeof
 18887        if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {
 18888          // the value of an included boolean attribute is typically an empty
 18889          // string ('') which would equal false if we just check for a false value.
 18890          // we also don't want support bad code like autoplay='false'
 18891          attrVal = attrVal !== null ? true : false;
 18892        }
 18893  
 18894        obj[attrName] = attrVal;
 18895      }
 18896    }
 18897  
 18898    return obj;
 18899  }
 18900  
 18901  /**
 18902   * Attempt to block the ability to select text while dragging controls
 18903   *
 18904   * @return {Boolean}
 18905   * @function blockTextSelection
 18906   */
 18907  
 18908  function blockTextSelection() {
 18909    _globalDocument2['default'].body.focus();
 18910    _globalDocument2['default'].onselectstart = function () {
 18911      return false;
 18912    };
 18913  }
 18914  
 18915  /**
 18916   * Turn off text selection blocking
 18917   *
 18918   * @return {Boolean}
 18919   * @function unblockTextSelection
 18920   */
 18921  
 18922  function unblockTextSelection() {
 18923    _globalDocument2['default'].onselectstart = function () {
 18924      return true;
 18925    };
 18926  }
 18927  
 18928  /**
 18929   * Offset Left
 18930   * getBoundingClientRect technique from
 18931   * John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/
 18932   *
 18933   * @function findElPosition
 18934   * @param {Element} el Element from which to get offset
 18935   * @return {Object}
 18936   */
 18937  
 18938  function findElPosition(el) {
 18939    var box = undefined;
 18940  
 18941    if (el.getBoundingClientRect && el.parentNode) {
 18942      box = el.getBoundingClientRect();
 18943    }
 18944  
 18945    if (!box) {
 18946      return {
 18947        left: 0,
 18948        top: 0
 18949      };
 18950    }
 18951  
 18952    var docEl = _globalDocument2['default'].documentElement;
 18953    var body = _globalDocument2['default'].body;
 18954  
 18955    var clientLeft = docEl.clientLeft || body.clientLeft || 0;
 18956    var scrollLeft = _globalWindow2['default'].pageXOffset || body.scrollLeft;
 18957    var left = box.left + scrollLeft - clientLeft;
 18958  
 18959    var clientTop = docEl.clientTop || body.clientTop || 0;
 18960    var scrollTop = _globalWindow2['default'].pageYOffset || body.scrollTop;
 18961    var top = box.top + scrollTop - clientTop;
 18962  
 18963    // Android sometimes returns slightly off decimal values, so need to round
 18964    return {
 18965      left: Math.round(left),
 18966      top: Math.round(top)
 18967    };
 18968  }
 18969  
 18970  /**
 18971   * Get pointer position in element
 18972   * Returns an object with x and y coordinates.
 18973   * The base on the coordinates are the bottom left of the element.
 18974   *
 18975   * @function getPointerPosition
 18976   * @param {Element} el Element on which to get the pointer position on
 18977   * @param {Event} event Event object
 18978   * @return {Object} This object will have x and y coordinates corresponding to the mouse position
 18979   */
 18980  
 18981  function getPointerPosition(el, event) {
 18982    var position = {};
 18983    var box = findElPosition(el);
 18984    var boxW = el.offsetWidth;
 18985    var boxH = el.offsetHeight;
 18986  
 18987    var boxY = box.top;
 18988    var boxX = box.left;
 18989    var pageY = event.pageY;
 18990    var pageX = event.pageX;
 18991  
 18992    if (event.changedTouches) {
 18993      pageX = event.changedTouches[0].pageX;
 18994      pageY = event.changedTouches[0].pageY;
 18995    }
 18996  
 18997    position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH));
 18998    position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));
 18999  
 19000    return position;
 19001  }
 19002  
 19003  /**
 19004   * Determines, via duck typing, whether or not a value is a DOM element.
 19005   *
 19006   * @function isEl
 19007   * @param    {Mixed} value
 19008   * @return   {Boolean}
 19009   */
 19010  
 19011  function isEl(value) {
 19012    return !!value && typeof value === 'object' && value.nodeType === 1;
 19013  }
 19014  
 19015  /**
 19016   * Determines, via duck typing, whether or not a value is a text node.
 19017   *
 19018   * @param  {Mixed} value
 19019   * @return {Boolean}
 19020   */
 19021  
 19022  function isTextNode(value) {
 19023    return !!value && typeof value === 'object' && value.nodeType === 3;
 19024  }
 19025  
 19026  /**
 19027   * Empties the contents of an element.
 19028   *
 19029   * @function emptyEl
 19030   * @param    {Element} el
 19031   * @return   {Element}
 19032   */
 19033  
 19034  function emptyEl(el) {
 19035    while (el.firstChild) {
 19036      el.removeChild(el.firstChild);
 19037    }
 19038    return el;
 19039  }
 19040  
 19041  /**
 19042   * Normalizes content for eventual insertion into the DOM.
 19043   *
 19044   * This allows a wide range of content definition methods, but protects
 19045   * from falling into the trap of simply writing to `innerHTML`, which is
 19046   * an XSS concern.
 19047   *
 19048   * The content for an element can be passed in multiple types and
 19049   * combinations, whose behavior is as follows:
 19050   *
 19051   * - String
 19052   *   Normalized into a text node.
 19053   *
 19054   * - Element, TextNode
 19055   *   Passed through.
 19056   *
 19057   * - Array
 19058   *   A one-dimensional array of strings, elements, nodes, or functions (which
 19059   *   return single strings, elements, or nodes).
 19060   *
 19061   * - Function
 19062   *   If the sole argument, is expected to produce a string, element,
 19063   *   node, or array.
 19064   *
 19065   * @function normalizeContent
 19066   * @param    {String|Element|TextNode|Array|Function} content
 19067   * @return   {Array}
 19068   */
 19069  
 19070  function normalizeContent(content) {
 19071  
 19072    // First, invoke content if it is a function. If it produces an array,
 19073    // that needs to happen before normalization.
 19074    if (typeof content === 'function') {
 19075      content = content();
 19076    }
 19077  
 19078    // Next up, normalize to an array, so one or many items can be normalized,
 19079    // filtered, and returned.
 19080    return (Array.isArray(content) ? content : [content]).map(function (value) {
 19081  
 19082      // First, invoke value if it is a function to produce a new value,
 19083      // which will be subsequently normalized to a Node of some kind.
 19084      if (typeof value === 'function') {
 19085        value = value();
 19086      }
 19087  
 19088      if (isEl(value) || isTextNode(value)) {
 19089        return value;
 19090      }
 19091  
 19092      if (typeof value === 'string' && /\S/.test(value)) {
 19093        return _globalDocument2['default'].createTextNode(value);
 19094      }
 19095    }).filter(function (value) {
 19096      return value;
 19097    });
 19098  }
 19099  
 19100  /**
 19101   * Normalizes and appends content to an element.
 19102   *
 19103   * @function appendContent
 19104   * @param    {Element} el
 19105   * @param    {String|Element|TextNode|Array|Function} content
 19106   *           See: `normalizeContent`
 19107   * @return   {Element}
 19108   */
 19109  
 19110  function appendContent(el, content) {
 19111    normalizeContent(content).forEach(function (node) {
 19112      return el.appendChild(node);
 19113    });
 19114    return el;
 19115  }
 19116  
 19117  /**
 19118   * Normalizes and inserts content into an element; this is identical to
 19119   * `appendContent()`, except it empties the element first.
 19120   *
 19121   * @function insertContent
 19122   * @param    {Element} el
 19123   * @param    {String|Element|TextNode|Array|Function} content
 19124   *           See: `normalizeContent`
 19125   * @return   {Element}
 19126   */
 19127  
 19128  function insertContent(el, content) {
 19129    return appendContent(emptyEl(el), content);
 19130  }
 19131  
 19132  /**
 19133   * Finds a single DOM element matching `selector` within the optional
 19134   * `context` of another DOM element (defaulting to `document`).
 19135   *
 19136   * @function $
 19137   * @param    {String} selector
 19138   *           A valid CSS selector, which will be passed to `querySelector`.
 19139   *
 19140   * @param    {Element|String} [context=document]
 19141   *           A DOM element within which to query. Can also be a selector
 19142   *           string in which case the first matching element will be used
 19143   *           as context. If missing (or no element matches selector), falls
 19144   *           back to `document`.
 19145   *
 19146   * @return   {Element|null}
 19147   */
 19148  var $ = createQuerier('querySelector');
 19149  
 19150  exports.$ = $;
 19151  /**
 19152   * Finds a all DOM elements matching `selector` within the optional
 19153   * `context` of another DOM element (defaulting to `document`).
 19154   *
 19155   * @function $$
 19156   * @param    {String} selector
 19157   *           A valid CSS selector, which will be passed to `querySelectorAll`.
 19158   *
 19159   * @param    {Element|String} [context=document]
 19160   *           A DOM element within which to query. Can also be a selector
 19161   *           string in which case the first matching element will be used
 19162   *           as context. If missing (or no element matches selector), falls
 19163   *           back to `document`.
 19164   *
 19165   * @return   {NodeList}
 19166   */
 19167  var $$ = createQuerier('querySelectorAll');
 19168  exports.$$ = $$;
 19169  
 19170  },{"./guid.js":138,"./log.js":139,"global/document":1,"global/window":2,"tsml":55}],135:[function(_dereq_,module,exports){
 19171  /**
 19172   * @file events.js
 19173   *
 19174   * Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/)
 19175   * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible)
 19176   * This should work very similarly to jQuery's events, however it's based off the book version which isn't as
 19177   * robust as jquery's, so there's probably some differences.
 19178   */
 19179  
 19180  'use strict';
 19181  
 19182  exports.__esModule = true;
 19183  exports.on = on;
 19184  exports.off = off;
 19185  exports.trigger = trigger;
 19186  exports.one = one;
 19187  exports.fixEvent = fixEvent;
 19188  
 19189  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 19190  
 19191  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 19192  
 19193  var _domJs = _dereq_('./dom.js');
 19194  
 19195  var Dom = _interopRequireWildcard(_domJs);
 19196  
 19197  var _guidJs = _dereq_('./guid.js');
 19198  
 19199  var Guid = _interopRequireWildcard(_guidJs);
 19200  
 19201  var _globalWindow = _dereq_('global/window');
 19202  
 19203  var _globalWindow2 = _interopRequireDefault(_globalWindow);
 19204  
 19205  var _globalDocument = _dereq_('global/document');
 19206  
 19207  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 19208  
 19209  /**
 19210   * Add an event listener to element
 19211   * It stores the handler function in a separate cache object
 19212   * and adds a generic handler to the element's event,
 19213   * along with a unique id (guid) to the element.
 19214   *
 19215   * @param  {Element|Object}   elem Element or object to bind listeners to
 19216   * @param  {String|Array}   type Type of event to bind to.
 19217   * @param  {Function} fn   Event listener.
 19218   * @method on
 19219   */
 19220  
 19221  function on(elem, type, fn) {
 19222    if (Array.isArray(type)) {
 19223      return _handleMultipleEvents(on, elem, type, fn);
 19224    }
 19225  
 19226    var data = Dom.getElData(elem);
 19227  
 19228    // We need a place to store all our handler data
 19229    if (!data.handlers) data.handlers = {};
 19230  
 19231    if (!data.handlers[type]) data.handlers[type] = [];
 19232  
 19233    if (!fn.guid) fn.guid = Guid.newGUID();
 19234  
 19235    data.handlers[type].push(fn);
 19236  
 19237    if (!data.dispatcher) {
 19238      data.disabled = false;
 19239  
 19240      data.dispatcher = function (event, hash) {
 19241  
 19242        if (data.disabled) return;
 19243        event = fixEvent(event);
 19244  
 19245        var handlers = data.handlers[event.type];
 19246  
 19247        if (handlers) {
 19248          // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.
 19249          var handlersCopy = handlers.slice(0);
 19250  
 19251          for (var m = 0, n = handlersCopy.length; m < n; m++) {
 19252            if (event.isImmediatePropagationStopped()) {
 19253              break;
 19254            } else {
 19255              handlersCopy[m].call(elem, event, hash);
 19256            }
 19257          }
 19258        }
 19259      };
 19260    }
 19261  
 19262    if (data.handlers[type].length === 1) {
 19263      if (elem.addEventListener) {
 19264        elem.addEventListener(type, data.dispatcher, false);
 19265      } else if (elem.attachEvent) {
 19266        elem.attachEvent('on' + type, data.dispatcher);
 19267      }
 19268    }
 19269  }
 19270  
 19271  /**
 19272   * Removes event listeners from an element
 19273   *
 19274   * @param  {Element|Object}   elem Object to remove listeners from
 19275   * @param  {String|Array=}   type Type of listener to remove. Don't include to remove all events from element.
 19276   * @param  {Function} fn   Specific listener to remove. Don't include to remove listeners for an event type.
 19277   * @method off
 19278   */
 19279  
 19280  function off(elem, type, fn) {
 19281    // Don't want to add a cache object through getElData if not needed
 19282    if (!Dom.hasElData(elem)) return;
 19283  
 19284    var data = Dom.getElData(elem);
 19285  
 19286    // If no events exist, nothing to unbind
 19287    if (!data.handlers) {
 19288      return;
 19289    }
 19290  
 19291    if (Array.isArray(type)) {
 19292      return _handleMultipleEvents(off, elem, type, fn);
 19293    }
 19294  
 19295    // Utility function
 19296    var removeType = function removeType(t) {
 19297      data.handlers[t] = [];
 19298      _cleanUpEvents(elem, t);
 19299    };
 19300  
 19301    // Are we removing all bound events?
 19302    if (!type) {
 19303      for (var t in data.handlers) {
 19304        removeType(t);
 19305      }return;
 19306    }
 19307  
 19308    var handlers = data.handlers[type];
 19309  
 19310    // If no handlers exist, nothing to unbind
 19311    if (!handlers) return;
 19312  
 19313    // If no listener was provided, remove all listeners for type
 19314    if (!fn) {
 19315      removeType(type);
 19316      return;
 19317    }
 19318  
 19319    // We're only removing a single handler
 19320    if (fn.guid) {
 19321      for (var n = 0; n < handlers.length; n++) {
 19322        if (handlers[n].guid === fn.guid) {
 19323          handlers.splice(n--, 1);
 19324        }
 19325      }
 19326    }
 19327  
 19328    _cleanUpEvents(elem, type);
 19329  }
 19330  
 19331  /**
 19332   * Trigger an event for an element
 19333   *
 19334   * @param  {Element|Object}      elem  Element to trigger an event on
 19335   * @param  {Event|Object|String} event A string (the type) or an event object with a type attribute
 19336   * @param  {Object} [hash] data hash to pass along with the event
 19337   * @return {Boolean=} Returned only if default was prevented
 19338   * @method trigger
 19339   */
 19340  
 19341  function trigger(elem, event, hash) {
 19342    // Fetches element data and a reference to the parent (for bubbling).
 19343    // Don't want to add a data object to cache for every parent,
 19344    // so checking hasElData first.
 19345    var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {};
 19346    var parent = elem.parentNode || elem.ownerDocument;
 19347    // type = event.type || event,
 19348    // handler;
 19349  
 19350    // If an event name was passed as a string, creates an event out of it
 19351    if (typeof event === 'string') {
 19352      event = { type: event, target: elem };
 19353    }
 19354    // Normalizes the event properties.
 19355    event = fixEvent(event);
 19356  
 19357    // If the passed element has a dispatcher, executes the established handlers.
 19358    if (elemData.dispatcher) {
 19359      elemData.dispatcher.call(elem, event, hash);
 19360    }
 19361  
 19362    // Unless explicitly stopped or the event does not bubble (e.g. media events)
 19363    // recursively calls this function to bubble the event up the DOM.
 19364    if (parent && !event.isPropagationStopped() && event.bubbles === true) {
 19365      trigger.call(null, parent, event, hash);
 19366  
 19367      // If at the top of the DOM, triggers the default action unless disabled.
 19368    } else if (!parent && !event.defaultPrevented) {
 19369        var targetData = Dom.getElData(event.target);
 19370  
 19371        // Checks if the target has a default action for this event.
 19372        if (event.target[event.type]) {
 19373          // Temporarily disables event dispatching on the target as we have already executed the handler.
 19374          targetData.disabled = true;
 19375          // Executes the default action.
 19376          if (typeof event.target[event.type] === 'function') {
 19377            event.target[event.type]();
 19378          }
 19379          // Re-enables event dispatching.
 19380          targetData.disabled = false;
 19381        }
 19382      }
 19383  
 19384    // Inform the triggerer if the default was prevented by returning false
 19385    return !event.defaultPrevented;
 19386  }
 19387  
 19388  /**
 19389   * Trigger a listener only once for an event
 19390   *
 19391   * @param  {Element|Object}   elem Element or object to
 19392   * @param  {String|Array}   type Name/type of event
 19393   * @param  {Function} fn Event handler function
 19394   * @method one
 19395   */
 19396  
 19397  function one(elem, type, fn) {
 19398    if (Array.isArray(type)) {
 19399      return _handleMultipleEvents(one, elem, type, fn);
 19400    }
 19401    var func = function func() {
 19402      off(elem, type, func);
 19403      fn.apply(this, arguments);
 19404    };
 19405    // copy the guid to the new function so it can removed using the original function's ID
 19406    func.guid = fn.guid = fn.guid || Guid.newGUID();
 19407    on(elem, type, func);
 19408  }
 19409  
 19410  /**
 19411   * Fix a native event to have standard property values
 19412   *
 19413   * @param  {Object} event Event object to fix
 19414   * @return {Object}
 19415   * @private
 19416   * @method fixEvent
 19417   */
 19418  
 19419  function fixEvent(event) {
 19420  
 19421    function returnTrue() {
 19422      return true;
 19423    }
 19424    function returnFalse() {
 19425      return false;
 19426    }
 19427  
 19428    // Test if fixing up is needed
 19429    // Used to check if !event.stopPropagation instead of isPropagationStopped
 19430    // But native events return true for stopPropagation, but don't have
 19431    // other expected methods like isPropagationStopped. Seems to be a problem
 19432    // with the Javascript Ninja code. So we're just overriding all events now.
 19433    if (!event || !event.isPropagationStopped) {
 19434      var old = event || _globalWindow2['default'].event;
 19435  
 19436      event = {};
 19437      // Clone the old object so that we can modify the values event = {};
 19438      // IE8 Doesn't like when you mess with native event properties
 19439      // Firefox returns false for event.hasOwnProperty('type') and other props
 19440      //  which makes copying more difficult.
 19441      // TODO: Probably best to create a whitelist of event props
 19442      for (var key in old) {
 19443        // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
 19444        // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation
 19445        // and webkitMovementX/Y
 19446        if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') {
 19447          // Chrome 32+ warns if you try to copy deprecated returnValue, but
 19448          // we still want to if preventDefault isn't supported (IE8).
 19449          if (!(key === 'returnValue' && old.preventDefault)) {
 19450            event[key] = old[key];
 19451          }
 19452        }
 19453      }
 19454  
 19455      // The event occurred on this element
 19456      if (!event.target) {
 19457        event.target = event.srcElement || _globalDocument2['default'];
 19458      }
 19459  
 19460      // Handle which other element the event is related to
 19461      if (!event.relatedTarget) {
 19462        event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
 19463      }
 19464  
 19465      // Stop the default browser action
 19466      event.preventDefault = function () {
 19467        if (old.preventDefault) {
 19468          old.preventDefault();
 19469        }
 19470        event.returnValue = false;
 19471        old.returnValue = false;
 19472        event.defaultPrevented = true;
 19473      };
 19474  
 19475      event.defaultPrevented = false;
 19476  
 19477      // Stop the event from bubbling
 19478      event.stopPropagation = function () {
 19479        if (old.stopPropagation) {
 19480          old.stopPropagation();
 19481        }
 19482        event.cancelBubble = true;
 19483        old.cancelBubble = true;
 19484        event.isPropagationStopped = returnTrue;
 19485      };
 19486  
 19487      event.isPropagationStopped = returnFalse;
 19488  
 19489      // Stop the event from bubbling and executing other handlers
 19490      event.stopImmediatePropagation = function () {
 19491        if (old.stopImmediatePropagation) {
 19492          old.stopImmediatePropagation();
 19493        }
 19494        event.isImmediatePropagationStopped = returnTrue;
 19495        event.stopPropagation();
 19496      };
 19497  
 19498      event.isImmediatePropagationStopped = returnFalse;
 19499  
 19500      // Handle mouse position
 19501      if (event.clientX != null) {
 19502        var doc = _globalDocument2['default'].documentElement,
 19503            body = _globalDocument2['default'].body;
 19504  
 19505        event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
 19506        event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
 19507      }
 19508  
 19509      // Handle key presses
 19510      event.which = event.charCode || event.keyCode;
 19511  
 19512      // Fix button for mouse clicks:
 19513      // 0 == left; 1 == middle; 2 == right
 19514      if (event.button != null) {
 19515        event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0;
 19516      }
 19517    }
 19518  
 19519    // Returns fixed-up instance
 19520    return event;
 19521  }
 19522  
 19523  /**
 19524   * Clean up the listener cache and dispatchers
 19525  *
 19526   * @param  {Element|Object} elem Element to clean up
 19527   * @param  {String} type Type of event to clean up
 19528   * @private
 19529   * @method _cleanUpEvents
 19530   */
 19531  function _cleanUpEvents(elem, type) {
 19532    var data = Dom.getElData(elem);
 19533  
 19534    // Remove the events of a particular type if there are none left
 19535    if (data.handlers[type].length === 0) {
 19536      delete data.handlers[type];
 19537      // data.handlers[type] = null;
 19538      // Setting to null was causing an error with data.handlers
 19539  
 19540      // Remove the meta-handler from the element
 19541      if (elem.removeEventListener) {
 19542        elem.removeEventListener(type, data.dispatcher, false);
 19543      } else if (elem.detachEvent) {
 19544        elem.detachEvent('on' + type, data.dispatcher);
 19545      }
 19546    }
 19547  
 19548    // Remove the events object if there are no types left
 19549    if (Object.getOwnPropertyNames(data.handlers).length <= 0) {
 19550      delete data.handlers;
 19551      delete data.dispatcher;
 19552      delete data.disabled;
 19553    }
 19554  
 19555    // Finally remove the element data if there is no data left
 19556    if (Object.getOwnPropertyNames(data).length === 0) {
 19557      Dom.removeElData(elem);
 19558    }
 19559  }
 19560  
 19561  /**
 19562   * Loops through an array of event types and calls the requested method for each type.
 19563   *
 19564   * @param  {Function} fn   The event method we want to use.
 19565   * @param  {Element|Object} elem Element or object to bind listeners to
 19566   * @param  {String}   type Type of event to bind to.
 19567   * @param  {Function} callback   Event listener.
 19568   * @private
 19569   * @function _handleMultipleEvents
 19570   */
 19571  function _handleMultipleEvents(fn, elem, types, callback) {
 19572    types.forEach(function (type) {
 19573      //Call the event method for each one of the types
 19574      fn(elem, type, callback);
 19575    });
 19576  }
 19577  
 19578  },{"./dom.js":134,"./guid.js":138,"global/document":1,"global/window":2}],136:[function(_dereq_,module,exports){
 19579  /**
 19580   * @file fn.js
 19581   */
 19582  'use strict';
 19583  
 19584  exports.__esModule = true;
 19585  
 19586  var _guidJs = _dereq_('./guid.js');
 19587  
 19588  /**
 19589   * Bind (a.k.a proxy or Context). A simple method for changing the context of a function
 19590   * It also stores a unique id on the function so it can be easily removed from events
 19591   *
 19592   * @param  {*}   context The object to bind as scope
 19593   * @param  {Function} fn      The function to be bound to a scope
 19594   * @param  {Number=}   uid     An optional unique ID for the function to be set
 19595   * @return {Function}
 19596   * @private
 19597   * @method bind
 19598   */
 19599  var bind = function bind(context, fn, uid) {
 19600    // Make sure the function has a unique ID
 19601    if (!fn.guid) {
 19602      fn.guid = _guidJs.newGUID();
 19603    }
 19604  
 19605    // Create the new function that changes the context
 19606    var ret = function ret() {
 19607      return fn.apply(context, arguments);
 19608    };
 19609  
 19610    // Allow for the ability to individualize this function
 19611    // Needed in the case where multiple objects might share the same prototype
 19612    // IF both items add an event listener with the same function, then you try to remove just one
 19613    // it will remove both because they both have the same guid.
 19614    // when using this, you need to use the bind method when you remove the listener as well.
 19615    // currently used in text tracks
 19616    ret.guid = uid ? uid + '_' + fn.guid : fn.guid;
 19617  
 19618    return ret;
 19619  };
 19620  exports.bind = bind;
 19621  
 19622  },{"./guid.js":138}],137:[function(_dereq_,module,exports){
 19623  /**
 19624   * @file format-time.js
 19625   *
 19626   * Format seconds as a time string, H:MM:SS or M:SS
 19627   * Supplying a guide (in seconds) will force a number of leading zeros
 19628   * to cover the length of the guide
 19629   *
 19630   * @param  {Number} seconds Number of seconds to be turned into a string
 19631   * @param  {Number} guide   Number (in seconds) to model the string after
 19632   * @return {String}         Time formatted as H:MM:SS or M:SS
 19633   * @private
 19634   * @function formatTime
 19635   */
 19636  'use strict';
 19637  
 19638  exports.__esModule = true;
 19639  function formatTime(seconds) {
 19640    var guide = arguments.length <= 1 || arguments[1] === undefined ? seconds : arguments[1];
 19641    return (function () {
 19642      seconds = seconds < 0 ? 0 : seconds;
 19643      var s = Math.floor(seconds % 60);
 19644      var m = Math.floor(seconds / 60 % 60);
 19645      var h = Math.floor(seconds / 3600);
 19646      var gm = Math.floor(guide / 60 % 60);
 19647      var gh = Math.floor(guide / 3600);
 19648  
 19649      // handle invalid times
 19650      if (isNaN(seconds) || seconds === Infinity) {
 19651        // '-' is false for all relational operators (e.g. <, >=) so this setting
 19652        // will add the minimum number of fields specified by the guide
 19653        h = m = s = '-';
 19654      }
 19655  
 19656      // Check if we need to show hours
 19657      h = h > 0 || gh > 0 ? h + ':' : '';
 19658  
 19659      // If hours are showing, we may need to add a leading zero.
 19660      // Always show at least one digit of minutes.
 19661      m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':';
 19662  
 19663      // Check if leading zero is need for seconds
 19664      s = s < 10 ? '0' + s : s;
 19665  
 19666      return h + m + s;
 19667    })();
 19668  }
 19669  
 19670  exports['default'] = formatTime;
 19671  module.exports = exports['default'];
 19672  
 19673  },{}],138:[function(_dereq_,module,exports){
 19674  /**
 19675   * @file guid.js
 19676   *
 19677   * Unique ID for an element or function
 19678   * @type {Number}
 19679   * @private
 19680   */
 19681  "use strict";
 19682  
 19683  exports.__esModule = true;
 19684  exports.newGUID = newGUID;
 19685  var _guid = 1;
 19686  
 19687  /**
 19688   * Get the next unique ID
 19689   *
 19690   * @return {String} 
 19691   * @function newGUID
 19692   */
 19693  
 19694  function newGUID() {
 19695    return _guid++;
 19696  }
 19697  
 19698  },{}],139:[function(_dereq_,module,exports){
 19699  /**
 19700   * @file log.js
 19701   */
 19702  'use strict';
 19703  
 19704  exports.__esModule = true;
 19705  
 19706  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 19707  
 19708  var _globalWindow = _dereq_('global/window');
 19709  
 19710  var _globalWindow2 = _interopRequireDefault(_globalWindow);
 19711  
 19712  /**
 19713   * Log plain debug messages
 19714   */
 19715  var log = function log() {
 19716    _logType(null, arguments);
 19717  };
 19718  
 19719  /**
 19720   * Keep a history of log messages
 19721   * @type {Array}
 19722   */
 19723  log.history = [];
 19724  
 19725  /**
 19726   * Log error messages
 19727   */
 19728  log.error = function () {
 19729    _logType('error', arguments);
 19730  };
 19731  
 19732  /**
 19733   * Log warning messages
 19734   */
 19735  log.warn = function () {
 19736    _logType('warn', arguments);
 19737  };
 19738  
 19739  /**
 19740   * Log messages to the console and history based on the type of message
 19741   *
 19742   * @param  {String} type The type of message, or `null` for `log`
 19743   * @param  {Object} args The args to be passed to the log
 19744   * @private
 19745   * @method _logType
 19746   */
 19747  function _logType(type, args) {
 19748    // convert args to an array to get array functions
 19749    var argsArray = Array.prototype.slice.call(args);
 19750    // if there's no console then don't try to output messages
 19751    // they will still be stored in log.history
 19752    // Was setting these once outside of this function, but containing them
 19753    // in the function makes it easier to test cases where console doesn't exist
 19754    var noop = function noop() {};
 19755  
 19756    var console = _globalWindow2['default']['console'] || {
 19757      'log': noop,
 19758      'warn': noop,
 19759      'error': noop
 19760    };
 19761  
 19762    if (type) {
 19763      // add the type to the front of the message
 19764      argsArray.unshift(type.toUpperCase() + ':');
 19765    } else {
 19766      // default to log with no prefix
 19767      type = 'log';
 19768    }
 19769  
 19770    // add to history
 19771    log.history.push(argsArray);
 19772  
 19773    // add console prefix after adding to history
 19774    argsArray.unshift('VIDEOJS:');
 19775  
 19776    // call appropriate log function
 19777    if (console[type].apply) {
 19778      console[type].apply(console, argsArray);
 19779    } else {
 19780      // ie8 doesn't allow error.apply, but it will just join() the array anyway
 19781      console[type](argsArray.join(' '));
 19782    }
 19783  }
 19784  
 19785  exports['default'] = log;
 19786  module.exports = exports['default'];
 19787  
 19788  },{"global/window":2}],140:[function(_dereq_,module,exports){
 19789  /**
 19790   * @file merge-options.js
 19791   */
 19792  'use strict';
 19793  
 19794  exports.__esModule = true;
 19795  exports['default'] = mergeOptions;
 19796  
 19797  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 19798  
 19799  var _lodashCompatObjectMerge = _dereq_('lodash-compat/object/merge');
 19800  
 19801  var _lodashCompatObjectMerge2 = _interopRequireDefault(_lodashCompatObjectMerge);
 19802  
 19803  function isPlain(obj) {
 19804    return !!obj && typeof obj === 'object' && obj.toString() === '[object Object]' && obj.constructor === Object;
 19805  }
 19806  
 19807  /**
 19808   * Merge customizer. video.js simply overwrites non-simple objects
 19809   * (like arrays) instead of attempting to overlay them.
 19810   * @see https://lodash.com/docs#merge
 19811   */
 19812  var customizer = function customizer(destination, source) {
 19813    // If we're not working with a plain object, copy the value as is
 19814    // If source is an array, for instance, it will replace destination
 19815    if (!isPlain(source)) {
 19816      return source;
 19817    }
 19818  
 19819    // If the new value is a plain object but the first object value is not
 19820    // we need to create a new object for the first object to merge with.
 19821    // This makes it consistent with how merge() works by default
 19822    // and also protects from later changes the to first object affecting
 19823    // the second object's values.
 19824    if (!isPlain(destination)) {
 19825      return mergeOptions(source);
 19826    }
 19827  };
 19828  
 19829  /**
 19830   * Merge one or more options objects, recursively merging **only**
 19831   * plain object properties.  Previously `deepMerge`.
 19832   *
 19833   * @param  {...Object} source One or more objects to merge
 19834   * @returns {Object}          a new object that is the union of all
 19835   * provided objects
 19836   * @function mergeOptions
 19837   */
 19838  
 19839  function mergeOptions() {
 19840    // contruct the call dynamically to handle the variable number of
 19841    // objects to merge
 19842    var args = Array.prototype.slice.call(arguments);
 19843  
 19844    // unshift an empty object into the front of the call as the target
 19845    // of the merge
 19846    args.unshift({});
 19847  
 19848    // customize conflict resolution to match our historical merge behavior
 19849    args.push(customizer);
 19850  
 19851    _lodashCompatObjectMerge2['default'].apply(null, args);
 19852  
 19853    // return the mutated result object
 19854    return args[0];
 19855  }
 19856  
 19857  module.exports = exports['default'];
 19858  
 19859  },{"lodash-compat/object/merge":40}],141:[function(_dereq_,module,exports){
 19860  'use strict';
 19861  
 19862  exports.__esModule = true;
 19863  
 19864  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 19865  
 19866  var _globalDocument = _dereq_('global/document');
 19867  
 19868  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 19869  
 19870  var createStyleElement = function createStyleElement(className) {
 19871    var style = _globalDocument2['default'].createElement('style');
 19872    style.className = className;
 19873  
 19874    return style;
 19875  };
 19876  
 19877  exports.createStyleElement = createStyleElement;
 19878  var setTextContent = function setTextContent(el, content) {
 19879    if (el.styleSheet) {
 19880      el.styleSheet.cssText = content;
 19881    } else {
 19882      el.textContent = content;
 19883    }
 19884  };
 19885  exports.setTextContent = setTextContent;
 19886  
 19887  },{"global/document":1}],142:[function(_dereq_,module,exports){
 19888  'use strict';
 19889  
 19890  exports.__esModule = true;
 19891  exports.createTimeRanges = createTimeRanges;
 19892  
 19893  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 19894  
 19895  var _logJs = _dereq_('./log.js');
 19896  
 19897  var _logJs2 = _interopRequireDefault(_logJs);
 19898  
 19899  /**
 19900   * @file time-ranges.js
 19901   *
 19902   * Should create a fake TimeRange object
 19903   * Mimics an HTML5 time range instance, which has functions that
 19904   * return the start and end times for a range
 19905   * TimeRanges are returned by the buffered() method
 19906   *
 19907   * @param  {(Number|Array)} Start of a single range or an array of ranges
 19908   * @param  {Number} End of a single range
 19909   * @private
 19910   * @method createTimeRanges
 19911   */
 19912  
 19913  function createTimeRanges(start, end) {
 19914    if (Array.isArray(start)) {
 19915      return createTimeRangesObj(start);
 19916    } else if (start === undefined || end === undefined) {
 19917      return createTimeRangesObj();
 19918    }
 19919    return createTimeRangesObj([[start, end]]);
 19920  }
 19921  
 19922  exports.createTimeRange = createTimeRanges;
 19923  
 19924  function createTimeRangesObj(ranges) {
 19925    if (ranges === undefined || ranges.length === 0) {
 19926      return {
 19927        length: 0,
 19928        start: function start() {
 19929          throw new Error('This TimeRanges object is empty');
 19930        },
 19931        end: function end() {
 19932          throw new Error('This TimeRanges object is empty');
 19933        }
 19934      };
 19935    }
 19936    return {
 19937      length: ranges.length,
 19938      start: getRange.bind(null, 'start', 0, ranges),
 19939      end: getRange.bind(null, 'end', 1, ranges)
 19940    };
 19941  }
 19942  
 19943  function getRange(fnName, valueIndex, ranges, rangeIndex) {
 19944    if (rangeIndex === undefined) {
 19945      _logJs2['default'].warn('DEPRECATED: Function \'' + fnName + '\' on \'TimeRanges\' called without an index argument.');
 19946      rangeIndex = 0;
 19947    }
 19948    rangeCheck(fnName, rangeIndex, ranges.length - 1);
 19949    return ranges[rangeIndex][valueIndex];
 19950  }
 19951  
 19952  function rangeCheck(fnName, index, maxIndex) {
 19953    if (index < 0 || index > maxIndex) {
 19954      throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is greater than or equal to the maximum bound (' + maxIndex + ').');
 19955    }
 19956  }
 19957  
 19958  },{"./log.js":139}],143:[function(_dereq_,module,exports){
 19959  /**
 19960   * @file to-title-case.js
 19961   *
 19962   * Uppercase the first letter of a string
 19963   *
 19964   * @param  {String} string String to be uppercased
 19965   * @return {String}
 19966   * @private
 19967   * @method toTitleCase
 19968   */
 19969  "use strict";
 19970  
 19971  exports.__esModule = true;
 19972  function toTitleCase(string) {
 19973    return string.charAt(0).toUpperCase() + string.slice(1);
 19974  }
 19975  
 19976  exports["default"] = toTitleCase;
 19977  module.exports = exports["default"];
 19978  
 19979  },{}],144:[function(_dereq_,module,exports){
 19980  /**
 19981   * @file url.js
 19982   */
 19983  'use strict';
 19984  
 19985  exports.__esModule = true;
 19986  
 19987  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 19988  
 19989  var _globalDocument = _dereq_('global/document');
 19990  
 19991  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 19992  
 19993  var _globalWindow = _dereq_('global/window');
 19994  
 19995  var _globalWindow2 = _interopRequireDefault(_globalWindow);
 19996  
 19997  /**
 19998   * Resolve and parse the elements of a URL
 19999   *
 20000   * @param  {String} url The url to parse
 20001   * @return {Object}     An object of url details
 20002   * @method parseUrl
 20003   */
 20004  var parseUrl = function parseUrl(url) {
 20005    var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host'];
 20006  
 20007    // add the url to an anchor and let the browser parse the URL
 20008    var a = _globalDocument2['default'].createElement('a');
 20009    a.href = url;
 20010  
 20011    // IE8 (and 9?) Fix
 20012    // ie8 doesn't parse the URL correctly until the anchor is actually
 20013    // added to the body, and an innerHTML is needed to trigger the parsing
 20014    var addToBody = a.host === '' && a.protocol !== 'file:';
 20015    var div = undefined;
 20016    if (addToBody) {
 20017      div = _globalDocument2['default'].createElement('div');
 20018      div.innerHTML = '<a href="' + url + '"></a>';
 20019      a = div.firstChild;
 20020      // prevent the div from affecting layout
 20021      div.setAttribute('style', 'display:none; position:absolute;');
 20022      _globalDocument2['default'].body.appendChild(div);
 20023    }
 20024  
 20025    // Copy the specific URL properties to a new object
 20026    // This is also needed for IE8 because the anchor loses its
 20027    // properties when it's removed from the dom
 20028    var details = {};
 20029    for (var i = 0; i < props.length; i++) {
 20030      details[props[i]] = a[props[i]];
 20031    }
 20032  
 20033    // IE9 adds the port to the host property unlike everyone else. If
 20034    // a port identifier is added for standard ports, strip it.
 20035    if (details.protocol === 'http:') {
 20036      details.host = details.host.replace(/:80$/, '');
 20037    }
 20038    if (details.protocol === 'https:') {
 20039      details.host = details.host.replace(/:443$/, '');
 20040    }
 20041  
 20042    if (addToBody) {
 20043      _globalDocument2['default'].body.removeChild(div);
 20044    }
 20045  
 20046    return details;
 20047  };
 20048  
 20049  exports.parseUrl = parseUrl;
 20050  /**
 20051   * Get absolute version of relative URL. Used to tell flash correct URL.
 20052   * http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
 20053   *
 20054   * @param  {String} url URL to make absolute
 20055   * @return {String}     Absolute URL
 20056   * @private
 20057   * @method getAbsoluteURL
 20058   */
 20059  var getAbsoluteURL = function getAbsoluteURL(url) {
 20060    // Check if absolute URL
 20061    if (!url.match(/^https?:\/\//)) {
 20062      // Convert to absolute URL. Flash hosted off-site needs an absolute URL.
 20063      var div = _globalDocument2['default'].createElement('div');
 20064      div.innerHTML = '<a href="' + url + '">x</a>';
 20065      url = div.firstChild.href;
 20066    }
 20067  
 20068    return url;
 20069  };
 20070  
 20071  exports.getAbsoluteURL = getAbsoluteURL;
 20072  /**
 20073   * Returns the extension of the passed file name. It will return an empty string if you pass an invalid path
 20074   *
 20075   * @param {String}    path    The fileName path like '/path/to/file.mp4'
 20076   * @returns {String}          The extension in lower case or an empty string if no extension could be found.
 20077   * @method getFileExtension
 20078   */
 20079  var getFileExtension = function getFileExtension(path) {
 20080    if (typeof path === 'string') {
 20081      var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i;
 20082      var pathParts = splitPathRe.exec(path);
 20083  
 20084      if (pathParts) {
 20085        return pathParts.pop().toLowerCase();
 20086      }
 20087    }
 20088  
 20089    return '';
 20090  };
 20091  
 20092  exports.getFileExtension = getFileExtension;
 20093  /**
 20094   * Returns whether the url passed is a cross domain request or not.
 20095   *
 20096   * @param {String} url The url to check
 20097   * @return {Boolean}   Whether it is a cross domain request or not
 20098   * @method isCrossOrigin
 20099   */
 20100  var isCrossOrigin = function isCrossOrigin(url) {
 20101    var winLoc = _globalWindow2['default'].location;
 20102    var urlInfo = parseUrl(url);
 20103  
 20104    // IE8 protocol relative urls will return ':' for protocol
 20105    var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol;
 20106  
 20107    // Check if url is for another domain/origin
 20108    // IE8 doesn't know location.origin, so we won't rely on it here
 20109    var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host;
 20110  
 20111    return crossOrigin;
 20112  };
 20113  exports.isCrossOrigin = isCrossOrigin;
 20114  
 20115  },{"global/document":1,"global/window":2}],145:[function(_dereq_,module,exports){
 20116  /**
 20117   * @file video.js
 20118   */
 20119  'use strict';
 20120  
 20121  exports.__esModule = true;
 20122  
 20123  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
 20124  
 20125  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
 20126  
 20127  var _globalWindow = _dereq_('global/window');
 20128  
 20129  var _globalWindow2 = _interopRequireDefault(_globalWindow);
 20130  
 20131  var _globalDocument = _dereq_('global/document');
 20132  
 20133  var _globalDocument2 = _interopRequireDefault(_globalDocument);
 20134  
 20135  var _setup = _dereq_('./setup');
 20136  
 20137  var setup = _interopRequireWildcard(_setup);
 20138  
 20139  var _utilsStylesheetJs = _dereq_('./utils/stylesheet.js');
 20140  
 20141  var stylesheet = _interopRequireWildcard(_utilsStylesheetJs);
 20142  
 20143  var _component = _dereq_('./component');
 20144  
 20145  var _component2 = _interopRequireDefault(_component);
 20146  
 20147  var _eventTarget = _dereq_('./event-target');
 20148  
 20149  var _eventTarget2 = _interopRequireDefault(_eventTarget);
 20150  
 20151  var _utilsEventsJs = _dereq_('./utils/events.js');
 20152  
 20153  var Events = _interopRequireWildcard(_utilsEventsJs);
 20154  
 20155  var _player = _dereq_('./player');
 20156  
 20157  var _player2 = _interopRequireDefault(_player);
 20158  
 20159  var _pluginsJs = _dereq_('./plugins.js');
 20160  
 20161  var _pluginsJs2 = _interopRequireDefault(_pluginsJs);
 20162  
 20163  var _srcJsUtilsMergeOptionsJs = _dereq_('../../src/js/utils/merge-options.js');
 20164  
 20165  var _srcJsUtilsMergeOptionsJs2 = _interopRequireDefault(_srcJsUtilsMergeOptionsJs);
 20166  
 20167  var _utilsFnJs = _dereq_('./utils/fn.js');
 20168  
 20169  var Fn = _interopRequireWildcard(_utilsFnJs);
 20170  
 20171  var _tracksTextTrackJs = _dereq_('./tracks/text-track.js');
 20172  
 20173  var _tracksTextTrackJs2 = _interopRequireDefault(_tracksTextTrackJs);
 20174  
 20175  var _objectAssign = _dereq_('object.assign');
 20176  
 20177  var _objectAssign2 = _interopRequireDefault(_objectAssign);
 20178  
 20179  var _utilsTimeRangesJs = _dereq_('./utils/time-ranges.js');
 20180  
 20181  var _utilsFormatTimeJs = _dereq_('./utils/format-time.js');
 20182  
 20183  var _utilsFormatTimeJs2 = _interopRequireDefault(_utilsFormatTimeJs);
 20184  
 20185  var _utilsLogJs = _dereq_('./utils/log.js');
 20186  
 20187  var _utilsLogJs2 = _interopRequireDefault(_utilsLogJs);
 20188  
 20189  var _utilsDomJs = _dereq_('./utils/dom.js');
 20190  
 20191  var Dom = _interopRequireWildcard(_utilsDomJs);
 20192  
 20193  var _utilsBrowserJs = _dereq_('./utils/browser.js');
 20194  
 20195  var browser = _interopRequireWildcard(_utilsBrowserJs);
 20196  
 20197  var _utilsUrlJs = _dereq_('./utils/url.js');
 20198  
 20199  var Url = _interopRequireWildcard(_utilsUrlJs);
 20200  
 20201  var _extendJs = _dereq_('./extend.js');
 20202  
 20203  var _extendJs2 = _interopRequireDefault(_extendJs);
 20204  
 20205  var _lodashCompatObjectMerge = _dereq_('lodash-compat/object/merge');
 20206  
 20207  var _lodashCompatObjectMerge2 = _interopRequireDefault(_lodashCompatObjectMerge);
 20208  
 20209  var _utilsCreateDeprecationProxyJs = _dereq_('./utils/create-deprecation-proxy.js');
 20210  
 20211  var _utilsCreateDeprecationProxyJs2 = _interopRequireDefault(_utilsCreateDeprecationProxyJs);
 20212  
 20213  var _xhr = _dereq_('xhr');
 20214  
 20215  var _xhr2 = _interopRequireDefault(_xhr);
 20216  
 20217  // Include the built-in techs
 20218  
 20219  var _techTechJs = _dereq_('./tech/tech.js');
 20220  
 20221  var _techTechJs2 = _interopRequireDefault(_techTechJs);
 20222  
 20223  var _techHtml5Js = _dereq_('./tech/html5.js');
 20224  
 20225  var _techHtml5Js2 = _interopRequireDefault(_techHtml5Js);
 20226  
 20227  var _techFlashJs = _dereq_('./tech/flash.js');
 20228  
 20229  var _techFlashJs2 = _interopRequireDefault(_techFlashJs);
 20230  
 20231  // HTML5 Element Shim for IE8
 20232  if (typeof HTMLVideoElement === 'undefined') {
 20233    _globalDocument2['default'].createElement('video');
 20234    _globalDocument2['default'].createElement('audio');
 20235    _globalDocument2['default'].createElement('track');
 20236  }
 20237  
 20238  /**
 20239   * Doubles as the main function for users to create a player instance and also
 20240   * the main library object.
 20241   * The `videojs` function can be used to initialize or retrieve a player.
 20242   * ```js
 20243   *     var myPlayer = videojs('my_video_id');
 20244   * ```
 20245   *
 20246   * @param  {String|Element} id      Video element or video element ID
 20247   * @param  {Object=} options        Optional options object for config/settings
 20248   * @param  {Function=} ready        Optional ready callback
 20249   * @return {Player}                 A player instance
 20250   * @mixes videojs
 20251   * @method videojs
 20252   */
 20253  var videojs = function videojs(id, options, ready) {
 20254    var tag = undefined; // Element of ID
 20255  
 20256    // Allow for element or ID to be passed in
 20257    // String ID
 20258    if (typeof id === 'string') {
 20259  
 20260      // Adjust for jQuery ID syntax
 20261      if (id.indexOf('#') === 0) {
 20262        id = id.slice(1);
 20263      }
 20264  
 20265      // If a player instance has already been created for this ID return it.
 20266      if (videojs.getPlayers()[id]) {
 20267  
 20268        // If options or ready funtion are passed, warn
 20269        if (options) {
 20270          _utilsLogJs2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.');
 20271        }
 20272  
 20273        if (ready) {
 20274          videojs.getPlayers()[id].ready(ready);
 20275        }
 20276  
 20277        return videojs.getPlayers()[id];
 20278  
 20279        // Otherwise get element for ID
 20280      } else {
 20281          tag = Dom.getEl(id);
 20282        }
 20283  
 20284      // ID is a media element
 20285    } else {
 20286        tag = id;
 20287      }
 20288  
 20289    // Check for a useable element
 20290    if (!tag || !tag.nodeName) {
 20291      // re: nodeName, could be a box div also
 20292      throw new TypeError('The element or ID supplied is not valid. (videojs)'); // Returns
 20293    }
 20294  
 20295    // Element may have a player attr referring to an already created player instance.
 20296    // If not, set up a new player and return the instance.
 20297    return tag['player'] || _player2['default'].players[tag.playerId] || new _player2['default'](tag, options, ready);
 20298  };
 20299  
 20300  // Add default styles
 20301  if (_globalWindow2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) {
 20302    var style = Dom.$('.vjs-styles-defaults');
 20303  
 20304    if (!style) {
 20305      style = stylesheet.createStyleElement('vjs-styles-defaults');
 20306      var head = Dom.$('head');
 20307      head.insertBefore(style, head.firstChild);
 20308      stylesheet.setTextContent(style, '\n      .video-js {\n        width: 300px;\n        height: 150px;\n      }\n\n      .vjs-fluid {\n        padding-top: 56.25%\n      }\n    ');
 20309    }
 20310  }
 20311  
 20312  // Run Auto-load players
 20313  // 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)
 20314  setup.autoSetupTimeout(1, videojs);
 20315  
 20316  /*
 20317   * Current software version (semver)
 20318   *
 20319   * @type {String}
 20320   */
 20321  videojs.VERSION = '5.9.0';
 20322  
 20323  /**
 20324   * The global options object. These are the settings that take effect
 20325   * if no overrides are specified when the player is created.
 20326   *
 20327   * ```js
 20328   *     videojs.options.autoplay = true
 20329   *     // -> all players will autoplay by default
 20330   * ```
 20331   *
 20332   * @type {Object}
 20333   */
 20334  videojs.options = _player2['default'].prototype.options_;
 20335  
 20336  /**
 20337   * Get an object with the currently created players, keyed by player ID
 20338   *
 20339   * @return {Object} The created players
 20340   * @mixes videojs
 20341   * @method getPlayers
 20342   */
 20343  videojs.getPlayers = function () {
 20344    return _player2['default'].players;
 20345  };
 20346  
 20347  /**
 20348   * For backward compatibility, expose players object.
 20349   *
 20350   * @deprecated
 20351   * @memberOf videojs
 20352   * @property {Object|Proxy} players
 20353   */
 20354  videojs.players = _utilsCreateDeprecationProxyJs2['default'](_player2['default'].players, {
 20355    get: 'Access to videojs.players is deprecated; use videojs.getPlayers instead',
 20356    set: 'Modification of videojs.players is deprecated'
 20357  });
 20358  
 20359  /**
 20360   * Get a component class object by name
 20361   * ```js
 20362   *     var VjsButton = videojs.getComponent('Button');
 20363   *     // Create a new instance of the component
 20364   *     var myButton = new VjsButton(myPlayer);
 20365   * ```
 20366   *
 20367   * @return {Component} Component identified by name
 20368   * @mixes videojs
 20369   * @method getComponent
 20370   */
 20371  videojs.getComponent = _component2['default'].getComponent;
 20372  
 20373  /**
 20374   * Register a component so it can referred to by name
 20375   * Used when adding to other
 20376   * components, either through addChild
 20377   * `component.addChild('myComponent')`
 20378   * or through default children options
 20379   * `{ children: ['myComponent'] }`.
 20380   * ```js
 20381   *     // Get a component to subclass
 20382   *     var VjsButton = videojs.getComponent('Button');
 20383   *     // Subclass the component (see 'extend' doc for more info)
 20384   *     var MySpecialButton = videojs.extend(VjsButton, {});
 20385   *     // Register the new component
 20386   *     VjsButton.registerComponent('MySepcialButton', MySepcialButton);
 20387   *     // (optionally) add the new component as a default player child
 20388   *     myPlayer.addChild('MySepcialButton');
 20389   * ```
 20390   * NOTE: You could also just initialize the component before adding.
 20391   * `component.addChild(new MyComponent());`
 20392   *
 20393   * @param {String} The class name of the component
 20394   * @param {Component} The component class
 20395   * @return {Component} The newly registered component
 20396   * @mixes videojs
 20397   * @method registerComponent
 20398   */
 20399  videojs.registerComponent = function (name, comp) {
 20400    if (_techTechJs2['default'].isTech(comp)) {
 20401      _utilsLogJs2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)');
 20402    }
 20403  
 20404    _component2['default'].registerComponent.call(_component2['default'], name, comp);
 20405  };
 20406  
 20407  /**
 20408   * Get a Tech class object by name
 20409   * ```js
 20410   *     var Html5 = videojs.getTech('Html5');
 20411   *     // Create a new instance of the component
 20412   *     var html5 = new Html5(options);
 20413   * ```
 20414   *
 20415   * @return {Tech} Tech identified by name
 20416   * @mixes videojs
 20417   * @method getComponent
 20418   */
 20419  videojs.getTech = _techTechJs2['default'].getTech;
 20420  
 20421  /**
 20422   * Register a Tech so it can referred to by name.
 20423   * This is used in the tech order for the player.
 20424   *
 20425   * ```js
 20426   *     // get the Html5 Tech
 20427   *     var Html5 = videojs.getTech('Html5');
 20428   *     var MyTech = videojs.extend(Html5, {});
 20429   *     // Register the new Tech
 20430   *     VjsButton.registerTech('Tech', MyTech);
 20431   *     var player = videojs('myplayer', {
 20432   *       techOrder: ['myTech', 'html5']
 20433   *     });
 20434   * ```
 20435   *
 20436   * @param {String} The class name of the tech
 20437   * @param {Tech} The tech class
 20438   * @return {Tech} The newly registered Tech
 20439   * @mixes videojs
 20440   * @method registerTech
 20441   */
 20442  videojs.registerTech = _techTechJs2['default'].registerTech;
 20443  
 20444  /**
 20445   * A suite of browser and device tests
 20446   *
 20447   * @type {Object}
 20448   * @private
 20449   */
 20450  videojs.browser = browser;
 20451  
 20452  /**
 20453   * Whether or not the browser supports touch events. Included for backward
 20454   * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED`
 20455   * instead going forward.
 20456   *
 20457   * @deprecated
 20458   * @type {Boolean}
 20459   */
 20460  videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED;
 20461  
 20462  /**
 20463   * Subclass an existing class
 20464   * Mimics ES6 subclassing with the `extend` keyword
 20465   * ```js
 20466   *     // Create a basic javascript 'class'
 20467   *     function MyClass(name){
 20468   *       // Set a property at initialization
 20469   *       this.myName = name;
 20470   *     }
 20471   *     // Create an instance method
 20472   *     MyClass.prototype.sayMyName = function(){
 20473   *       alert(this.myName);
 20474   *     };
 20475   *     // Subclass the exisitng class and change the name
 20476   *     // when initializing
 20477   *     var MySubClass = videojs.extend(MyClass, {
 20478   *       constructor: function(name) {
 20479   *         // Call the super class constructor for the subclass
 20480   *         MyClass.call(this, name)
 20481   *       }
 20482   *     });
 20483   *     // Create an instance of the new sub class
 20484   *     var myInstance = new MySubClass('John');
 20485   *     myInstance.sayMyName(); // -> should alert "John"
 20486   * ```
 20487   *
 20488   * @param {Function} The Class to subclass
 20489   * @param {Object} An object including instace methods for the new class
 20490   *                   Optionally including a `constructor` function
 20491   * @return {Function} The newly created subclass
 20492   * @mixes videojs
 20493   * @method extend
 20494   */
 20495  videojs.extend = _extendJs2['default'];
 20496  
 20497  /**
 20498   * Merge two options objects recursively
 20499   * Performs a deep merge like lodash.merge but **only merges plain objects**
 20500   * (not arrays, elements, anything else)
 20501   * Other values will be copied directly from the second object.
 20502   * ```js
 20503   *     var defaultOptions = {
 20504   *       foo: true,
 20505   *       bar: {
 20506   *         a: true,
 20507   *         b: [1,2,3]
 20508   *       }
 20509   *     };
 20510   *     var newOptions = {
 20511   *       foo: false,
 20512   *       bar: {
 20513   *         b: [4,5,6]
 20514   *       }
 20515   *     };
 20516   *     var result = videojs.mergeOptions(defaultOptions, newOptions);
 20517   *     // result.foo = false;
 20518   *     // result.bar.a = true;
 20519   *     // result.bar.b = [4,5,6];
 20520   * ```
 20521   *
 20522   * @param {Object} defaults  The options object whose values will be overriden
 20523   * @param {Object} overrides The options object with values to override the first
 20524   * @param {Object} etc       Any number of additional options objects
 20525   *
 20526   * @return {Object} a new object with the merged values
 20527   * @mixes videojs
 20528   * @method mergeOptions
 20529   */
 20530  videojs.mergeOptions = _srcJsUtilsMergeOptionsJs2['default'];
 20531  
 20532  /**
 20533   * Change the context (this) of a function
 20534   *
 20535   *     videojs.bind(newContext, function(){
 20536   *       this === newContext
 20537   *     });
 20538   *
 20539   * NOTE: as of v5.0 we require an ES5 shim, so you should use the native
 20540   * `function(){}.bind(newContext);` instead of this.
 20541   *
 20542   * @param  {*}        context The object to bind as scope
 20543   * @param  {Function} fn      The function to be bound to a scope
 20544   * @param  {Number=}  uid     An optional unique ID for the function to be set
 20545   * @return {Function}
 20546   */
 20547  videojs.bind = Fn.bind;
 20548  
 20549  /**
 20550   * Create a Video.js player plugin
 20551   * Plugins are only initialized when options for the plugin are included
 20552   * in the player options, or the plugin function on the player instance is
 20553   * called.
 20554   * **See the plugin guide in the docs for a more detailed example**
 20555   * ```js
 20556   *     // Make a plugin that alerts when the player plays
 20557   *     videojs.plugin('myPlugin', function(myPluginOptions) {
 20558   *       myPluginOptions = myPluginOptions || {};
 20559   *
 20560   *       var player = this;
 20561   *       var alertText = myPluginOptions.text || 'Player is playing!'
 20562   *
 20563   *       player.on('play', function(){
 20564   *         alert(alertText);
 20565   *       });
 20566   *     });
 20567   *     // USAGE EXAMPLES
 20568   *     // EXAMPLE 1: New player with plugin options, call plugin immediately
 20569   *     var player1 = videojs('idOne', {
 20570   *       myPlugin: {
 20571   *         text: 'Custom text!'
 20572   *       }
 20573   *     });
 20574   *     // Click play
 20575   *     // --> Should alert 'Custom text!'
 20576   *     // EXAMPLE 3: New player, initialize plugin later
 20577   *     var player3 = videojs('idThree');
 20578   *     // Click play
 20579   *     // --> NO ALERT
 20580   *     // Click pause
 20581   *     // Initialize plugin using the plugin function on the player instance
 20582   *     player3.myPlugin({
 20583   *       text: 'Plugin added later!'
 20584   *     });
 20585   *     // Click play
 20586   *     // --> Should alert 'Plugin added later!'
 20587   * ```
 20588   *
 20589   * @param {String} name The plugin name
 20590   * @param {Function} fn The plugin function that will be called with options
 20591   * @mixes videojs
 20592   * @method plugin
 20593   */
 20594  videojs.plugin = _pluginsJs2['default'];
 20595  
 20596  /**
 20597   * Adding languages so that they're available to all players.
 20598   * ```js
 20599   *     videojs.addLanguage('es', { 'Hello': 'Hola' });
 20600   * ```
 20601   *
 20602   * @param  {String} code The language code or dictionary property
 20603   * @param  {Object} data The data values to be translated
 20604   * @return {Object} The resulting language dictionary object
 20605   * @mixes videojs
 20606   * @method addLanguage
 20607   */
 20608  videojs.addLanguage = function (code, data) {
 20609    var _merge;
 20610  
 20611    code = ('' + code).toLowerCase();
 20612    return _lodashCompatObjectMerge2['default'](videojs.options.languages, (_merge = {}, _merge[code] = data, _merge))[code];
 20613  };
 20614  
 20615  /**
 20616   * Log debug messages.
 20617   *
 20618   * @param {...Object} messages One or more messages to log
 20619   */
 20620  videojs.log = _utilsLogJs2['default'];
 20621  
 20622  /**
 20623   * Creates an emulated TimeRange object.
 20624   *
 20625   * @param  {Number|Array} start Start time in seconds or an array of ranges
 20626   * @param  {Number} end   End time in seconds
 20627   * @return {Object}       Fake TimeRange object
 20628   * @method createTimeRange
 20629   */
 20630  videojs.createTimeRange = videojs.createTimeRanges = _utilsTimeRangesJs.createTimeRanges;
 20631  
 20632  /**
 20633   * Format seconds as a time string, H:MM:SS or M:SS
 20634   * Supplying a guide (in seconds) will force a number of leading zeros
 20635   * to cover the length of the guide
 20636   *
 20637   * @param  {Number} seconds Number of seconds to be turned into a string
 20638   * @param  {Number} guide   Number (in seconds) to model the string after
 20639   * @return {String}         Time formatted as H:MM:SS or M:SS
 20640   * @method formatTime
 20641   */
 20642  videojs.formatTime = _utilsFormatTimeJs2['default'];
 20643  
 20644  /**
 20645   * Resolve and parse the elements of a URL
 20646   *
 20647   * @param  {String} url The url to parse
 20648   * @return {Object}     An object of url details
 20649   * @method parseUrl
 20650   */
 20651  videojs.parseUrl = Url.parseUrl;
 20652  
 20653  /**
 20654   * Returns whether the url passed is a cross domain request or not.
 20655   *
 20656   * @param {String} url The url to check
 20657   * @return {Boolean}   Whether it is a cross domain request or not
 20658   * @method isCrossOrigin
 20659   */
 20660  videojs.isCrossOrigin = Url.isCrossOrigin;
 20661  
 20662  /**
 20663   * Event target class.
 20664   *
 20665   * @type {Function}
 20666   */
 20667  videojs.EventTarget = _eventTarget2['default'];
 20668  
 20669  /**
 20670   * Add an event listener to element
 20671   * It stores the handler function in a separate cache object
 20672   * and adds a generic handler to the element's event,
 20673   * along with a unique id (guid) to the element.
 20674   *
 20675   * @param  {Element|Object}   elem Element or object to bind listeners to
 20676   * @param  {String|Array}   type Type of event to bind to.
 20677   * @param  {Function} fn   Event listener.
 20678   * @method on
 20679   */
 20680  videojs.on = Events.on;
 20681  
 20682  /**
 20683   * Trigger a listener only once for an event
 20684   *
 20685   * @param  {Element|Object}   elem Element or object to
 20686   * @param  {String|Array}   type Name/type of event
 20687   * @param  {Function} fn Event handler function
 20688   * @method one
 20689   */
 20690  videojs.one = Events.one;
 20691  
 20692  /**
 20693   * Removes event listeners from an element
 20694   *
 20695   * @param  {Element|Object}   elem Object to remove listeners from
 20696   * @param  {String|Array=}   type Type of listener to remove. Don't include to remove all events from element.
 20697   * @param  {Function} fn   Specific listener to remove. Don't include to remove listeners for an event type.
 20698   * @method off
 20699   */
 20700  videojs.off = Events.off;
 20701  
 20702  /**
 20703   * Trigger an event for an element
 20704   *
 20705   * @param  {Element|Object}      elem  Element to trigger an event on
 20706   * @param  {Event|Object|String} event A string (the type) or an event object with a type attribute
 20707   * @param  {Object} [hash] data hash to pass along with the event
 20708   * @return {Boolean=} Returned only if default was prevented
 20709   * @method trigger
 20710   */
 20711  videojs.trigger = Events.trigger;
 20712  
 20713  /**
 20714   * A cross-browser XMLHttpRequest wrapper. Here's a simple example:
 20715   *
 20716   *     videojs.xhr({
 20717   *       body: someJSONString,
 20718   *       uri: "/foo",
 20719   *       headers: {
 20720   *         "Content-Type": "application/json"
 20721   *       }
 20722   *     }, function (err, resp, body) {
 20723   *       // check resp.statusCode
 20724   *     });
 20725   *
 20726   * Check out the [full
 20727   * documentation](https://github.com/Raynos/xhr/blob/v2.1.0/README.md)
 20728   * for more options.
 20729   *
 20730   * @param {Object} options settings for the request.
 20731   * @return {XMLHttpRequest|XDomainRequest} the request object.
 20732   * @see https://github.com/Raynos/xhr
 20733   */
 20734  videojs.xhr = _xhr2['default'];
 20735  
 20736  /**
 20737   * TextTrack class
 20738   *
 20739   * @type {Function}
 20740   */
 20741  videojs.TextTrack = _tracksTextTrackJs2['default'];
 20742  
 20743  /**
 20744   * Determines, via duck typing, whether or not a value is a DOM element.
 20745   *
 20746   * @method isEl
 20747   * @param  {Mixed} value
 20748   * @return {Boolean}
 20749   */
 20750  videojs.isEl = Dom.isEl;
 20751  
 20752  /**
 20753   * Determines, via duck typing, whether or not a value is a text node.
 20754   *
 20755   * @method isTextNode
 20756   * @param  {Mixed} value
 20757   * @return {Boolean}
 20758   */
 20759  videojs.isTextNode = Dom.isTextNode;
 20760  
 20761  /**
 20762   * Creates an element and applies properties.
 20763   *
 20764   * @method createEl
 20765   * @param  {String} [tagName='div'] Name of tag to be created.
 20766   * @param  {Object} [properties={}] Element properties to be applied.
 20767   * @param  {Object} [attributes={}] Element attributes to be applied.
 20768   * @return {Element}
 20769   */
 20770  videojs.createEl = Dom.createEl;
 20771  
 20772  /**
 20773   * Check if an element has a CSS class
 20774   *
 20775   * @method hasClass
 20776   * @param {Element} element Element to check
 20777   * @param {String} classToCheck Classname to check
 20778   */
 20779  videojs.hasClass = Dom.hasElClass;
 20780  
 20781  /**
 20782   * Add a CSS class name to an element
 20783   *
 20784   * @method addClass
 20785   * @param {Element} element    Element to add class name to
 20786   * @param {String} classToAdd Classname to add
 20787   */
 20788  videojs.addClass = Dom.addElClass;
 20789  
 20790  /**
 20791   * Remove a CSS class name from an element
 20792   *
 20793   * @method removeClass
 20794   * @param {Element} element    Element to remove from class name
 20795   * @param {String} classToRemove Classname to remove
 20796   */
 20797  videojs.removeClass = Dom.removeElClass;
 20798  
 20799  /**
 20800   * Adds or removes a CSS class name on an element depending on an optional
 20801   * condition or the presence/absence of the class name.
 20802   *
 20803   * @method toggleElClass
 20804   * @param  {Element} element
 20805   * @param  {String} classToToggle
 20806   * @param  {Boolean|Function} [predicate]
 20807   *         Can be a function that returns a Boolean. If `true`, the class
 20808   *         will be added; if `false`, the class will be removed. If not
 20809   *         given, the class will be added if not present and vice versa.
 20810   */
 20811  videojs.toggleClass = Dom.toggleElClass;
 20812  
 20813  /**
 20814   * Apply attributes to an HTML element.
 20815   *
 20816   * @method setAttributes
 20817   * @param  {Element} el         Target element.
 20818   * @param  {Object=} attributes Element attributes to be applied.
 20819   */
 20820  videojs.setAttributes = Dom.setElAttributes;
 20821  
 20822  /**
 20823   * Get an element's attribute values, as defined on the HTML tag
 20824   * Attributes are not the same as properties. They're defined on the tag
 20825   * or with setAttribute (which shouldn't be used with HTML)
 20826   * This will return true or false for boolean attributes.
 20827   *
 20828   * @method getAttributes
 20829   * @param  {Element} tag Element from which to get tag attributes
 20830   * @return {Object}
 20831   */
 20832  videojs.getAttributes = Dom.getElAttributes;
 20833  
 20834  /**
 20835   * Empties the contents of an element.
 20836   *
 20837   * @method emptyEl
 20838   * @param  {Element} el
 20839   * @return {Element}
 20840   */
 20841  videojs.emptyEl = Dom.emptyEl;
 20842  
 20843  /**
 20844   * Normalizes and appends content to an element.
 20845   *
 20846   * The content for an element can be passed in multiple types and
 20847   * combinations, whose behavior is as follows:
 20848   *
 20849   * - String
 20850   *   Normalized into a text node.
 20851   *
 20852   * - Element, TextNode
 20853   *   Passed through.
 20854   *
 20855   * - Array
 20856   *   A one-dimensional array of strings, elements, nodes, or functions (which
 20857   *   return single strings, elements, or nodes).
 20858   *
 20859   * - Function
 20860   *   If the sole argument, is expected to produce a string, element,
 20861   *   node, or array.
 20862   *
 20863   * @method appendContent
 20864   * @param  {Element} el
 20865   * @param  {String|Element|TextNode|Array|Function} content
 20866   * @return {Element}
 20867   */
 20868  videojs.appendContent = Dom.appendContent;
 20869  
 20870  /**
 20871   * Normalizes and inserts content into an element; this is identical to
 20872   * `appendContent()`, except it empties the element first.
 20873   *
 20874   * The content for an element can be passed in multiple types and
 20875   * combinations, whose behavior is as follows:
 20876   *
 20877   * - String
 20878   *   Normalized into a text node.
 20879   *
 20880   * - Element, TextNode
 20881   *   Passed through.
 20882   *
 20883   * - Array
 20884   *   A one-dimensional array of strings, elements, nodes, or functions (which
 20885   *   return single strings, elements, or nodes).
 20886   *
 20887   * - Function
 20888   *   If the sole argument, is expected to produce a string, element,
 20889   *   node, or array.
 20890   *
 20891   * @method insertContent
 20892   * @param  {Element} el
 20893   * @param  {String|Element|TextNode|Array|Function} content
 20894   * @return {Element}
 20895   */
 20896  videojs.insertContent = Dom.insertContent;
 20897  
 20898  /*
 20899   * Custom Universal Module Definition (UMD)
 20900   *
 20901   * Video.js will never be a non-browser lib so we can simplify UMD a bunch and
 20902   * still support requirejs and browserify. This also needs to be closure
 20903   * compiler compatible, so string keys are used.
 20904   */
 20905  if (typeof define === 'function' && define['amd']) {
 20906    define('videojs', [], function () {
 20907      return videojs;
 20908    });
 20909  
 20910    // checking that module is an object too because of umdjs/umd#35
 20911  } else if (typeof exports === 'object' && typeof module === 'object') {
 20912      module['exports'] = videojs;
 20913    }
 20914  
 20915  exports['default'] = videojs;
 20916  module.exports = exports['default'];
 20917  
 20918  },{"../../src/js/utils/merge-options.js":140,"./component":67,"./event-target":101,"./extend.js":102,"./player":110,"./plugins.js":111,"./setup":115,"./tech/flash.js":118,"./tech/html5.js":119,"./tech/tech.js":121,"./tracks/text-track.js":130,"./utils/browser.js":131,"./utils/create-deprecation-proxy.js":133,"./utils/dom.js":134,"./utils/events.js":135,"./utils/fn.js":136,"./utils/format-time.js":137,"./utils/log.js":139,"./utils/stylesheet.js":141,"./utils/time-ranges.js":142,"./utils/url.js":144,"global/document":1,"global/window":2,"lodash-compat/object/merge":40,"object.assign":45,"xhr":56}]},{},[145])(145)
 20919  });
 20920  
 20921  
 20922  //# sourceMappingURL=video.js.map
 20923  /* vtt.js - v0.12.1 (https://github.com/mozilla/vtt.js) built on 08-07-2015 */
 20924  
 20925  (function(root) {
 20926    var vttjs = root.vttjs = {};
 20927    var cueShim = vttjs.VTTCue;
 20928    var regionShim = vttjs.VTTRegion;
 20929    var oldVTTCue = root.VTTCue;
 20930    var oldVTTRegion = root.VTTRegion;
 20931  
 20932    vttjs.shim = function() {
 20933      vttjs.VTTCue = cueShim;
 20934      vttjs.VTTRegion = regionShim;
 20935    };
 20936  
 20937    vttjs.restore = function() {
 20938      vttjs.VTTCue = oldVTTCue;
 20939      vttjs.VTTRegion = oldVTTRegion;
 20940    };
 20941  }(this));
 20942  
 20943  /**
 20944   * Copyright 2013 vtt.js Contributors
 20945   *
 20946   * Licensed under the Apache License, Version 2.0 (the "License");
 20947   * you may not use this file except in compliance with the License.
 20948   * You may obtain a copy of the License at
 20949   *
 20950   *   http://www.apache.org/licenses/LICENSE-2.0
 20951   *
 20952   * Unless required by applicable law or agreed to in writing, software
 20953   * distributed under the License is distributed on an "AS IS" BASIS,
 20954   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 20955   * See the License for the specific language governing permissions and
 20956   * limitations under the License.
 20957   */
 20958  
 20959  (function(root, vttjs) {
 20960  
 20961    var autoKeyword = "auto";
 20962    var directionSetting = {
 20963      "": true,
 20964      "lr": true,
 20965      "rl": true
 20966    };
 20967    var alignSetting = {
 20968      "start": true,
 20969      "middle": true,
 20970      "end": true,
 20971      "left": true,
 20972      "right": true
 20973    };
 20974  
 20975    function findDirectionSetting(value) {
 20976      if (typeof value !== "string") {
 20977        return false;
 20978      }
 20979      var dir = directionSetting[value.toLowerCase()];
 20980      return dir ? value.toLowerCase() : false;
 20981    }
 20982  
 20983    function findAlignSetting(value) {
 20984      if (typeof value !== "string") {
 20985        return false;
 20986      }
 20987      var align = alignSetting[value.toLowerCase()];
 20988      return align ? value.toLowerCase() : false;
 20989    }
 20990  
 20991    function extend(obj) {
 20992      var i = 1;
 20993      for (; i < arguments.length; i++) {
 20994        var cobj = arguments[i];
 20995        for (var p in cobj) {
 20996          obj[p] = cobj[p];
 20997        }
 20998      }
 20999  
 21000      return obj;
 21001    }
 21002  
 21003    function VTTCue(startTime, endTime, text) {
 21004      var cue = this;
 21005      var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
 21006      var baseObj = {};
 21007  
 21008      if (isIE8) {
 21009        cue = document.createElement('custom');
 21010      } else {
 21011        baseObj.enumerable = true;
 21012      }
 21013  
 21014      /**
 21015       * Shim implementation specific properties. These properties are not in
 21016       * the spec.
 21017       */
 21018  
 21019      // Lets us know when the VTTCue's data has changed in such a way that we need
 21020      // to recompute its display state. This lets us compute its display state
 21021      // lazily.
 21022      cue.hasBeenReset = false;
 21023  
 21024      /**
 21025       * VTTCue and TextTrackCue properties
 21026       * http://dev.w3.org/html5/webvtt/#vttcue-interface
 21027       */
 21028  
 21029      var _id = "";
 21030      var _pauseOnExit = false;
 21031      var _startTime = startTime;
 21032      var _endTime = endTime;
 21033      var _text = text;
 21034      var _region = null;
 21035      var _vertical = "";
 21036      var _snapToLines = true;
 21037      var _line = "auto";
 21038      var _lineAlign = "start";
 21039      var _position = 50;
 21040      var _positionAlign = "middle";
 21041      var _size = 50;
 21042      var _align = "middle";
 21043  
 21044      Object.defineProperty(cue,
 21045        "id", extend({}, baseObj, {
 21046          get: function() {
 21047            return _id;
 21048          },
 21049          set: function(value) {
 21050            _id = "" + value;
 21051          }
 21052        }));
 21053  
 21054      Object.defineProperty(cue,
 21055        "pauseOnExit", extend({}, baseObj, {
 21056          get: function() {
 21057            return _pauseOnExit;
 21058          },
 21059          set: function(value) {
 21060            _pauseOnExit = !!value;
 21061          }
 21062        }));
 21063  
 21064      Object.defineProperty(cue,
 21065        "startTime", extend({}, baseObj, {
 21066          get: function() {
 21067            return _startTime;
 21068          },
 21069          set: function(value) {
 21070            if (typeof value !== "number") {
 21071              throw new TypeError("Start time must be set to a number.");
 21072            }
 21073            _startTime = value;
 21074            this.hasBeenReset = true;
 21075          }
 21076        }));
 21077  
 21078      Object.defineProperty(cue,
 21079        "endTime", extend({}, baseObj, {
 21080          get: function() {
 21081            return _endTime;
 21082          },
 21083          set: function(value) {
 21084            if (typeof value !== "number") {
 21085              throw new TypeError("End time must be set to a number.");
 21086            }
 21087            _endTime = value;
 21088            this.hasBeenReset = true;
 21089          }
 21090        }));
 21091  
 21092      Object.defineProperty(cue,
 21093        "text", extend({}, baseObj, {
 21094          get: function() {
 21095            return _text;
 21096          },
 21097          set: function(value) {
 21098            _text = "" + value;
 21099            this.hasBeenReset = true;
 21100          }
 21101        }));
 21102  
 21103      Object.defineProperty(cue,
 21104        "region", extend({}, baseObj, {
 21105          get: function() {
 21106            return _region;
 21107          },
 21108          set: function(value) {
 21109            _region = value;
 21110            this.hasBeenReset = true;
 21111          }
 21112        }));
 21113  
 21114      Object.defineProperty(cue,
 21115        "vertical", extend({}, baseObj, {
 21116          get: function() {
 21117            return _vertical;
 21118          },
 21119          set: function(value) {
 21120            var setting = findDirectionSetting(value);
 21121            // Have to check for false because the setting an be an empty string.
 21122            if (setting === false) {
 21123              throw new SyntaxError("An invalid or illegal string was specified.");
 21124            }
 21125            _vertical = setting;
 21126            this.hasBeenReset = true;
 21127          }
 21128        }));
 21129  
 21130      Object.defineProperty(cue,
 21131        "snapToLines", extend({}, baseObj, {
 21132          get: function() {
 21133            return _snapToLines;
 21134          },
 21135          set: function(value) {
 21136            _snapToLines = !!value;
 21137            this.hasBeenReset = true;
 21138          }
 21139        }));
 21140  
 21141      Object.defineProperty(cue,
 21142        "line", extend({}, baseObj, {
 21143          get: function() {
 21144            return _line;
 21145          },
 21146          set: function(value) {
 21147            if (typeof value !== "number" && value !== autoKeyword) {
 21148              throw new SyntaxError("An invalid number or illegal string was specified.");
 21149            }
 21150            _line = value;
 21151            this.hasBeenReset = true;
 21152          }
 21153        }));
 21154  
 21155      Object.defineProperty(cue,
 21156        "lineAlign", extend({}, baseObj, {
 21157          get: function() {
 21158            return _lineAlign;
 21159          },
 21160          set: function(value) {
 21161            var setting = findAlignSetting(value);
 21162            if (!setting) {
 21163              throw new SyntaxError("An invalid or illegal string was specified.");
 21164            }
 21165            _lineAlign = setting;
 21166            this.hasBeenReset = true;
 21167          }
 21168        }));
 21169  
 21170      Object.defineProperty(cue,
 21171        "position", extend({}, baseObj, {
 21172          get: function() {
 21173            return _position;
 21174          },
 21175          set: function(value) {
 21176            if (value < 0 || value > 100) {
 21177              throw new Error("Position must be between 0 and 100.");
 21178            }
 21179            _position = value;
 21180            this.hasBeenReset = true;
 21181          }
 21182        }));
 21183  
 21184      Object.defineProperty(cue,
 21185        "positionAlign", extend({}, baseObj, {
 21186          get: function() {
 21187            return _positionAlign;
 21188          },
 21189          set: function(value) {
 21190            var setting = findAlignSetting(value);
 21191            if (!setting) {
 21192              throw new SyntaxError("An invalid or illegal string was specified.");
 21193            }
 21194            _positionAlign = setting;
 21195            this.hasBeenReset = true;
 21196          }
 21197        }));
 21198  
 21199      Object.defineProperty(cue,
 21200        "size", extend({}, baseObj, {
 21201          get: function() {
 21202            return _size;
 21203          },
 21204          set: function(value) {
 21205            if (value < 0 || value > 100) {
 21206              throw new Error("Size must be between 0 and 100.");
 21207            }
 21208            _size = value;
 21209            this.hasBeenReset = true;
 21210          }
 21211        }));
 21212  
 21213      Object.defineProperty(cue,
 21214        "align", extend({}, baseObj, {
 21215          get: function() {
 21216            return _align;
 21217          },
 21218          set: function(value) {
 21219            var setting = findAlignSetting(value);
 21220            if (!setting) {
 21221              throw new SyntaxError("An invalid or illegal string was specified.");
 21222            }
 21223            _align = setting;
 21224            this.hasBeenReset = true;
 21225          }
 21226        }));
 21227  
 21228      /**
 21229       * Other <track> spec defined properties
 21230       */
 21231  
 21232      // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state
 21233      cue.displayState = undefined;
 21234  
 21235      if (isIE8) {
 21236        return cue;
 21237      }
 21238    }
 21239  
 21240    /**
 21241     * VTTCue methods
 21242     */
 21243  
 21244    VTTCue.prototype.getCueAsHTML = function() {
 21245      // Assume WebVTT.convertCueToDOMTree is on the global.
 21246      return WebVTT.convertCueToDOMTree(window, this.text);
 21247    };
 21248  
 21249    root.VTTCue = root.VTTCue || VTTCue;
 21250    vttjs.VTTCue = VTTCue;
 21251  }(this, (this.vttjs || {})));
 21252  
 21253  /**
 21254   * Copyright 2013 vtt.js Contributors
 21255   *
 21256   * Licensed under the Apache License, Version 2.0 (the "License");
 21257   * you may not use this file except in compliance with the License.
 21258   * You may obtain a copy of the License at
 21259   *
 21260   *   http://www.apache.org/licenses/LICENSE-2.0
 21261   *
 21262   * Unless required by applicable law or agreed to in writing, software
 21263   * distributed under the License is distributed on an "AS IS" BASIS,
 21264   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 21265   * See the License for the specific language governing permissions and
 21266   * limitations under the License.
 21267   */
 21268  
 21269  (function(root, vttjs) {
 21270  
 21271    var scrollSetting = {
 21272      "": true,
 21273      "up": true
 21274    };
 21275  
 21276    function findScrollSetting(value) {
 21277      if (typeof value !== "string") {
 21278        return false;
 21279      }
 21280      var scroll = scrollSetting[value.toLowerCase()];
 21281      return scroll ? value.toLowerCase() : false;
 21282    }
 21283  
 21284    function isValidPercentValue(value) {
 21285      return typeof value === "number" && (value >= 0 && value <= 100);
 21286    }
 21287  
 21288    // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface
 21289    function VTTRegion() {
 21290      var _width = 100;
 21291      var _lines = 3;
 21292      var _regionAnchorX = 0;
 21293      var _regionAnchorY = 100;
 21294      var _viewportAnchorX = 0;
 21295      var _viewportAnchorY = 100;
 21296      var _scroll = "";
 21297  
 21298      Object.defineProperties(this, {
 21299        "width": {
 21300          enumerable: true,
 21301          get: function() {
 21302            return _width;
 21303          },
 21304          set: function(value) {
 21305            if (!isValidPercentValue(value)) {
 21306              throw new Error("Width must be between 0 and 100.");
 21307            }
 21308            _width = value;
 21309          }
 21310        },
 21311        "lines": {
 21312          enumerable: true,
 21313          get: function() {
 21314            return _lines;
 21315          },
 21316          set: function(value) {
 21317            if (typeof value !== "number") {
 21318              throw new TypeError("Lines must be set to a number.");
 21319            }
 21320            _lines = value;
 21321          }
 21322        },
 21323        "regionAnchorY": {
 21324          enumerable: true,
 21325          get: function() {
 21326            return _regionAnchorY;
 21327          },
 21328          set: function(value) {
 21329            if (!isValidPercentValue(value)) {
 21330              throw new Error("RegionAnchorX must be between 0 and 100.");
 21331            }
 21332            _regionAnchorY = value;
 21333          }
 21334        },
 21335        "regionAnchorX": {
 21336          enumerable: true,
 21337          get: function() {
 21338            return _regionAnchorX;
 21339          },
 21340          set: function(value) {
 21341            if(!isValidPercentValue(value)) {
 21342              throw new Error("RegionAnchorY must be between 0 and 100.");
 21343            }
 21344            _regionAnchorX = value;
 21345          }
 21346        },
 21347        "viewportAnchorY": {
 21348          enumerable: true,
 21349          get: function() {
 21350            return _viewportAnchorY;
 21351          },
 21352          set: function(value) {
 21353            if (!isValidPercentValue(value)) {
 21354              throw new Error("ViewportAnchorY must be between 0 and 100.");
 21355            }
 21356            _viewportAnchorY = value;
 21357          }
 21358        },
 21359        "viewportAnchorX": {
 21360          enumerable: true,
 21361          get: function() {
 21362            return _viewportAnchorX;
 21363          },
 21364          set: function(value) {
 21365            if (!isValidPercentValue(value)) {
 21366              throw new Error("ViewportAnchorX must be between 0 and 100.");
 21367            }
 21368            _viewportAnchorX = value;
 21369          }
 21370        },
 21371        "scroll": {
 21372          enumerable: true,
 21373          get: function() {
 21374            return _scroll;
 21375          },
 21376          set: function(value) {
 21377            var setting = findScrollSetting(value);
 21378            // Have to check for false as an empty string is a legal value.
 21379            if (setting === false) {
 21380              throw new SyntaxError("An invalid or illegal string was specified.");
 21381            }
 21382            _scroll = setting;
 21383          }
 21384        }
 21385      });
 21386    }
 21387  
 21388    root.VTTRegion = root.VTTRegion || VTTRegion;
 21389    vttjs.VTTRegion = VTTRegion;
 21390  }(this, (this.vttjs || {})));
 21391  
 21392  /**
 21393   * Copyright 2013 vtt.js Contributors
 21394   *
 21395   * Licensed under the Apache License, Version 2.0 (the "License");
 21396   * you may not use this file except in compliance with the License.
 21397   * You may obtain a copy of the License at
 21398   *
 21399   *   http://www.apache.org/licenses/LICENSE-2.0
 21400   *
 21401   * Unless required by applicable law or agreed to in writing, software
 21402   * distributed under the License is distributed on an "AS IS" BASIS,
 21403   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 21404   * See the License for the specific language governing permissions and
 21405   * limitations under the License.
 21406   */
 21407  
 21408  /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 21409  /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
 21410  
 21411  (function(global) {
 21412  
 21413    var _objCreate = Object.create || (function() {
 21414      function F() {}
 21415      return function(o) {
 21416        if (arguments.length !== 1) {
 21417          throw new Error('Object.create shim only accepts one parameter.');
 21418        }
 21419        F.prototype = o;
 21420        return new F();
 21421      };
 21422    })();
 21423  
 21424    // Creates a new ParserError object from an errorData object. The errorData
 21425    // object should have default code and message properties. The default message
 21426    // property can be overriden by passing in a message parameter.
 21427    // See ParsingError.Errors below for acceptable errors.
 21428    function ParsingError(errorData, message) {
 21429      this.name = "ParsingError";
 21430      this.code = errorData.code;
 21431      this.message = message || errorData.message;
 21432    }
 21433    ParsingError.prototype = _objCreate(Error.prototype);
 21434    ParsingError.prototype.constructor = ParsingError;
 21435  
 21436    // ParsingError metadata for acceptable ParsingErrors.
 21437    ParsingError.Errors = {
 21438      BadSignature: {
 21439        code: 0,
 21440        message: "Malformed WebVTT signature."
 21441      },
 21442      BadTimeStamp: {
 21443        code: 1,
 21444        message: "Malformed time stamp."
 21445      }
 21446    };
 21447  
 21448    // Try to parse input as a time stamp.
 21449    function parseTimeStamp(input) {
 21450  
 21451      function computeSeconds(h, m, s, f) {
 21452        return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000;
 21453      }
 21454  
 21455      var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);
 21456      if (!m) {
 21457        return null;
 21458      }
 21459  
 21460      if (m[3]) {
 21461        // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds]
 21462        return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]);
 21463      } else if (m[1] > 59) {
 21464        // Timestamp takes the form of [hours]:[minutes].[milliseconds]
 21465        // First position is hours as it's over 59.
 21466        return computeSeconds(m[1], m[2], 0,  m[4]);
 21467      } else {
 21468        // Timestamp takes the form of [minutes]:[seconds].[milliseconds]
 21469        return computeSeconds(0, m[1], m[2], m[4]);
 21470      }
 21471    }
 21472  
 21473    // A settings object holds key/value pairs and will ignore anything but the first
 21474    // assignment to a specific key.
 21475    function Settings() {
 21476      this.values = _objCreate(null);
 21477    }
 21478  
 21479    Settings.prototype = {
 21480      // Only accept the first assignment to any key.
 21481      set: function(k, v) {
 21482        if (!this.get(k) && v !== "") {
 21483          this.values[k] = v;
 21484        }
 21485      },
 21486      // Return the value for a key, or a default value.
 21487      // If 'defaultKey' is passed then 'dflt' is assumed to be an object with
 21488      // a number of possible default values as properties where 'defaultKey' is
 21489      // the key of the property that will be chosen; otherwise it's assumed to be
 21490      // a single value.
 21491      get: function(k, dflt, defaultKey) {
 21492        if (defaultKey) {
 21493          return this.has(k) ? this.values[k] : dflt[defaultKey];
 21494        }
 21495        return this.has(k) ? this.values[k] : dflt;
 21496      },
 21497      // Check whether we have a value for a key.
 21498      has: function(k) {
 21499        return k in this.values;
 21500      },
 21501      // Accept a setting if its one of the given alternatives.
 21502      alt: function(k, v, a) {
 21503        for (var n = 0; n < a.length; ++n) {
 21504          if (v === a[n]) {
 21505            this.set(k, v);
 21506            break;
 21507          }
 21508        }
 21509      },
 21510      // Accept a setting if its a valid (signed) integer.
 21511      integer: function(k, v) {
 21512        if (/^-?\d+$/.test(v)) { // integer
 21513          this.set(k, parseInt(v, 10));
 21514        }
 21515      },
 21516      // Accept a setting if its a valid percentage.
 21517      percent: function(k, v) {
 21518        var m;
 21519        if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) {
 21520          v = parseFloat(v);
 21521          if (v >= 0 && v <= 100) {
 21522            this.set(k, v);
 21523            return true;
 21524          }
 21525        }
 21526        return false;
 21527      }
 21528    };
 21529  
 21530    // Helper function to parse input into groups separated by 'groupDelim', and
 21531    // interprete each group as a key/value pair separated by 'keyValueDelim'.
 21532    function parseOptions(input, callback, keyValueDelim, groupDelim) {
 21533      var groups = groupDelim ? input.split(groupDelim) : [input];
 21534      for (var i in groups) {
 21535        if (typeof groups[i] !== "string") {
 21536          continue;
 21537        }
 21538        var kv = groups[i].split(keyValueDelim);
 21539        if (kv.length !== 2) {
 21540          continue;
 21541        }
 21542        var k = kv[0];
 21543        var v = kv[1];
 21544        callback(k, v);
 21545      }
 21546    }
 21547  
 21548    function parseCue(input, cue, regionList) {
 21549      // Remember the original input if we need to throw an error.
 21550      var oInput = input;
 21551      // 4.1 WebVTT timestamp
 21552      function consumeTimeStamp() {
 21553        var ts = parseTimeStamp(input);
 21554        if (ts === null) {
 21555          throw new ParsingError(ParsingError.Errors.BadTimeStamp,
 21556                                "Malformed timestamp: " + oInput);
 21557        }
 21558        // Remove time stamp from input.
 21559        input = input.replace(/^[^\sa-zA-Z-]+/, "");
 21560        return ts;
 21561      }
 21562  
 21563      // 4.4.2 WebVTT cue settings
 21564      function consumeCueSettings(input, cue) {
 21565        var settings = new Settings();
 21566  
 21567        parseOptions(input, function (k, v) {
 21568          switch (k) {
 21569          case "region":
 21570            // Find the last region we parsed with the same region id.
 21571            for (var i = regionList.length - 1; i >= 0; i--) {
 21572              if (regionList[i].id === v) {
 21573                settings.set(k, regionList[i].region);
 21574                break;
 21575              }
 21576            }
 21577            break;
 21578          case "vertical":
 21579            settings.alt(k, v, ["rl", "lr"]);
 21580            break;
 21581          case "line":
 21582            var vals = v.split(","),
 21583                vals0 = vals[0];
 21584            settings.integer(k, vals0);
 21585            settings.percent(k, vals0) ? settings.set("snapToLines", false) : null;
 21586            settings.alt(k, vals0, ["auto"]);
 21587            if (vals.length === 2) {
 21588              settings.alt("lineAlign", vals[1], ["start", "middle", "end"]);
 21589            }
 21590            break;
 21591          case "position":
 21592            vals = v.split(",");
 21593            settings.percent(k, vals[0]);
 21594            if (vals.length === 2) {
 21595              settings.alt("positionAlign", vals[1], ["start", "middle", "end"]);
 21596            }
 21597            break;
 21598          case "size":
 21599            settings.percent(k, v);
 21600            break;
 21601          case "align":
 21602            settings.alt(k, v, ["start", "middle", "end", "left", "right"]);
 21603            break;
 21604          }
 21605        }, /:/, /\s/);
 21606  
 21607        // Apply default values for any missing fields.
 21608        cue.region = settings.get("region", null);
 21609        cue.vertical = settings.get("vertical", "");
 21610        cue.line = settings.get("line", "auto");
 21611        cue.lineAlign = settings.get("lineAlign", "start");
 21612        cue.snapToLines = settings.get("snapToLines", true);
 21613        cue.size = settings.get("size", 100);
 21614        cue.align = settings.get("align", "middle");
 21615        cue.position = settings.get("position", {
 21616          start: 0,
 21617          left: 0,
 21618          middle: 50,
 21619          end: 100,
 21620          right: 100
 21621        }, cue.align);
 21622        cue.positionAlign = settings.get("positionAlign", {
 21623          start: "start",
 21624          left: "start",
 21625          middle: "middle",
 21626          end: "end",
 21627          right: "end"
 21628        }, cue.align);
 21629      }
 21630  
 21631      function skipWhitespace() {
 21632        input = input.replace(/^\s+/, "");
 21633      }
 21634  
 21635      // 4.1 WebVTT cue timings.
 21636      skipWhitespace();
 21637      cue.startTime = consumeTimeStamp();   // (1) collect cue start time
 21638      skipWhitespace();
 21639      if (input.substr(0, 3) !== "-->") {     // (3) next characters must match "-->"
 21640        throw new ParsingError(ParsingError.Errors.BadTimeStamp,
 21641                               "Malformed time stamp (time stamps must be separated by '-->'): " +
 21642                               oInput);
 21643      }
 21644      input = input.substr(3);
 21645      skipWhitespace();
 21646      cue.endTime = consumeTimeStamp();     // (5) collect cue end time
 21647  
 21648      // 4.1 WebVTT cue settings list.
 21649      skipWhitespace();
 21650      consumeCueSettings(input, cue);
 21651    }
 21652  
 21653    var ESCAPE = {
 21654      "&amp;": "&",
 21655      "&lt;": "<",
 21656      "&gt;": ">",
 21657      "&lrm;": "\u200e",
 21658      "&rlm;": "\u200f",
 21659      "&nbsp;": "\u00a0"
 21660    };
 21661  
 21662    var TAG_NAME = {
 21663      c: "span",
 21664      i: "i",
 21665      b: "b",
 21666      u: "u",
 21667      ruby: "ruby",
 21668      rt: "rt",
 21669      v: "span",
 21670      lang: "span"
 21671    };
 21672  
 21673    var TAG_ANNOTATION = {
 21674      v: "title",
 21675      lang: "lang"
 21676    };
 21677  
 21678    var NEEDS_PARENT = {
 21679      rt: "ruby"
 21680    };
 21681  
 21682    // Parse content into a document fragment.
 21683    function parseContent(window, input) {
 21684      function nextToken() {
 21685        // Check for end-of-string.
 21686        if (!input) {
 21687          return null;
 21688        }
 21689  
 21690        // Consume 'n' characters from the input.
 21691        function consume(result) {
 21692          input = input.substr(result.length);
 21693          return result;
 21694        }
 21695  
 21696        var m = input.match(/^([^<]*)(<[^>]+>?)?/);
 21697        // If there is some text before the next tag, return it, otherwise return
 21698        // the tag.
 21699        return consume(m[1] ? m[1] : m[2]);
 21700      }
 21701  
 21702      // Unescape a string 's'.
 21703      function unescape1(e) {
 21704        return ESCAPE[e];
 21705      }
 21706      function unescape(s) {
 21707        while ((m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/))) {
 21708          s = s.replace(m[0], unescape1);
 21709        }
 21710        return s;
 21711      }
 21712  
 21713      function shouldAdd(current, element) {
 21714        return !NEEDS_PARENT[element.localName] ||
 21715               NEEDS_PARENT[element.localName] === current.localName;
 21716      }
 21717  
 21718      // Create an element for this tag.
 21719      function createElement(type, annotation) {
 21720        var tagName = TAG_NAME[type];
 21721        if (!tagName) {
 21722          return null;
 21723        }
 21724        var element = window.document.createElement(tagName);
 21725        element.localName = tagName;
 21726        var name = TAG_ANNOTATION[type];
 21727        if (name && annotation) {
 21728          element[name] = annotation.trim();
 21729        }
 21730        return element;
 21731      }
 21732  
 21733      var rootDiv = window.document.createElement("div"),
 21734          current = rootDiv,
 21735          t,
 21736          tagStack = [];
 21737  
 21738      while ((t = nextToken()) !== null) {
 21739        if (t[0] === '<') {
 21740          if (t[1] === "/") {
 21741            // If the closing tag matches, move back up to the parent node.
 21742            if (tagStack.length &&
 21743                tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) {
 21744              tagStack.pop();
 21745              current = current.parentNode;
 21746            }
 21747            // Otherwise just ignore the end tag.
 21748            continue;
 21749          }
 21750          var ts = parseTimeStamp(t.substr(1, t.length - 2));
 21751          var node;
 21752          if (ts) {
 21753            // Timestamps are lead nodes as well.
 21754            node = window.document.createProcessingInstruction("timestamp", ts);
 21755            current.appendChild(node);
 21756            continue;
 21757          }
 21758          var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);
 21759          // If we can't parse the tag, skip to the next tag.
 21760          if (!m) {
 21761            continue;
 21762          }
 21763          // Try to construct an element, and ignore the tag if we couldn't.
 21764          node = createElement(m[1], m[3]);
 21765          if (!node) {
 21766            continue;
 21767          }
 21768          // Determine if the tag should be added based on the context of where it
 21769          // is placed in the cuetext.
 21770          if (!shouldAdd(current, node)) {
 21771            continue;
 21772          }
 21773          // Set the class list (as a list of classes, separated by space).
 21774          if (m[2]) {
 21775            node.className = m[2].substr(1).replace('.', ' ');
 21776          }
 21777          // Append the node to the current node, and enter the scope of the new
 21778          // node.
 21779          tagStack.push(m[1]);
 21780          current.appendChild(node);
 21781          current = node;
 21782          continue;
 21783        }
 21784  
 21785        // Text nodes are leaf nodes.
 21786        current.appendChild(window.document.createTextNode(unescape(t)));
 21787      }
 21788  
 21789      return rootDiv;
 21790    }
 21791  
 21792    // This is a list of all the Unicode characters that have a strong
 21793    // right-to-left category. What this means is that these characters are
 21794    // written right-to-left for sure. It was generated by pulling all the strong
 21795    // right-to-left characters out of the Unicode data table. That table can
 21796    // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
 21797    var strongRTLChars = [0x05BE, 0x05C0, 0x05C3, 0x05C6, 0x05D0, 0x05D1,
 21798        0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA,
 21799        0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3,
 21800        0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x05F0, 0x05F1,
 21801        0x05F2, 0x05F3, 0x05F4, 0x0608, 0x060B, 0x060D, 0x061B, 0x061E, 0x061F,
 21802        0x0620, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628,
 21803        0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631,
 21804        0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A,
 21805        0x063B, 0x063C, 0x063D, 0x063E, 0x063F, 0x0640, 0x0641, 0x0642, 0x0643,
 21806        0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x066D, 0x066E,
 21807        0x066F, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675, 0x0676, 0x0677, 0x0678,
 21808        0x0679, 0x067A, 0x067B, 0x067C, 0x067D, 0x067E, 0x067F, 0x0680, 0x0681,
 21809        0x0682, 0x0683, 0x0684, 0x0685, 0x0686, 0x0687, 0x0688, 0x0689, 0x068A,
 21810        0x068B, 0x068C, 0x068D, 0x068E, 0x068F, 0x0690, 0x0691, 0x0692, 0x0693,
 21811        0x0694, 0x0695, 0x0696, 0x0697, 0x0698, 0x0699, 0x069A, 0x069B, 0x069C,
 21812        0x069D, 0x069E, 0x069F, 0x06A0, 0x06A1, 0x06A2, 0x06A3, 0x06A4, 0x06A5,
 21813        0x06A6, 0x06A7, 0x06A8, 0x06A9, 0x06AA, 0x06AB, 0x06AC, 0x06AD, 0x06AE,
 21814        0x06AF, 0x06B0, 0x06B1, 0x06B2, 0x06B3, 0x06B4, 0x06B5, 0x06B6, 0x06B7,
 21815        0x06B8, 0x06B9, 0x06BA, 0x06BB, 0x06BC, 0x06BD, 0x06BE, 0x06BF, 0x06C0,
 21816        0x06C1, 0x06C2, 0x06C3, 0x06C4, 0x06C5, 0x06C6, 0x06C7, 0x06C8, 0x06C9,
 21817        0x06CA, 0x06CB, 0x06CC, 0x06CD, 0x06CE, 0x06CF, 0x06D0, 0x06D1, 0x06D2,
 21818        0x06D3, 0x06D4, 0x06D5, 0x06E5, 0x06E6, 0x06EE, 0x06EF, 0x06FA, 0x06FB,
 21819        0x06FC, 0x06FD, 0x06FE, 0x06FF, 0x0700, 0x0701, 0x0702, 0x0703, 0x0704,
 21820        0x0705, 0x0706, 0x0707, 0x0708, 0x0709, 0x070A, 0x070B, 0x070C, 0x070D,
 21821        0x070F, 0x0710, 0x0712, 0x0713, 0x0714, 0x0715, 0x0716, 0x0717, 0x0718,
 21822        0x0719, 0x071A, 0x071B, 0x071C, 0x071D, 0x071E, 0x071F, 0x0720, 0x0721,
 21823        0x0722, 0x0723, 0x0724, 0x0725, 0x0726, 0x0727, 0x0728, 0x0729, 0x072A,
 21824        0x072B, 0x072C, 0x072D, 0x072E, 0x072F, 0x074D, 0x074E, 0x074F, 0x0750,
 21825        0x0751, 0x0752, 0x0753, 0x0754, 0x0755, 0x0756, 0x0757, 0x0758, 0x0759,
 21826        0x075A, 0x075B, 0x075C, 0x075D, 0x075E, 0x075F, 0x0760, 0x0761, 0x0762,
 21827        0x0763, 0x0764, 0x0765, 0x0766, 0x0767, 0x0768, 0x0769, 0x076A, 0x076B,
 21828        0x076C, 0x076D, 0x076E, 0x076F, 0x0770, 0x0771, 0x0772, 0x0773, 0x0774,
 21829        0x0775, 0x0776, 0x0777, 0x0778, 0x0779, 0x077A, 0x077B, 0x077C, 0x077D,
 21830        0x077E, 0x077F, 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0786,
 21831        0x0787, 0x0788, 0x0789, 0x078A, 0x078B, 0x078C, 0x078D, 0x078E, 0x078F,
 21832        0x0790, 0x0791, 0x0792, 0x0793, 0x0794, 0x0795, 0x0796, 0x0797, 0x0798,
 21833        0x0799, 0x079A, 0x079B, 0x079C, 0x079D, 0x079E, 0x079F, 0x07A0, 0x07A1,
 21834        0x07A2, 0x07A3, 0x07A4, 0x07A5, 0x07B1, 0x07C0, 0x07C1, 0x07C2, 0x07C3,
 21835        0x07C4, 0x07C5, 0x07C6, 0x07C7, 0x07C8, 0x07C9, 0x07CA, 0x07CB, 0x07CC,
 21836        0x07CD, 0x07CE, 0x07CF, 0x07D0, 0x07D1, 0x07D2, 0x07D3, 0x07D4, 0x07D5,
 21837        0x07D6, 0x07D7, 0x07D8, 0x07D9, 0x07DA, 0x07DB, 0x07DC, 0x07DD, 0x07DE,
 21838        0x07DF, 0x07E0, 0x07E1, 0x07E2, 0x07E3, 0x07E4, 0x07E5, 0x07E6, 0x07E7,
 21839        0x07E8, 0x07E9, 0x07EA, 0x07F4, 0x07F5, 0x07FA, 0x0800, 0x0801, 0x0802,
 21840        0x0803, 0x0804, 0x0805, 0x0806, 0x0807, 0x0808, 0x0809, 0x080A, 0x080B,
 21841        0x080C, 0x080D, 0x080E, 0x080F, 0x0810, 0x0811, 0x0812, 0x0813, 0x0814,
 21842        0x0815, 0x081A, 0x0824, 0x0828, 0x0830, 0x0831, 0x0832, 0x0833, 0x0834,
 21843        0x0835, 0x0836, 0x0837, 0x0838, 0x0839, 0x083A, 0x083B, 0x083C, 0x083D,
 21844        0x083E, 0x0840, 0x0841, 0x0842, 0x0843, 0x0844, 0x0845, 0x0846, 0x0847,
 21845        0x0848, 0x0849, 0x084A, 0x084B, 0x084C, 0x084D, 0x084E, 0x084F, 0x0850,
 21846        0x0851, 0x0852, 0x0853, 0x0854, 0x0855, 0x0856, 0x0857, 0x0858, 0x085E,
 21847        0x08A0, 0x08A2, 0x08A3, 0x08A4, 0x08A5, 0x08A6, 0x08A7, 0x08A8, 0x08A9,
 21848        0x08AA, 0x08AB, 0x08AC, 0x200F, 0xFB1D, 0xFB1F, 0xFB20, 0xFB21, 0xFB22,
 21849        0xFB23, 0xFB24, 0xFB25, 0xFB26, 0xFB27, 0xFB28, 0xFB2A, 0xFB2B, 0xFB2C,
 21850        0xFB2D, 0xFB2E, 0xFB2F, 0xFB30, 0xFB31, 0xFB32, 0xFB33, 0xFB34, 0xFB35,
 21851        0xFB36, 0xFB38, 0xFB39, 0xFB3A, 0xFB3B, 0xFB3C, 0xFB3E, 0xFB40, 0xFB41,
 21852        0xFB43, 0xFB44, 0xFB46, 0xFB47, 0xFB48, 0xFB49, 0xFB4A, 0xFB4B, 0xFB4C,
 21853        0xFB4D, 0xFB4E, 0xFB4F, 0xFB50, 0xFB51, 0xFB52, 0xFB53, 0xFB54, 0xFB55,
 21854        0xFB56, 0xFB57, 0xFB58, 0xFB59, 0xFB5A, 0xFB5B, 0xFB5C, 0xFB5D, 0xFB5E,
 21855        0xFB5F, 0xFB60, 0xFB61, 0xFB62, 0xFB63, 0xFB64, 0xFB65, 0xFB66, 0xFB67,
 21856        0xFB68, 0xFB69, 0xFB6A, 0xFB6B, 0xFB6C, 0xFB6D, 0xFB6E, 0xFB6F, 0xFB70,
 21857        0xFB71, 0xFB72, 0xFB73, 0xFB74, 0xFB75, 0xFB76, 0xFB77, 0xFB78, 0xFB79,
 21858        0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D, 0xFB7E, 0xFB7F, 0xFB80, 0xFB81, 0xFB82,
 21859        0xFB83, 0xFB84, 0xFB85, 0xFB86, 0xFB87, 0xFB88, 0xFB89, 0xFB8A, 0xFB8B,
 21860        0xFB8C, 0xFB8D, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91, 0xFB92, 0xFB93, 0xFB94,
 21861        0xFB95, 0xFB96, 0xFB97, 0xFB98, 0xFB99, 0xFB9A, 0xFB9B, 0xFB9C, 0xFB9D,
 21862        0xFB9E, 0xFB9F, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3, 0xFBA4, 0xFBA5, 0xFBA6,
 21863        0xFBA7, 0xFBA8, 0xFBA9, 0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD, 0xFBAE, 0xFBAF,
 21864        0xFBB0, 0xFBB1, 0xFBB2, 0xFBB3, 0xFBB4, 0xFBB5, 0xFBB6, 0xFBB7, 0xFBB8,
 21865        0xFBB9, 0xFBBA, 0xFBBB, 0xFBBC, 0xFBBD, 0xFBBE, 0xFBBF, 0xFBC0, 0xFBC1,
 21866        0xFBD3, 0xFBD4, 0xFBD5, 0xFBD6, 0xFBD7, 0xFBD8, 0xFBD9, 0xFBDA, 0xFBDB,
 21867        0xFBDC, 0xFBDD, 0xFBDE, 0xFBDF, 0xFBE0, 0xFBE1, 0xFBE2, 0xFBE3, 0xFBE4,
 21868        0xFBE5, 0xFBE6, 0xFBE7, 0xFBE8, 0xFBE9, 0xFBEA, 0xFBEB, 0xFBEC, 0xFBED,
 21869        0xFBEE, 0xFBEF, 0xFBF0, 0xFBF1, 0xFBF2, 0xFBF3, 0xFBF4, 0xFBF5, 0xFBF6,
 21870        0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF,
 21871        0xFC00, 0xFC01, 0xFC02, 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFC08,
 21872        0xFC09, 0xFC0A, 0xFC0B, 0xFC0C, 0xFC0D, 0xFC0E, 0xFC0F, 0xFC10, 0xFC11,
 21873        0xFC12, 0xFC13, 0xFC14, 0xFC15, 0xFC16, 0xFC17, 0xFC18, 0xFC19, 0xFC1A,
 21874        0xFC1B, 0xFC1C, 0xFC1D, 0xFC1E, 0xFC1F, 0xFC20, 0xFC21, 0xFC22, 0xFC23,
 21875        0xFC24, 0xFC25, 0xFC26, 0xFC27, 0xFC28, 0xFC29, 0xFC2A, 0xFC2B, 0xFC2C,
 21876        0xFC2D, 0xFC2E, 0xFC2F, 0xFC30, 0xFC31, 0xFC32, 0xFC33, 0xFC34, 0xFC35,
 21877        0xFC36, 0xFC37, 0xFC38, 0xFC39, 0xFC3A, 0xFC3B, 0xFC3C, 0xFC3D, 0xFC3E,
 21878        0xFC3F, 0xFC40, 0xFC41, 0xFC42, 0xFC43, 0xFC44, 0xFC45, 0xFC46, 0xFC47,
 21879        0xFC48, 0xFC49, 0xFC4A, 0xFC4B, 0xFC4C, 0xFC4D, 0xFC4E, 0xFC4F, 0xFC50,
 21880        0xFC51, 0xFC52, 0xFC53, 0xFC54, 0xFC55, 0xFC56, 0xFC57, 0xFC58, 0xFC59,
 21881        0xFC5A, 0xFC5B, 0xFC5C, 0xFC5D, 0xFC5E, 0xFC5F, 0xFC60, 0xFC61, 0xFC62,
 21882        0xFC63, 0xFC64, 0xFC65, 0xFC66, 0xFC67, 0xFC68, 0xFC69, 0xFC6A, 0xFC6B,
 21883        0xFC6C, 0xFC6D, 0xFC6E, 0xFC6F, 0xFC70, 0xFC71, 0xFC72, 0xFC73, 0xFC74,
 21884        0xFC75, 0xFC76, 0xFC77, 0xFC78, 0xFC79, 0xFC7A, 0xFC7B, 0xFC7C, 0xFC7D,
 21885        0xFC7E, 0xFC7F, 0xFC80, 0xFC81, 0xFC82, 0xFC83, 0xFC84, 0xFC85, 0xFC86,
 21886        0xFC87, 0xFC88, 0xFC89, 0xFC8A, 0xFC8B, 0xFC8C, 0xFC8D, 0xFC8E, 0xFC8F,
 21887        0xFC90, 0xFC91, 0xFC92, 0xFC93, 0xFC94, 0xFC95, 0xFC96, 0xFC97, 0xFC98,
 21888        0xFC99, 0xFC9A, 0xFC9B, 0xFC9C, 0xFC9D, 0xFC9E, 0xFC9F, 0xFCA0, 0xFCA1,
 21889        0xFCA2, 0xFCA3, 0xFCA4, 0xFCA5, 0xFCA6, 0xFCA7, 0xFCA8, 0xFCA9, 0xFCAA,
 21890        0xFCAB, 0xFCAC, 0xFCAD, 0xFCAE, 0xFCAF, 0xFCB0, 0xFCB1, 0xFCB2, 0xFCB3,
 21891        0xFCB4, 0xFCB5, 0xFCB6, 0xFCB7, 0xFCB8, 0xFCB9, 0xFCBA, 0xFCBB, 0xFCBC,
 21892        0xFCBD, 0xFCBE, 0xFCBF, 0xFCC0, 0xFCC1, 0xFCC2, 0xFCC3, 0xFCC4, 0xFCC5,
 21893        0xFCC6, 0xFCC7, 0xFCC8, 0xFCC9, 0xFCCA, 0xFCCB, 0xFCCC, 0xFCCD, 0xFCCE,
 21894        0xFCCF, 0xFCD0, 0xFCD1, 0xFCD2, 0xFCD3, 0xFCD4, 0xFCD5, 0xFCD6, 0xFCD7,
 21895        0xFCD8, 0xFCD9, 0xFCDA, 0xFCDB, 0xFCDC, 0xFCDD, 0xFCDE, 0xFCDF, 0xFCE0,
 21896        0xFCE1, 0xFCE2, 0xFCE3, 0xFCE4, 0xFCE5, 0xFCE6, 0xFCE7, 0xFCE8, 0xFCE9,
 21897        0xFCEA, 0xFCEB, 0xFCEC, 0xFCED, 0xFCEE, 0xFCEF, 0xFCF0, 0xFCF1, 0xFCF2,
 21898        0xFCF3, 0xFCF4, 0xFCF5, 0xFCF6, 0xFCF7, 0xFCF8, 0xFCF9, 0xFCFA, 0xFCFB,
 21899        0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, 0xFD00, 0xFD01, 0xFD02, 0xFD03, 0xFD04,
 21900        0xFD05, 0xFD06, 0xFD07, 0xFD08, 0xFD09, 0xFD0A, 0xFD0B, 0xFD0C, 0xFD0D,
 21901        0xFD0E, 0xFD0F, 0xFD10, 0xFD11, 0xFD12, 0xFD13, 0xFD14, 0xFD15, 0xFD16,
 21902        0xFD17, 0xFD18, 0xFD19, 0xFD1A, 0xFD1B, 0xFD1C, 0xFD1D, 0xFD1E, 0xFD1F,
 21903        0xFD20, 0xFD21, 0xFD22, 0xFD23, 0xFD24, 0xFD25, 0xFD26, 0xFD27, 0xFD28,
 21904        0xFD29, 0xFD2A, 0xFD2B, 0xFD2C, 0xFD2D, 0xFD2E, 0xFD2F, 0xFD30, 0xFD31,
 21905        0xFD32, 0xFD33, 0xFD34, 0xFD35, 0xFD36, 0xFD37, 0xFD38, 0xFD39, 0xFD3A,
 21906        0xFD3B, 0xFD3C, 0xFD3D, 0xFD50, 0xFD51, 0xFD52, 0xFD53, 0xFD54, 0xFD55,
 21907        0xFD56, 0xFD57, 0xFD58, 0xFD59, 0xFD5A, 0xFD5B, 0xFD5C, 0xFD5D, 0xFD5E,
 21908        0xFD5F, 0xFD60, 0xFD61, 0xFD62, 0xFD63, 0xFD64, 0xFD65, 0xFD66, 0xFD67,
 21909        0xFD68, 0xFD69, 0xFD6A, 0xFD6B, 0xFD6C, 0xFD6D, 0xFD6E, 0xFD6F, 0xFD70,
 21910        0xFD71, 0xFD72, 0xFD73, 0xFD74, 0xFD75, 0xFD76, 0xFD77, 0xFD78, 0xFD79,
 21911        0xFD7A, 0xFD7B, 0xFD7C, 0xFD7D, 0xFD7E, 0xFD7F, 0xFD80, 0xFD81, 0xFD82,
 21912        0xFD83, 0xFD84, 0xFD85, 0xFD86, 0xFD87, 0xFD88, 0xFD89, 0xFD8A, 0xFD8B,
 21913        0xFD8C, 0xFD8D, 0xFD8E, 0xFD8F, 0xFD92, 0xFD93, 0xFD94, 0xFD95, 0xFD96,
 21914        0xFD97, 0xFD98, 0xFD99, 0xFD9A, 0xFD9B, 0xFD9C, 0xFD9D, 0xFD9E, 0xFD9F,
 21915        0xFDA0, 0xFDA1, 0xFDA2, 0xFDA3, 0xFDA4, 0xFDA5, 0xFDA6, 0xFDA7, 0xFDA8,
 21916        0xFDA9, 0xFDAA, 0xFDAB, 0xFDAC, 0xFDAD, 0xFDAE, 0xFDAF, 0xFDB0, 0xFDB1,
 21917        0xFDB2, 0xFDB3, 0xFDB4, 0xFDB5, 0xFDB6, 0xFDB7, 0xFDB8, 0xFDB9, 0xFDBA,
 21918        0xFDBB, 0xFDBC, 0xFDBD, 0xFDBE, 0xFDBF, 0xFDC0, 0xFDC1, 0xFDC2, 0xFDC3,
 21919        0xFDC4, 0xFDC5, 0xFDC6, 0xFDC7, 0xFDF0, 0xFDF1, 0xFDF2, 0xFDF3, 0xFDF4,
 21920        0xFDF5, 0xFDF6, 0xFDF7, 0xFDF8, 0xFDF9, 0xFDFA, 0xFDFB, 0xFDFC, 0xFE70,
 21921        0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE76, 0xFE77, 0xFE78, 0xFE79, 0xFE7A,
 21922        0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F, 0xFE80, 0xFE81, 0xFE82, 0xFE83,
 21923        0xFE84, 0xFE85, 0xFE86, 0xFE87, 0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C,
 21924        0xFE8D, 0xFE8E, 0xFE8F, 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95,
 21925        0xFE96, 0xFE97, 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E,
 21926        0xFE9F, 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7,
 21927        0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF, 0xFEB0,
 21928        0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8, 0xFEB9,
 21929        0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0, 0xFEC1, 0xFEC2,
 21930        0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, 0xFEC9, 0xFECA, 0xFECB,
 21931        0xFECC, 0xFECD, 0xFECE, 0xFECF, 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4,
 21932        0xFED5, 0xFED6, 0xFED7, 0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD,
 21933        0xFEDE, 0xFEDF, 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6,
 21934        0xFEE7, 0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF,
 21935        0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8,
 21936        0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0x10800, 0x10801, 0x10802, 0x10803,
 21937        0x10804, 0x10805, 0x10808, 0x1080A, 0x1080B, 0x1080C, 0x1080D, 0x1080E,
 21938        0x1080F, 0x10810, 0x10811, 0x10812, 0x10813, 0x10814, 0x10815, 0x10816,
 21939        0x10817, 0x10818, 0x10819, 0x1081A, 0x1081B, 0x1081C, 0x1081D, 0x1081E,
 21940        0x1081F, 0x10820, 0x10821, 0x10822, 0x10823, 0x10824, 0x10825, 0x10826,
 21941        0x10827, 0x10828, 0x10829, 0x1082A, 0x1082B, 0x1082C, 0x1082D, 0x1082E,
 21942        0x1082F, 0x10830, 0x10831, 0x10832, 0x10833, 0x10834, 0x10835, 0x10837,
 21943        0x10838, 0x1083C, 0x1083F, 0x10840, 0x10841, 0x10842, 0x10843, 0x10844,
 21944        0x10845, 0x10846, 0x10847, 0x10848, 0x10849, 0x1084A, 0x1084B, 0x1084C,
 21945        0x1084D, 0x1084E, 0x1084F, 0x10850, 0x10851, 0x10852, 0x10853, 0x10854,
 21946        0x10855, 0x10857, 0x10858, 0x10859, 0x1085A, 0x1085B, 0x1085C, 0x1085D,
 21947        0x1085E, 0x1085F, 0x10900, 0x10901, 0x10902, 0x10903, 0x10904, 0x10905,
 21948        0x10906, 0x10907, 0x10908, 0x10909, 0x1090A, 0x1090B, 0x1090C, 0x1090D,
 21949        0x1090E, 0x1090F, 0x10910, 0x10911, 0x10912, 0x10913, 0x10914, 0x10915,
 21950        0x10916, 0x10917, 0x10918, 0x10919, 0x1091A, 0x1091B, 0x10920, 0x10921,
 21951        0x10922, 0x10923, 0x10924, 0x10925, 0x10926, 0x10927, 0x10928, 0x10929,
 21952        0x1092A, 0x1092B, 0x1092C, 0x1092D, 0x1092E, 0x1092F, 0x10930, 0x10931,
 21953        0x10932, 0x10933, 0x10934, 0x10935, 0x10936, 0x10937, 0x10938, 0x10939,
 21954        0x1093F, 0x10980, 0x10981, 0x10982, 0x10983, 0x10984, 0x10985, 0x10986,
 21955        0x10987, 0x10988, 0x10989, 0x1098A, 0x1098B, 0x1098C, 0x1098D, 0x1098E,
 21956        0x1098F, 0x10990, 0x10991, 0x10992, 0x10993, 0x10994, 0x10995, 0x10996,
 21957        0x10997, 0x10998, 0x10999, 0x1099A, 0x1099B, 0x1099C, 0x1099D, 0x1099E,
 21958        0x1099F, 0x109A0, 0x109A1, 0x109A2, 0x109A3, 0x109A4, 0x109A5, 0x109A6,
 21959        0x109A7, 0x109A8, 0x109A9, 0x109AA, 0x109AB, 0x109AC, 0x109AD, 0x109AE,
 21960        0x109AF, 0x109B0, 0x109B1, 0x109B2, 0x109B3, 0x109B4, 0x109B5, 0x109B6,
 21961        0x109B7, 0x109BE, 0x109BF, 0x10A00, 0x10A10, 0x10A11, 0x10A12, 0x10A13,
 21962        0x10A15, 0x10A16, 0x10A17, 0x10A19, 0x10A1A, 0x10A1B, 0x10A1C, 0x10A1D,
 21963        0x10A1E, 0x10A1F, 0x10A20, 0x10A21, 0x10A22, 0x10A23, 0x10A24, 0x10A25,
 21964        0x10A26, 0x10A27, 0x10A28, 0x10A29, 0x10A2A, 0x10A2B, 0x10A2C, 0x10A2D,
 21965        0x10A2E, 0x10A2F, 0x10A30, 0x10A31, 0x10A32, 0x10A33, 0x10A40, 0x10A41,
 21966        0x10A42, 0x10A43, 0x10A44, 0x10A45, 0x10A46, 0x10A47, 0x10A50, 0x10A51,
 21967        0x10A52, 0x10A53, 0x10A54, 0x10A55, 0x10A56, 0x10A57, 0x10A58, 0x10A60,
 21968        0x10A61, 0x10A62, 0x10A63, 0x10A64, 0x10A65, 0x10A66, 0x10A67, 0x10A68,
 21969        0x10A69, 0x10A6A, 0x10A6B, 0x10A6C, 0x10A6D, 0x10A6E, 0x10A6F, 0x10A70,
 21970        0x10A71, 0x10A72, 0x10A73, 0x10A74, 0x10A75, 0x10A76, 0x10A77, 0x10A78,
 21971        0x10A79, 0x10A7A, 0x10A7B, 0x10A7C, 0x10A7D, 0x10A7E, 0x10A7F, 0x10B00,
 21972        0x10B01, 0x10B02, 0x10B03, 0x10B04, 0x10B05, 0x10B06, 0x10B07, 0x10B08,
 21973        0x10B09, 0x10B0A, 0x10B0B, 0x10B0C, 0x10B0D, 0x10B0E, 0x10B0F, 0x10B10,
 21974        0x10B11, 0x10B12, 0x10B13, 0x10B14, 0x10B15, 0x10B16, 0x10B17, 0x10B18,
 21975        0x10B19, 0x10B1A, 0x10B1B, 0x10B1C, 0x10B1D, 0x10B1E, 0x10B1F, 0x10B20,
 21976        0x10B21, 0x10B22, 0x10B23, 0x10B24, 0x10B25, 0x10B26, 0x10B27, 0x10B28,
 21977        0x10B29, 0x10B2A, 0x10B2B, 0x10B2C, 0x10B2D, 0x10B2E, 0x10B2F, 0x10B30,
 21978        0x10B31, 0x10B32, 0x10B33, 0x10B34, 0x10B35, 0x10B40, 0x10B41, 0x10B42,
 21979        0x10B43, 0x10B44, 0x10B45, 0x10B46, 0x10B47, 0x10B48, 0x10B49, 0x10B4A,
 21980        0x10B4B, 0x10B4C, 0x10B4D, 0x10B4E, 0x10B4F, 0x10B50, 0x10B51, 0x10B52,
 21981        0x10B53, 0x10B54, 0x10B55, 0x10B58, 0x10B59, 0x10B5A, 0x10B5B, 0x10B5C,
 21982        0x10B5D, 0x10B5E, 0x10B5F, 0x10B60, 0x10B61, 0x10B62, 0x10B63, 0x10B64,
 21983        0x10B65, 0x10B66, 0x10B67, 0x10B68, 0x10B69, 0x10B6A, 0x10B6B, 0x10B6C,
 21984        0x10B6D, 0x10B6E, 0x10B6F, 0x10B70, 0x10B71, 0x10B72, 0x10B78, 0x10B79,
 21985        0x10B7A, 0x10B7B, 0x10B7C, 0x10B7D, 0x10B7E, 0x10B7F, 0x10C00, 0x10C01,
 21986        0x10C02, 0x10C03, 0x10C04, 0x10C05, 0x10C06, 0x10C07, 0x10C08, 0x10C09,
 21987        0x10C0A, 0x10C0B, 0x10C0C, 0x10C0D, 0x10C0E, 0x10C0F, 0x10C10, 0x10C11,
 21988        0x10C12, 0x10C13, 0x10C14, 0x10C15, 0x10C16, 0x10C17, 0x10C18, 0x10C19,
 21989        0x10C1A, 0x10C1B, 0x10C1C, 0x10C1D, 0x10C1E, 0x10C1F, 0x10C20, 0x10C21,
 21990        0x10C22, 0x10C23, 0x10C24, 0x10C25, 0x10C26, 0x10C27, 0x10C28, 0x10C29,
 21991        0x10C2A, 0x10C2B, 0x10C2C, 0x10C2D, 0x10C2E, 0x10C2F, 0x10C30, 0x10C31,
 21992        0x10C32, 0x10C33, 0x10C34, 0x10C35, 0x10C36, 0x10C37, 0x10C38, 0x10C39,
 21993        0x10C3A, 0x10C3B, 0x10C3C, 0x10C3D, 0x10C3E, 0x10C3F, 0x10C40, 0x10C41,
 21994        0x10C42, 0x10C43, 0x10C44, 0x10C45, 0x10C46, 0x10C47, 0x10C48, 0x1EE00,
 21995        0x1EE01, 0x1EE02, 0x1EE03, 0x1EE05, 0x1EE06, 0x1EE07, 0x1EE08, 0x1EE09,
 21996        0x1EE0A, 0x1EE0B, 0x1EE0C, 0x1EE0D, 0x1EE0E, 0x1EE0F, 0x1EE10, 0x1EE11,
 21997        0x1EE12, 0x1EE13, 0x1EE14, 0x1EE15, 0x1EE16, 0x1EE17, 0x1EE18, 0x1EE19,
 21998        0x1EE1A, 0x1EE1B, 0x1EE1C, 0x1EE1D, 0x1EE1E, 0x1EE1F, 0x1EE21, 0x1EE22,
 21999        0x1EE24, 0x1EE27, 0x1EE29, 0x1EE2A, 0x1EE2B, 0x1EE2C, 0x1EE2D, 0x1EE2E,
 22000        0x1EE2F, 0x1EE30, 0x1EE31, 0x1EE32, 0x1EE34, 0x1EE35, 0x1EE36, 0x1EE37,
 22001        0x1EE39, 0x1EE3B, 0x1EE42, 0x1EE47, 0x1EE49, 0x1EE4B, 0x1EE4D, 0x1EE4E,
 22002        0x1EE4F, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE57, 0x1EE59, 0x1EE5B, 0x1EE5D,
 22003        0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE67, 0x1EE68, 0x1EE69, 0x1EE6A,
 22004        0x1EE6C, 0x1EE6D, 0x1EE6E, 0x1EE6F, 0x1EE70, 0x1EE71, 0x1EE72, 0x1EE74,
 22005        0x1EE75, 0x1EE76, 0x1EE77, 0x1EE79, 0x1EE7A, 0x1EE7B, 0x1EE7C, 0x1EE7E,
 22006        0x1EE80, 0x1EE81, 0x1EE82, 0x1EE83, 0x1EE84, 0x1EE85, 0x1EE86, 0x1EE87,
 22007        0x1EE88, 0x1EE89, 0x1EE8B, 0x1EE8C, 0x1EE8D, 0x1EE8E, 0x1EE8F, 0x1EE90,
 22008        0x1EE91, 0x1EE92, 0x1EE93, 0x1EE94, 0x1EE95, 0x1EE96, 0x1EE97, 0x1EE98,
 22009        0x1EE99, 0x1EE9A, 0x1EE9B, 0x1EEA1, 0x1EEA2, 0x1EEA3, 0x1EEA5, 0x1EEA6,
 22010        0x1EEA7, 0x1EEA8, 0x1EEA9, 0x1EEAB, 0x1EEAC, 0x1EEAD, 0x1EEAE, 0x1EEAF,
 22011        0x1EEB0, 0x1EEB1, 0x1EEB2, 0x1EEB3, 0x1EEB4, 0x1EEB5, 0x1EEB6, 0x1EEB7,
 22012        0x1EEB8, 0x1EEB9, 0x1EEBA, 0x1EEBB, 0x10FFFD];
 22013  
 22014    function determineBidi(cueDiv) {
 22015      var nodeStack = [],
 22016          text = "",
 22017          charCode;
 22018  
 22019      if (!cueDiv || !cueDiv.childNodes) {
 22020        return "ltr";
 22021      }
 22022  
 22023      function pushNodes(nodeStack, node) {
 22024        for (var i = node.childNodes.length - 1; i >= 0; i--) {
 22025          nodeStack.push(node.childNodes[i]);
 22026        }
 22027      }
 22028  
 22029      function nextTextNode(nodeStack) {
 22030        if (!nodeStack || !nodeStack.length) {
 22031          return null;
 22032        }
 22033  
 22034        var node = nodeStack.pop(),
 22035            text = node.textContent || node.innerText;
 22036        if (text) {
 22037          // TODO: This should match all unicode type B characters (paragraph
 22038          // separator characters). See issue #115.
 22039          var m = text.match(/^.*(\n|\r)/);
 22040          if (m) {
 22041            nodeStack.length = 0;
 22042            return m[0];
 22043          }
 22044          return text;
 22045        }
 22046        if (node.tagName === "ruby") {
 22047          return nextTextNode(nodeStack);
 22048        }
 22049        if (node.childNodes) {
 22050          pushNodes(nodeStack, node);
 22051          return nextTextNode(nodeStack);
 22052        }
 22053      }
 22054  
 22055      pushNodes(nodeStack, cueDiv);
 22056      while ((text = nextTextNode(nodeStack))) {
 22057        for (var i = 0; i < text.length; i++) {
 22058          charCode = text.charCodeAt(i);
 22059          for (var j = 0; j < strongRTLChars.length; j++) {
 22060            if (strongRTLChars[j] === charCode) {
 22061              return "rtl";
 22062            }
 22063          }
 22064        }
 22065      }
 22066      return "ltr";
 22067    }
 22068  
 22069    function computeLinePos(cue) {
 22070      if (typeof cue.line === "number" &&
 22071          (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) {
 22072        return cue.line;
 22073      }
 22074      if (!cue.track || !cue.track.textTrackList ||
 22075          !cue.track.textTrackList.mediaElement) {
 22076        return -1;
 22077      }
 22078      var track = cue.track,
 22079          trackList = track.textTrackList,
 22080          count = 0;
 22081      for (var i = 0; i < trackList.length && trackList[i] !== track; i++) {
 22082        if (trackList[i].mode === "showing") {
 22083          count++;
 22084        }
 22085      }
 22086      return ++count * -1;
 22087    }
 22088  
 22089    function StyleBox() {
 22090    }
 22091  
 22092    // Apply styles to a div. If there is no div passed then it defaults to the
 22093    // div on 'this'.
 22094    StyleBox.prototype.applyStyles = function(styles, div) {
 22095      div = div || this.div;
 22096      for (var prop in styles) {
 22097        if (styles.hasOwnProperty(prop)) {
 22098          div.style[prop] = styles[prop];
 22099        }
 22100      }
 22101    };
 22102  
 22103    StyleBox.prototype.formatStyle = function(val, unit) {
 22104      return val === 0 ? 0 : val + unit;
 22105    };
 22106  
 22107    // Constructs the computed display state of the cue (a div). Places the div
 22108    // into the overlay which should be a block level element (usually a div).
 22109    function CueStyleBox(window, cue, styleOptions) {
 22110      var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
 22111      var color = "rgba(255, 255, 255, 1)";
 22112      var backgroundColor = "rgba(0, 0, 0, 0.8)";
 22113  
 22114      if (isIE8) {
 22115        color = "rgb(255, 255, 255)";
 22116        backgroundColor = "rgb(0, 0, 0)";
 22117      }
 22118  
 22119      StyleBox.call(this);
 22120      this.cue = cue;
 22121  
 22122      // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will
 22123      // have inline positioning and will function as the cue background box.
 22124      this.cueDiv = parseContent(window, cue.text);
 22125      var styles = {
 22126        color: color,
 22127        backgroundColor: backgroundColor,
 22128        position: "relative",
 22129        left: 0,
 22130        right: 0,
 22131        top: 0,
 22132        bottom: 0,
 22133        display: "inline"
 22134      };
 22135  
 22136      if (!isIE8) {
 22137        styles.writingMode = cue.vertical === "" ? "horizontal-tb"
 22138                                                 : cue.vertical === "lr" ? "vertical-lr"
 22139                                                                         : "vertical-rl";
 22140        styles.unicodeBidi = "plaintext";
 22141      }
 22142      this.applyStyles(styles, this.cueDiv);
 22143  
 22144      // Create an absolutely positioned div that will be used to position the cue
 22145      // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS
 22146      // mirrors of them except "middle" which is "center" in CSS.
 22147      this.div = window.document.createElement("div");
 22148      styles = {
 22149        textAlign: cue.align === "middle" ? "center" : cue.align,
 22150        font: styleOptions.font,
 22151        whiteSpace: "pre-line",
 22152        position: "absolute"
 22153      };
 22154  
 22155      if (!isIE8) {
 22156        styles.direction = determineBidi(this.cueDiv);
 22157        styles.writingMode = cue.vertical === "" ? "horizontal-tb"
 22158                                                 : cue.vertical === "lr" ? "vertical-lr"
 22159                                                                         : "vertical-rl".
 22160        stylesunicodeBidi =  "plaintext";
 22161      }
 22162  
 22163      this.applyStyles(styles);
 22164  
 22165      this.div.appendChild(this.cueDiv);
 22166  
 22167      // Calculate the distance from the reference edge of the viewport to the text
 22168      // position of the cue box. The reference edge will be resolved later when
 22169      // the box orientation styles are applied.
 22170      var textPos = 0;
 22171      switch (cue.positionAlign) {
 22172      case "start":
 22173        textPos = cue.position;
 22174        break;
 22175      case "middle":
 22176        textPos = cue.position - (cue.size / 2);
 22177        break;
 22178      case "end":
 22179        textPos = cue.position - cue.size;
 22180        break;
 22181      }
 22182  
 22183      // Horizontal box orientation; textPos is the distance from the left edge of the
 22184      // area to the left edge of the box and cue.size is the distance extending to
 22185      // the right from there.
 22186      if (cue.vertical === "") {
 22187        this.applyStyles({
 22188          left:  this.formatStyle(textPos, "%"),
 22189          width: this.formatStyle(cue.size, "%")
 22190        });
 22191      // Vertical box orientation; textPos is the distance from the top edge of the
 22192      // area to the top edge of the box and cue.size is the height extending
 22193      // downwards from there.
 22194      } else {
 22195        this.applyStyles({
 22196          top: this.formatStyle(textPos, "%"),
 22197          height: this.formatStyle(cue.size, "%")
 22198        });
 22199      }
 22200  
 22201      this.move = function(box) {
 22202        this.applyStyles({
 22203          top: this.formatStyle(box.top, "px"),
 22204          bottom: this.formatStyle(box.bottom, "px"),
 22205          left: this.formatStyle(box.left, "px"),
 22206          right: this.formatStyle(box.right, "px"),
 22207          height: this.formatStyle(box.height, "px"),
 22208          width: this.formatStyle(box.width, "px")
 22209        });
 22210      };
 22211    }
 22212    CueStyleBox.prototype = _objCreate(StyleBox.prototype);
 22213    CueStyleBox.prototype.constructor = CueStyleBox;
 22214  
 22215    // Represents the co-ordinates of an Element in a way that we can easily
 22216    // compute things with such as if it overlaps or intersects with another Element.
 22217    // Can initialize it with either a StyleBox or another BoxPosition.
 22218    function BoxPosition(obj) {
 22219      var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
 22220  
 22221      // Either a BoxPosition was passed in and we need to copy it, or a StyleBox
 22222      // was passed in and we need to copy the results of 'getBoundingClientRect'
 22223      // as the object returned is readonly. All co-ordinate values are in reference
 22224      // to the viewport origin (top left).
 22225      var lh, height, width, top;
 22226      if (obj.div) {
 22227        height = obj.div.offsetHeight;
 22228        width = obj.div.offsetWidth;
 22229        top = obj.div.offsetTop;
 22230  
 22231        var rects = (rects = obj.div.childNodes) && (rects = rects[0]) &&
 22232                    rects.getClientRects && rects.getClientRects();
 22233        obj = obj.div.getBoundingClientRect();
 22234        // In certain cases the outter div will be slightly larger then the sum of
 22235        // the inner div's lines. This could be due to bold text, etc, on some platforms.
 22236        // In this case we should get the average line height and use that. This will
 22237        // result in the desired behaviour.
 22238        lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length)
 22239                   : 0;
 22240  
 22241      }
 22242      this.left = obj.left;
 22243      this.right = obj.right;
 22244      this.top = obj.top || top;
 22245      this.height = obj.height || height;
 22246      this.bottom = obj.bottom || (top + (obj.height || height));
 22247      this.width = obj.width || width;
 22248      this.lineHeight = lh !== undefined ? lh : obj.lineHeight;
 22249  
 22250      if (isIE8 && !this.lineHeight) {
 22251        this.lineHeight = 13;
 22252      }
 22253    }
 22254  
 22255    // Move the box along a particular axis. Optionally pass in an amount to move
 22256    // the box. If no amount is passed then the default is the line height of the
 22257    // box.
 22258    BoxPosition.prototype.move = function(axis, toMove) {
 22259      toMove = toMove !== undefined ? toMove : this.lineHeight;
 22260      switch (axis) {
 22261      case "+x":
 22262        this.left += toMove;
 22263        this.right += toMove;
 22264        break;
 22265      case "-x":
 22266        this.left -= toMove;
 22267        this.right -= toMove;
 22268        break;
 22269      case "+y":
 22270        this.top += toMove;
 22271        this.bottom += toMove;
 22272        break;
 22273      case "-y":
 22274        this.top -= toMove;
 22275        this.bottom -= toMove;
 22276        break;
 22277      }
 22278    };
 22279  
 22280    // Check if this box overlaps another box, b2.
 22281    BoxPosition.prototype.overlaps = function(b2) {
 22282      return this.left < b2.right &&
 22283             this.right > b2.left &&
 22284             this.top < b2.bottom &&
 22285             this.bottom > b2.top;
 22286    };
 22287  
 22288    // Check if this box overlaps any other boxes in boxes.
 22289    BoxPosition.prototype.overlapsAny = function(boxes) {
 22290      for (var i = 0; i < boxes.length; i++) {
 22291        if (this.overlaps(boxes[i])) {
 22292          return true;
 22293        }
 22294      }
 22295      return false;
 22296    };
 22297  
 22298    // Check if this box is within another box.
 22299    BoxPosition.prototype.within = function(container) {
 22300      return this.top >= container.top &&
 22301             this.bottom <= container.bottom &&
 22302             this.left >= container.left &&
 22303             this.right <= container.right;
 22304    };
 22305  
 22306    // Check if this box is entirely within the container or it is overlapping
 22307    // on the edge opposite of the axis direction passed. For example, if "+x" is
 22308    // passed and the box is overlapping on the left edge of the container, then
 22309    // return true.
 22310    BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) {
 22311      switch (axis) {
 22312      case "+x":
 22313        return this.left < container.left;
 22314      case "-x":
 22315        return this.right > container.right;
 22316      case "+y":
 22317        return this.top < container.top;
 22318      case "-y":
 22319        return this.bottom > container.bottom;
 22320      }
 22321    };
 22322  
 22323    // Find the percentage of the area that this box is overlapping with another
 22324    // box.
 22325    BoxPosition.prototype.intersectPercentage = function(b2) {
 22326      var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)),
 22327          y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)),
 22328          intersectArea = x * y;
 22329      return intersectArea / (this.height * this.width);
 22330    };
 22331  
 22332    // Convert the positions from this box to CSS compatible positions using
 22333    // the reference container's positions. This has to be done because this
 22334    // box's positions are in reference to the viewport origin, whereas, CSS
 22335    // values are in referecne to their respective edges.
 22336    BoxPosition.prototype.toCSSCompatValues = function(reference) {
 22337      return {
 22338        top: this.top - reference.top,
 22339        bottom: reference.bottom - this.bottom,
 22340        left: this.left - reference.left,
 22341        right: reference.right - this.right,
 22342        height: this.height,
 22343        width: this.width
 22344      };
 22345    };
 22346  
 22347    // Get an object that represents the box's position without anything extra.
 22348    // Can pass a StyleBox, HTMLElement, or another BoxPositon.
 22349    BoxPosition.getSimpleBoxPosition = function(obj) {
 22350      var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0;
 22351      var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0;
 22352      var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0;
 22353  
 22354      obj = obj.div ? obj.div.getBoundingClientRect() :
 22355                    obj.tagName ? obj.getBoundingClientRect() : obj;
 22356      var ret = {
 22357        left: obj.left,
 22358        right: obj.right,
 22359        top: obj.top || top,
 22360        height: obj.height || height,
 22361        bottom: obj.bottom || (top + (obj.height || height)),
 22362        width: obj.width || width
 22363      };
 22364      return ret;
 22365    };
 22366  
 22367    // Move a StyleBox to its specified, or next best, position. The containerBox
 22368    // is the box that contains the StyleBox, such as a div. boxPositions are
 22369    // a list of other boxes that the styleBox can't overlap with.
 22370    function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) {
 22371  
 22372      // Find the best position for a cue box, b, on the video. The axis parameter
 22373      // is a list of axis, the order of which, it will move the box along. For example:
 22374      // Passing ["+x", "-x"] will move the box first along the x axis in the positive
 22375      // direction. If it doesn't find a good position for it there it will then move
 22376      // it along the x axis in the negative direction.
 22377      function findBestPosition(b, axis) {
 22378        var bestPosition,
 22379            specifiedPosition = new BoxPosition(b),
 22380            percentage = 1; // Highest possible so the first thing we get is better.
 22381  
 22382        for (var i = 0; i < axis.length; i++) {
 22383          while (b.overlapsOppositeAxis(containerBox, axis[i]) ||
 22384                 (b.within(containerBox) && b.overlapsAny(boxPositions))) {
 22385            b.move(axis[i]);
 22386          }
 22387          // We found a spot where we aren't overlapping anything. This is our
 22388          // best position.
 22389          if (b.within(containerBox)) {
 22390            return b;
 22391          }
 22392          var p = b.intersectPercentage(containerBox);
 22393          // If we're outside the container box less then we were on our last try
 22394          // then remember this position as the best position.
 22395          if (percentage > p) {
 22396            bestPosition = new BoxPosition(b);
 22397            percentage = p;
 22398          }
 22399          // Reset the box position to the specified position.
 22400          b = new BoxPosition(specifiedPosition);
 22401        }
 22402        return bestPosition || specifiedPosition;
 22403      }
 22404  
 22405      var boxPosition = new BoxPosition(styleBox),
 22406          cue = styleBox.cue,
 22407          linePos = computeLinePos(cue),
 22408          axis = [];
 22409  
 22410      // If we have a line number to align the cue to.
 22411      if (cue.snapToLines) {
 22412        var size;
 22413        switch (cue.vertical) {
 22414        case "":
 22415          axis = [ "+y", "-y" ];
 22416          size = "height";
 22417          break;
 22418        case "rl":
 22419          axis = [ "+x", "-x" ];
 22420          size = "width";
 22421          break;
 22422        case "lr":
 22423          axis = [ "-x", "+x" ];
 22424          size = "width";
 22425          break;
 22426        }
 22427  
 22428        var step = boxPosition.lineHeight,
 22429            position = step * Math.round(linePos),
 22430            maxPosition = containerBox[size] + step,
 22431            initialAxis = axis[0];
 22432  
 22433        // If the specified intial position is greater then the max position then
 22434        // clamp the box to the amount of steps it would take for the box to
 22435        // reach the max position.
 22436        if (Math.abs(position) > maxPosition) {
 22437          position = position < 0 ? -1 : 1;
 22438          position *= Math.ceil(maxPosition / step) * step;
 22439        }
 22440  
 22441        // If computed line position returns negative then line numbers are
 22442        // relative to the bottom of the video instead of the top. Therefore, we
 22443        // need to increase our initial position by the length or width of the
 22444        // video, depending on the writing direction, and reverse our axis directions.
 22445        if (linePos < 0) {
 22446          position += cue.vertical === "" ? containerBox.height : containerBox.width;
 22447          axis = axis.reverse();
 22448        }
 22449  
 22450        // Move the box to the specified position. This may not be its best
 22451        // position.
 22452        boxPosition.move(initialAxis, position);
 22453  
 22454      } else {
 22455        // If we have a percentage line value for the cue.
 22456        var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100;
 22457  
 22458        switch (cue.lineAlign) {
 22459        case "middle":
 22460          linePos -= (calculatedPercentage / 2);
 22461          break;
 22462        case "end":
 22463          linePos -= calculatedPercentage;
 22464          break;
 22465        }
 22466  
 22467        // Apply initial line position to the cue box.
 22468        switch (cue.vertical) {
 22469        case "":
 22470          styleBox.applyStyles({
 22471            top: styleBox.formatStyle(linePos, "%")
 22472          });
 22473          break;
 22474        case "rl":
 22475          styleBox.applyStyles({
 22476            left: styleBox.formatStyle(linePos, "%")
 22477          });
 22478          break;
 22479        case "lr":
 22480          styleBox.applyStyles({
 22481            right: styleBox.formatStyle(linePos, "%")
 22482          });
 22483          break;
 22484        }
 22485  
 22486        axis = [ "+y", "-x", "+x", "-y" ];
 22487  
 22488        // Get the box position again after we've applied the specified positioning
 22489        // to it.
 22490        boxPosition = new BoxPosition(styleBox);
 22491      }
 22492  
 22493      var bestPosition = findBestPosition(boxPosition, axis);
 22494      styleBox.move(bestPosition.toCSSCompatValues(containerBox));
 22495    }
 22496  
 22497    function WebVTT() {
 22498      // Nothing
 22499    }
 22500  
 22501    // Helper to allow strings to be decoded instead of the default binary utf8 data.
 22502    WebVTT.StringDecoder = function() {
 22503      return {
 22504        decode: function(data) {
 22505          if (!data) {
 22506            return "";
 22507          }
 22508          if (typeof data !== "string") {
 22509            throw new Error("Error - expected string data.");
 22510          }
 22511          return decodeURIComponent(encodeURIComponent(data));
 22512        }
 22513      };
 22514    };
 22515  
 22516    WebVTT.convertCueToDOMTree = function(window, cuetext) {
 22517      if (!window || !cuetext) {
 22518        return null;
 22519      }
 22520      return parseContent(window, cuetext);
 22521    };
 22522  
 22523    var FONT_SIZE_PERCENT = 0.05;
 22524    var FONT_STYLE = "sans-serif";
 22525    var CUE_BACKGROUND_PADDING = "1.5%";
 22526  
 22527    // Runs the processing model over the cues and regions passed to it.
 22528    // @param overlay A block level element (usually a div) that the computed cues
 22529    //                and regions will be placed into.
 22530    WebVTT.processCues = function(window, cues, overlay) {
 22531      if (!window || !cues || !overlay) {
 22532        return null;
 22533      }
 22534  
 22535      // Remove all previous children.
 22536      while (overlay.firstChild) {
 22537        overlay.removeChild(overlay.firstChild);
 22538      }
 22539  
 22540      var paddedOverlay = window.document.createElement("div");
 22541      paddedOverlay.style.position = "absolute";
 22542      paddedOverlay.style.left = "0";
 22543      paddedOverlay.style.right = "0";
 22544      paddedOverlay.style.top = "0";
 22545      paddedOverlay.style.bottom = "0";
 22546      paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;
 22547      overlay.appendChild(paddedOverlay);
 22548  
 22549      // Determine if we need to compute the display states of the cues. This could
 22550      // be the case if a cue's state has been changed since the last computation or
 22551      // if it has not been computed yet.
 22552      function shouldCompute(cues) {
 22553        for (var i = 0; i < cues.length; i++) {
 22554          if (cues[i].hasBeenReset || !cues[i].displayState) {
 22555            return true;
 22556          }
 22557        }
 22558        return false;
 22559      }
 22560  
 22561      // We don't need to recompute the cues' display states. Just reuse them.
 22562      if (!shouldCompute(cues)) {
 22563        for (var i = 0; i < cues.length; i++) {
 22564          paddedOverlay.appendChild(cues[i].displayState);
 22565        }
 22566        return;
 22567      }
 22568  
 22569      var boxPositions = [],
 22570          containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay),
 22571          fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;
 22572      var styleOptions = {
 22573        font: fontSize + "px " + FONT_STYLE
 22574      };
 22575  
 22576      (function() {
 22577        var styleBox, cue;
 22578  
 22579        for (var i = 0; i < cues.length; i++) {
 22580          cue = cues[i];
 22581  
 22582          // Compute the intial position and styles of the cue div.
 22583          styleBox = new CueStyleBox(window, cue, styleOptions);
 22584          paddedOverlay.appendChild(styleBox.div);
 22585  
 22586          // Move the cue div to it's correct line position.
 22587          moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);
 22588  
 22589          // Remember the computed div so that we don't have to recompute it later
 22590          // if we don't have too.
 22591          cue.displayState = styleBox.div;
 22592  
 22593          boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox));
 22594        }
 22595      })();
 22596    };
 22597  
 22598    WebVTT.Parser = function(window, vttjs, decoder) {
 22599      if (!decoder) {
 22600        decoder = vttjs;
 22601        vttjs = {};
 22602      }
 22603      if (!vttjs) {
 22604        vttjs = {};
 22605      }
 22606  
 22607      this.window = window;
 22608      this.vttjs = vttjs;
 22609      this.state = "INITIAL";
 22610      this.buffer = "";
 22611      this.decoder = decoder || new TextDecoder("utf8");
 22612      this.regionList = [];
 22613    };
 22614  
 22615    WebVTT.Parser.prototype = {
 22616      // If the error is a ParsingError then report it to the consumer if
 22617      // possible. If it's not a ParsingError then throw it like normal.
 22618      reportOrThrowError: function(e) {
 22619        if (e instanceof ParsingError) {
 22620          this.onparsingerror && this.onparsingerror(e);
 22621        } else {
 22622          throw e;
 22623        }
 22624      },
 22625      parse: function (data) {
 22626        var self = this;
 22627  
 22628        // If there is no data then we won't decode it, but will just try to parse
 22629        // whatever is in buffer already. This may occur in circumstances, for
 22630        // example when flush() is called.
 22631        if (data) {
 22632          // Try to decode the data that we received.
 22633          self.buffer += self.decoder.decode(data, {stream: true});
 22634        }
 22635  
 22636        function collectNextLine() {
 22637          var buffer = self.buffer;
 22638          var pos = 0;
 22639          while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') {
 22640            ++pos;
 22641          }
 22642          var line = buffer.substr(0, pos);
 22643          // Advance the buffer early in case we fail below.
 22644          if (buffer[pos] === '\r') {
 22645            ++pos;
 22646          }
 22647          if (buffer[pos] === '\n') {
 22648            ++pos;
 22649          }
 22650          self.buffer = buffer.substr(pos);
 22651          return line;
 22652        }
 22653  
 22654        // 3.4 WebVTT region and WebVTT region settings syntax
 22655        function parseRegion(input) {
 22656          var settings = new Settings();
 22657  
 22658          parseOptions(input, function (k, v) {
 22659            switch (k) {
 22660            case "id":
 22661              settings.set(k, v);
 22662              break;
 22663            case "width":
 22664              settings.percent(k, v);
 22665              break;
 22666            case "lines":
 22667              settings.integer(k, v);
 22668              break;
 22669            case "regionanchor":
 22670            case "viewportanchor":
 22671              var xy = v.split(',');
 22672              if (xy.length !== 2) {
 22673                break;
 22674              }
 22675              // We have to make sure both x and y parse, so use a temporary
 22676              // settings object here.
 22677              var anchor = new Settings();
 22678              anchor.percent("x", xy[0]);
 22679              anchor.percent("y", xy[1]);
 22680              if (!anchor.has("x") || !anchor.has("y")) {
 22681                break;
 22682              }
 22683              settings.set(k + "X", anchor.get("x"));
 22684              settings.set(k + "Y", anchor.get("y"));
 22685              break;
 22686            case "scroll":
 22687              settings.alt(k, v, ["up"]);
 22688              break;
 22689            }
 22690          }, /=/, /\s/);
 22691  
 22692          // Create the region, using default values for any values that were not
 22693          // specified.
 22694          if (settings.has("id")) {
 22695            var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)();
 22696            region.width = settings.get("width", 100);
 22697            region.lines = settings.get("lines", 3);
 22698            region.regionAnchorX = settings.get("regionanchorX", 0);
 22699            region.regionAnchorY = settings.get("regionanchorY", 100);
 22700            region.viewportAnchorX = settings.get("viewportanchorX", 0);
 22701            region.viewportAnchorY = settings.get("viewportanchorY", 100);
 22702            region.scroll = settings.get("scroll", "");
 22703            // Register the region.
 22704            self.onregion && self.onregion(region);
 22705            // Remember the VTTRegion for later in case we parse any VTTCues that
 22706            // reference it.
 22707            self.regionList.push({
 22708              id: settings.get("id"),
 22709              region: region
 22710            });
 22711          }
 22712        }
 22713  
 22714        // 3.2 WebVTT metadata header syntax
 22715        function parseHeader(input) {
 22716          parseOptions(input, function (k, v) {
 22717            switch (k) {
 22718            case "Region":
 22719              // 3.3 WebVTT region metadata header syntax
 22720              parseRegion(v);
 22721              break;
 22722            }
 22723          }, /:/);
 22724        }
 22725  
 22726        // 5.1 WebVTT file parsing.
 22727        try {
 22728          var line;
 22729          if (self.state === "INITIAL") {
 22730            // We can't start parsing until we have the first line.
 22731            if (!/\r\n|\n/.test(self.buffer)) {
 22732              return this;
 22733            }
 22734  
 22735            line = collectNextLine();
 22736  
 22737            var m = line.match(/^WEBVTT([ \t].*)?$/);
 22738            if (!m || !m[0]) {
 22739              throw new ParsingError(ParsingError.Errors.BadSignature);
 22740            }
 22741  
 22742            self.state = "HEADER";
 22743          }
 22744  
 22745          var alreadyCollectedLine = false;
 22746          while (self.buffer) {
 22747            // We can't parse a line until we have the full line.
 22748            if (!/\r\n|\n/.test(self.buffer)) {
 22749              return this;
 22750            }
 22751  
 22752            if (!alreadyCollectedLine) {
 22753              line = collectNextLine();
 22754            } else {
 22755              alreadyCollectedLine = false;
 22756            }
 22757  
 22758            switch (self.state) {
 22759            case "HEADER":
 22760              // 13-18 - Allow a header (metadata) under the WEBVTT line.
 22761              if (/:/.test(line)) {
 22762                parseHeader(line);
 22763              } else if (!line) {
 22764                // An empty line terminates the header and starts the body (cues).
 22765                self.state = "ID";
 22766              }
 22767              continue;
 22768            case "NOTE":
 22769              // Ignore NOTE blocks.
 22770              if (!line) {
 22771                self.state = "ID";
 22772              }
 22773              continue;
 22774            case "ID":
 22775              // Check for the start of NOTE blocks.
 22776              if (/^NOTE($|[ \t])/.test(line)) {
 22777                self.state = "NOTE";
 22778                break;
 22779              }
 22780              // 19-29 - Allow any number of line terminators, then initialize new cue values.
 22781              if (!line) {
 22782                continue;
 22783              }
 22784              self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, "");
 22785              self.state = "CUE";
 22786              // 30-39 - Check if self line contains an optional identifier or timing data.
 22787              if (line.indexOf("-->") === -1) {
 22788                self.cue.id = line;
 22789                continue;
 22790              }
 22791              // Process line as start of a cue.
 22792              /*falls through*/
 22793            case "CUE":
 22794              // 40 - Collect cue timings and settings.
 22795              try {
 22796                parseCue(line, self.cue, self.regionList);
 22797              } catch (e) {
 22798                self.reportOrThrowError(e);
 22799                // In case of an error ignore rest of the cue.
 22800                self.cue = null;
 22801                self.state = "BADCUE";
 22802                continue;
 22803              }
 22804              self.state = "CUETEXT";
 22805              continue;
 22806            case "CUETEXT":
 22807              var hasSubstring = line.indexOf("-->") !== -1;
 22808              // 34 - If we have an empty line then report the cue.
 22809              // 35 - If we have the special substring '-->' then report the cue,
 22810              // but do not collect the line as we need to process the current
 22811              // one as a new cue.
 22812              if (!line || hasSubstring && (alreadyCollectedLine = true)) {
 22813                // We are done parsing self cue.
 22814                self.oncue && self.oncue(self.cue);
 22815                self.cue = null;
 22816                self.state = "ID";
 22817                continue;
 22818              }
 22819              if (self.cue.text) {
 22820                self.cue.text += "\n";
 22821              }
 22822              self.cue.text += line;
 22823              continue;
 22824            case "BADCUE": // BADCUE
 22825              // 54-62 - Collect and discard the remaining cue.
 22826              if (!line) {
 22827                self.state = "ID";
 22828              }
 22829              continue;
 22830            }
 22831          }
 22832        } catch (e) {
 22833          self.reportOrThrowError(e);
 22834  
 22835          // If we are currently parsing a cue, report what we have.
 22836          if (self.state === "CUETEXT" && self.cue && self.oncue) {
 22837            self.oncue(self.cue);
 22838          }
 22839          self.cue = null;
 22840          // Enter BADWEBVTT state if header was not parsed correctly otherwise
 22841          // another exception occurred so enter BADCUE state.
 22842          self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE";
 22843        }
 22844        return this;
 22845      },
 22846      flush: function () {
 22847        var self = this;
 22848        try {
 22849          // Finish decoding the stream.
 22850          self.buffer += self.decoder.decode();
 22851          // Synthesize the end of the current cue or region.
 22852          if (self.cue || self.state === "HEADER") {
 22853            self.buffer += "\n\n";
 22854            self.parse();
 22855          }
 22856          // If we've flushed, parsed, and we're still on the INITIAL state then
 22857          // that means we don't have enough of the stream to parse the first
 22858          // line.
 22859          if (self.state === "INITIAL") {
 22860            throw new ParsingError(ParsingError.Errors.BadSignature);
 22861          }
 22862        } catch(e) {
 22863          self.reportOrThrowError(e);
 22864        }
 22865        self.onflush && self.onflush();
 22866        return this;
 22867      }
 22868    };
 22869  
 22870    global.WebVTT = WebVTT;
 22871  
 22872  }(this, (this.vttjs || {})));