(window["webpackjsonp"] = window["webpackjsonp"] || []).push([[70],{ /***/ 100: /***/ (function(module, exports) { /** * mux.js * * copyright (c) brightcove * licensed apache-2.0 https://github.com/videojs/mux.js/blob/master/license */ var one_second_in_ts = 90000, // 90khz clock secondstovideots, secondstoaudiots, videotstoseconds, audiotstoseconds, audiotstovideots, videotstoaudiots, metadatatstoseconds; secondstovideots = function(seconds) { return seconds * one_second_in_ts; }; secondstoaudiots = function(seconds, samplerate) { return seconds * samplerate; }; videotstoseconds = function(timestamp) { return timestamp / one_second_in_ts; }; audiotstoseconds = function(timestamp, samplerate) { return timestamp / samplerate; }; audiotstovideots = function(timestamp, samplerate) { return secondstovideots(audiotstoseconds(timestamp, samplerate)); }; videotstoaudiots = function(timestamp, samplerate) { return secondstoaudiots(videotstoseconds(timestamp), samplerate); }; /** * adjust id3 tag or caption timing information by the timeline pts values * (if keeporiginaltimestamps is false) and convert to seconds */ metadatatstoseconds = function(timestamp, timelinestartpts, keeporiginaltimestamps) { return videotstoseconds(keeporiginaltimestamps ? timestamp : timestamp - timelinestartpts); }; module.exports = { one_second_in_ts: one_second_in_ts, secondstovideots: secondstovideots, secondstoaudiots: secondstoaudiots, videotstoseconds: videotstoseconds, audiotstoseconds: audiotstoseconds, audiotstovideots: audiotstovideots, videotstoaudiots: videotstoaudiots, metadatatstoseconds: metadatatstoseconds }; /***/ }), /***/ 122: /***/ (function(module, exports, __webpack_require__) { var eq = __webpack_require__(247); /** * gets the index at which the `key` is found in `array` of key-value pairs. * * @private * @param {array} array the array to inspect. * @param {*} key the key to search for. * @returns {number} returns the index of the matched value, else `-1`. */ function associndexof(array, key) { var length = array.length; while (length--) { if (eq(array[length][0], key)) { return length; } } return -1; } module.exports = associndexof; /***/ }), /***/ 123: /***/ (function(module, exports, __webpack_require__) { var assignvalue = __webpack_require__(248), baseassignvalue = __webpack_require__(249); /** * copies properties of `source` to `object`. * * @private * @param {object} source the object to copy properties from. * @param {array} props the property identifiers to copy. * @param {object} [object={}] the object to copy properties to. * @param {function} [customizer] the function to customize copied values. * @returns {object} returns `object`. */ function copyobject(source, props, object, customizer) { var isnew = !object; object || (object = {}); var index = -1, length = props.length; while (++index < length) { var key = props[index]; var newvalue = customizer ? customizer(object[key], source[key], key, object, source) : undefined; if (newvalue === undefined) { newvalue = source[key]; } if (isnew) { baseassignvalue(object, key, newvalue); } else { assignvalue(object, key, newvalue); } } return object; } module.exports = copyobject; /***/ }), /***/ 156: /***/ (function(module, exports) { /** * creates a unary function that invokes `func` with its argument transformed. * * @private * @param {function} func the function to wrap. * @param {function} transform the argument transform. * @returns {function} returns the new function. */ function overarg(func, transform) { return function(arg) { return func(transform(arg)); }; } module.exports = overarg; /***/ }), /***/ 159: /***/ (function(module, exports, __webpack_require__) { "use strict"; var replace = string.prototype.replace; var percenttwenties = /%20/g; var format = { rfc1738: 'rfc1738', rfc3986: 'rfc3986' }; module.exports = { 'default': format.rfc3986, formatters: { rfc1738: function (value) { return replace.call(value, percenttwenties, '+'); }, rfc3986: function (value) { return string(value); } }, rfc1738: format.rfc1738, rfc3986: format.rfc3986 }; /***/ }), /***/ 168: /***/ (function(module, exports, __webpack_require__) { var baseclone = __webpack_require__(373); /** used to compose bitmasks for cloning. */ var clone_deep_flag = 1, clone_symbols_flag = 4; /** * this method is like `_.clone` except that it recursively clones `value`. * * @static * @memberof _ * @since 1.0.0 * @category lang * @param {*} value the value to recursively clone. * @returns {*} returns the deep cloned value. * @see _.clone * @example * * var objects = [{ 'a': 1 }, { 'b': 2 }]; * * var deep = _.clonedeep(objects); * console.log(deep[0] === objects[0]); * // => false */ function clonedeep(value) { return baseclone(value, clone_deep_flag | clone_symbols_flag); } module.exports = clonedeep; /***/ }), /***/ 174: /***/ (function(module, exports, __webpack_require__) { "use strict"; var stringify = __webpack_require__(426); var parse = __webpack_require__(437); var formats = __webpack_require__(159); module.exports = { formats: formats, parse: parse, stringify: stringify }; /***/ }), /***/ 247: /***/ (function(module, exports) { /** * performs a * [`samevaluezero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * comparison between two values to determine if they are equivalent. * * @static * @memberof _ * @since 4.0.0 * @category lang * @param {*} value the value to compare. * @param {*} other the other value to compare. * @returns {boolean} returns `true` if the values are equivalent, else `false`. * @example * * var object = { 'a': 1 }; * var other = { 'a': 1 }; * * _.eq(object, object); * // => true * * _.eq(object, other); * // => false * * _.eq('a', 'a'); * // => true * * _.eq('a', object('a')); * // => false * * _.eq(nan, nan); * // => true */ function eq(value, other) { return value === other || (value !== value && other !== other); } module.exports = eq; /***/ }), /***/ 248: /***/ (function(module, exports, __webpack_require__) { var baseassignvalue = __webpack_require__(249), eq = __webpack_require__(247); /** used for built-in method references. */ var objectproto = object.prototype; /** used to check objects for own properties. */ var hasownproperty = objectproto.hasownproperty; /** * assigns `value` to `key` of `object` if the existing value is not equivalent * using [`samevaluezero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. * * @private * @param {object} object the object to modify. * @param {string} key the key of the property to assign. * @param {*} value the value to assign. */ function assignvalue(object, key, value) { var objvalue = object[key]; if (!(hasownproperty.call(object, key) && eq(objvalue, value)) || (value === undefined && !(key in object))) { baseassignvalue(object, key, value); } } module.exports = assignvalue; /***/ }), /***/ 249: /***/ (function(module, exports, __webpack_require__) { var defineproperty = __webpack_require__(381); /** * the base implementation of `assignvalue` and `assignmergevalue` without * value checks. * * @private * @param {object} object the object to modify. * @param {string} key the key of the property to assign. * @param {*} value the value to assign. */ function baseassignvalue(object, key, value) { if (key == '__proto__' && defineproperty) { defineproperty(object, key, { 'configurable': true, 'enumerable': true, 'value': value, 'writable': true }); } else { object[key] = value; } } module.exports = baseassignvalue; /***/ }), /***/ 250: /***/ (function(module, exports, __webpack_require__) { var overarg = __webpack_require__(156); /* built-in method references for those with the same name as other `lodash` methods. */ var nativekeys = overarg(object.keys, object); module.exports = nativekeys; /***/ }), /***/ 251: /***/ (function(module, exports) { /** * this function is like * [`object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) * except that it includes inherited enumerable properties. * * @private * @param {object} object the object to query. * @returns {array} returns the array of property names. */ function nativekeysin(object) { var result = []; if (object != null) { for (var key in object(object)) { result.push(key); } } return result; } module.exports = nativekeysin; /***/ }), /***/ 253: /***/ (function(module, exports) { /** * checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `object`. (e.g. arrays, functions, objects, regexes, `new number(0)`, and `new string('')`) * * @static * @memberof _ * @since 0.1.0 * @category lang * @param {*} value the value to check. * @returns {boolean} returns `true` if `value` is an object, else `false`. * @example * * _.isobject({}); * // => true * * _.isobject([1, 2, 3]); * // => true * * _.isobject(_.noop); * // => true * * _.isobject(null); * // => false */ function isobject(value) { var type = typeof value; return value != null && (type == 'object' || type == 'function'); } module.exports = isobject; /***/ }), /***/ 255: /***/ (function(module, exports, __webpack_require__) { "use strict"; var formats = __webpack_require__(159); var has = object.prototype.hasownproperty; var isarray = array.isarray; var hextable = (function () { var array = []; for (var i = 0; i < 256; ++i) { array.push('%' + ((i < 16 ? '0' : '') + i.tostring(16)).touppercase()); } return array; }()); var compactqueue = function compactqueue(queue) { while (queue.length > 1) { var item = queue.pop(); var obj = item.obj[item.prop]; if (isarray(obj)) { var compacted = []; for (var j = 0; j < obj.length; ++j) { if (typeof obj[j] !== 'undefined') { compacted.push(obj[j]); } } item.obj[item.prop] = compacted; } } }; var arraytoobject = function arraytoobject(source, options) { var obj = options && options.plainobjects ? object.create(null) : {}; for (var i = 0; i < source.length; ++i) { if (typeof source[i] !== 'undefined') { obj[i] = source[i]; } } return obj; }; var merge = function merge(target, source, options) { /* eslint no-param-reassign: 0 */ if (!source) { return target; } if (typeof source !== 'object') { if (isarray(target)) { target.push(source); } else if (target && typeof target === 'object') { if ((options && (options.plainobjects || options.allowprototypes)) || !has.call(object.prototype, source)) { target[source] = true; } } else { return [target, source]; } return target; } if (!target || typeof target !== 'object') { return [target].concat(source); } var mergetarget = target; if (isarray(target) && !isarray(source)) { mergetarget = arraytoobject(target, options); } if (isarray(target) && isarray(source)) { source.foreach(function (item, i) { if (has.call(target, i)) { var targetitem = target[i]; if (targetitem && typeof targetitem === 'object' && item && typeof item === 'object') { target[i] = merge(targetitem, item, options); } else { target.push(item); } } else { target[i] = item; } }); return target; } return object.keys(source).reduce(function (acc, key) { var value = source[key]; if (has.call(acc, key)) { acc[key] = merge(acc[key], value, options); } else { acc[key] = value; } return acc; }, mergetarget); }; var assign = function assignsinglesource(target, source) { return object.keys(source).reduce(function (acc, key) { acc[key] = source[key]; return acc; }, target); }; var decode = function (str, decoder, charset) { var strwithoutplus = str.replace(/\+/g, ' '); if (charset === 'iso-8859-1') { // unescape never throws, no try...catch needed: return strwithoutplus.replace(/%[0-9a-f]{2}/gi, unescape); } // utf-8 try { return decodeuricomponent(strwithoutplus); } catch (e) { return strwithoutplus; } }; var encode = function encode(str, defaultencoder, charset, kind, format) { // this code was originally written by brian white (mscdex) for the io.js core querystring library. // it has been adapted here for stricter adherence to rfc 3986 if (str.length === 0) { return str; } var string = str; if (typeof str === 'symbol') { string = symbol.prototype.tostring.call(str); } else if (typeof str !== 'string') { string = string(str); } if (charset === 'iso-8859-1') { return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) { return '%26%23' + parseint($0.slice(2), 16) + '%3b'; }); } var out = ''; for (var i = 0; i < string.length; ++i) { var c = string.charcodeat(i); if ( c === 0x2d // - || c === 0x2e // . || c === 0x5f // _ || c === 0x7e // ~ || (c >= 0x30 && c <= 0x39) // 0-9 || (c >= 0x41 && c <= 0x5a) // a-z || (c >= 0x61 && c <= 0x7a) // a-z || (format === formats.rfc1738 && (c === 0x28 || c === 0x29)) // ( ) ) { out += string.charat(i); continue; } if (c < 0x80) { out = out + hextable[c]; continue; } if (c < 0x800) { out = out + (hextable[0xc0 | (c >> 6)] + hextable[0x80 | (c & 0x3f)]); continue; } if (c < 0xd800 || c >= 0xe000) { out = out + (hextable[0xe0 | (c >> 12)] + hextable[0x80 | ((c >> 6) & 0x3f)] + hextable[0x80 | (c & 0x3f)]); continue; } i += 1; c = 0x10000 + (((c & 0x3ff) << 10) | (string.charcodeat(i) & 0x3ff)); /* eslint operator-linebreak: [2, "before"] */ out += hextable[0xf0 | (c >> 18)] + hextable[0x80 | ((c >> 12) & 0x3f)] + hextable[0x80 | ((c >> 6) & 0x3f)] + hextable[0x80 | (c & 0x3f)]; } return out; }; var compact = function compact(value) { var queue = [{ obj: { o: value }, prop: 'o' }]; var refs = []; for (var i = 0; i < queue.length; ++i) { var item = queue[i]; var obj = item.obj[item.prop]; var keys = object.keys(obj); for (var j = 0; j < keys.length; ++j) { var key = keys[j]; var val = obj[key]; if (typeof val === 'object' && val !== null && refs.indexof(val) === -1) { queue.push({ obj: obj, prop: key }); refs.push(val); } } } compactqueue(queue); return value; }; var isregexp = function isregexp(obj) { return object.prototype.tostring.call(obj) === '[object regexp]'; }; var isbuffer = function isbuffer(obj) { if (!obj || typeof obj !== 'object') { return false; } return !!(obj.constructor && obj.constructor.isbuffer && obj.constructor.isbuffer(obj)); }; var combine = function combine(a, b) { return [].concat(a, b); }; var maybemap = function maybemap(val, fn) { if (isarray(val)) { var mapped = []; for (var i = 0; i < val.length; i += 1) { mapped.push(fn(val[i])); } return mapped; } return fn(val); }; module.exports = { arraytoobject: arraytoobject, assign: assign, combine: combine, compact: compact, decode: decode, encode: encode, isbuffer: isbuffer, isregexp: isregexp, maybemap: maybemap, merge: merge }; /***/ }), /***/ 268: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export linestream */ /* unused harmony export parsestream */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return parser; }); /* harmony import */ var _babel_runtime_helpers_inheritsloose__webpack_imported_module_0__ = __webpack_require__(4); /* harmony import */ var _babel_runtime_helpers_inheritsloose__webpack_imported_module_0___default = /*#__pure__*/__webpack_require__.n(_babel_runtime_helpers_inheritsloose__webpack_imported_module_0__); /* harmony import */ var _videojs_vhs_utils_es_stream_js__webpack_imported_module_1__ = __webpack_require__(132); /* harmony import */ var _babel_runtime_helpers_extends__webpack_imported_module_2__ = __webpack_require__(35); /* harmony import */ var _babel_runtime_helpers_extends__webpack_imported_module_2___default = /*#__pure__*/__webpack_require__.n(_babel_runtime_helpers_extends__webpack_imported_module_2__); /* harmony import */ var _babel_runtime_helpers_assertthisinitialized__webpack_imported_module_3__ = __webpack_require__(6); /* harmony import */ var _babel_runtime_helpers_assertthisinitialized__webpack_imported_module_3___default = /*#__pure__*/__webpack_require__.n(_babel_runtime_helpers_assertthisinitialized__webpack_imported_module_3__); /* harmony import */ var _videojs_vhs_utils_es_decode_b64_to_uint8_array_js__webpack_imported_module_4__ = __webpack_require__(130); /*! @name m3u8-parser @version 4.8.0 @license apache-2.0 */ /** * a stream that buffers string input and generates a `data` event for each * line. * * @class linestream * @extends stream */ var linestream = /*#__pure__*/function (_stream) { _babel_runtime_helpers_inheritsloose__webpack_imported_module_0___default()(linestream, _stream); function linestream() { var _this; _this = _stream.call(this) || this; _this.buffer = ''; return _this; } /** * add new data to be parsed. * * @param {string} data the text to process */ var _proto = linestream.prototype; _proto.push = function push(data) { var nextnewline; this.buffer += data; nextnewline = this.buffer.indexof('\n'); for (; nextnewline > -1; nextnewline = this.buffer.indexof('\n')) { this.trigger('data', this.buffer.substring(0, nextnewline)); this.buffer = this.buffer.substring(nextnewline + 1); } }; return linestream; }(_videojs_vhs_utils_es_stream_js__webpack_imported_module_1__[/* default */ "a"]); var tab = string.fromcharcode(0x09); var parsebyterange = function parsebyterange(byterangestring) { // optionally match and capture 0+ digits before `@` // optionally match and capture 0+ digits after `@` var match = /([0-9.]*)?@?([0-9.]*)?/.exec(byterangestring || ''); var result = {}; if (match[1]) { result.length = parseint(match[1], 10); } if (match[2]) { result.offset = parseint(match[2], 10); } return result; }; /** * "forgiving" attribute list psuedo-grammar: * attributes -> keyvalue (',' keyvalue)* * keyvalue -> key '=' value * key -> [^=]* * value -> '"' [^"]* '"' | [^,]* */ var attributeseparator = function attributeseparator() { var key = '[^=]*'; var value = '"[^"]*"|[^,]*'; var keyvalue = '(?:' + key + ')=(?:' + value + ')'; return new regexp('(?:^|,)(' + keyvalue + ')'); }; /** * parse attributes from a line given the separator * * @param {string} attributes the attribute line to parse */ var parseattributes = function parseattributes(attributes) { // split the string using attributes as the separator var attrs = attributes.split(attributeseparator()); var result = {}; var i = attrs.length; var attr; while (i--) { // filter out unmatched portions of the string if (attrs[i] === '') { continue; } // split the key and value attr = /([^=]*)=(.*)/.exec(attrs[i]).slice(1); // trim whitespace and remove optional quotes around the value attr[0] = attr[0].replace(/^\s+|\s+$/g, ''); attr[1] = attr[1].replace(/^\s+|\s+$/g, ''); attr[1] = attr[1].replace(/^['"](.*)['"]$/g, '$1'); result[attr[0]] = attr[1]; } return result; }; /** * a line-level m3u8 parser event stream. it expects to receive input one * line at a time and performs a context-free parse of its contents. a stream * interpretation of a manifest can be useful if the manifest is expected to * be too large to fit comfortably into memory or the entirety of the input * is not immediately available. otherwise, it's probably much easier to work * with a regular `parser` object. * * produces `data` events with an object that captures the parser's * interpretation of the input. that object has a property `tag` that is one * of `uri`, `comment`, or `tag`. uris only have a single additional * property, `line`, which captures the entirety of the input without * interpretation. comments similarly have a single additional property * `text` which is the input without the leading `#`. * * tags always have a property `tagtype` which is the lower-cased version of * the m3u8 directive without the `#ext` or `#ext-x-` prefix. for instance, * `#ext-x-media-sequence` becomes `media-sequence` when parsed. unrecognized * tags are given the tag type `unknown` and a single additional property * `data` with the remainder of the input. * * @class parsestream * @extends stream */ var parsestream = /*#__pure__*/function (_stream) { _babel_runtime_helpers_inheritsloose__webpack_imported_module_0___default()(parsestream, _stream); function parsestream() { var _this; _this = _stream.call(this) || this; _this.customparsers = []; _this.tagmappers = []; return _this; } /** * parses an additional line of input. * * @param {string} line a single line of an m3u8 file to parse */ var _proto = parsestream.prototype; _proto.push = function push(line) { var _this2 = this; var match; var event; // strip whitespace line = line.trim(); if (line.length === 0) { // ignore empty lines return; } // uris if (line[0] !== '#') { this.trigger('data', { type: 'uri', uri: line }); return; } // map tags var newlines = this.tagmappers.reduce(function (acc, mapper) { var mappedline = mapper(line); // skip if unchanged if (mappedline === line) { return acc; } return acc.concat([mappedline]); }, [line]); newlines.foreach(function (newline) { for (var i = 0; i < _this2.customparsers.length; i++) { if (_this2.customparsers[i].call(_this2, newline)) { return; } } // comments if (newline.indexof('#ext') !== 0) { _this2.trigger('data', { type: 'comment', text: newline.slice(1) }); return; } // strip off any carriage returns here so the regex matching // doesn't have to account for them. newline = newline.replace('\r', ''); // tags match = /^#extm3u/.exec(newline); if (match) { _this2.trigger('data', { type: 'tag', tagtype: 'm3u' }); return; } match = /^#extinf:?([0-9\.]*)?,?(.*)?$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'inf' }; if (match[1]) { event.duration = parsefloat(match[1]); } if (match[2]) { event.title = match[2]; } _this2.trigger('data', event); return; } match = /^#ext-x-targetduration:?([0-9.]*)?/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'targetduration' }; if (match[1]) { event.duration = parseint(match[1], 10); } _this2.trigger('data', event); return; } match = /^#ext-x-version:?([0-9.]*)?/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'version' }; if (match[1]) { event.version = parseint(match[1], 10); } _this2.trigger('data', event); return; } match = /^#ext-x-media-sequence:?(\-?[0-9.]*)?/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'media-sequence' }; if (match[1]) { event.number = parseint(match[1], 10); } _this2.trigger('data', event); return; } match = /^#ext-x-discontinuity-sequence:?(\-?[0-9.]*)?/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'discontinuity-sequence' }; if (match[1]) { event.number = parseint(match[1], 10); } _this2.trigger('data', event); return; } match = /^#ext-x-playlist-type:?(.*)?$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'playlist-type' }; if (match[1]) { event.playlisttype = match[1]; } _this2.trigger('data', event); return; } match = /^#ext-x-byterange:?(.*)?$/.exec(newline); if (match) { event = _babel_runtime_helpers_extends__webpack_imported_module_2___default()(parsebyterange(match[1]), { type: 'tag', tagtype: 'byterange' }); _this2.trigger('data', event); return; } match = /^#ext-x-allow-cache:?(yes|no)?/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'allow-cache' }; if (match[1]) { event.allowed = !/no/.test(match[1]); } _this2.trigger('data', event); return; } match = /^#ext-x-map:?(.*)$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'map' }; if (match[1]) { var attributes = parseattributes(match[1]); if (attributes.uri) { event.uri = attributes.uri; } if (attributes.byterange) { event.byterange = parsebyterange(attributes.byterange); } } _this2.trigger('data', event); return; } match = /^#ext-x-stream-inf:?(.*)$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'stream-inf' }; if (match[1]) { event.attributes = parseattributes(match[1]); if (event.attributes.resolution) { var split = event.attributes.resolution.split('x'); var resolution = {}; if (split[0]) { resolution.width = parseint(split[0], 10); } if (split[1]) { resolution.height = parseint(split[1], 10); } event.attributes.resolution = resolution; } if (event.attributes.bandwidth) { event.attributes.bandwidth = parseint(event.attributes.bandwidth, 10); } if (event.attributes['frame-rate']) { event.attributes['frame-rate'] = parsefloat(event.attributes['frame-rate']); } if (event.attributes['program-id']) { event.attributes['program-id'] = parseint(event.attributes['program-id'], 10); } } _this2.trigger('data', event); return; } match = /^#ext-x-media:?(.*)$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'media' }; if (match[1]) { event.attributes = parseattributes(match[1]); } _this2.trigger('data', event); return; } match = /^#ext-x-endlist/.exec(newline); if (match) { _this2.trigger('data', { type: 'tag', tagtype: 'endlist' }); return; } match = /^#ext-x-discontinuity/.exec(newline); if (match) { _this2.trigger('data', { type: 'tag', tagtype: 'discontinuity' }); return; } match = /^#ext-x-program-date-time:?(.*)$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'program-date-time' }; if (match[1]) { event.datetimestring = match[1]; event.datetimeobject = new date(match[1]); } _this2.trigger('data', event); return; } match = /^#ext-x-key:?(.*)$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'key' }; if (match[1]) { event.attributes = parseattributes(match[1]); // parse the iv string into a uint32array if (event.attributes.iv) { if (event.attributes.iv.substring(0, 2).tolowercase() === '0x') { event.attributes.iv = event.attributes.iv.substring(2); } event.attributes.iv = event.attributes.iv.match(/.{8}/g); event.attributes.iv[0] = parseint(event.attributes.iv[0], 16); event.attributes.iv[1] = parseint(event.attributes.iv[1], 16); event.attributes.iv[2] = parseint(event.attributes.iv[2], 16); event.attributes.iv[3] = parseint(event.attributes.iv[3], 16); event.attributes.iv = new uint32array(event.attributes.iv); } } _this2.trigger('data', event); return; } match = /^#ext-x-start:?(.*)$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'start' }; if (match[1]) { event.attributes = parseattributes(match[1]); event.attributes['time-offset'] = parsefloat(event.attributes['time-offset']); event.attributes.precise = /yes/.test(event.attributes.precise); } _this2.trigger('data', event); return; } match = /^#ext-x-cue-out-cont:?(.*)?$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'cue-out-cont' }; if (match[1]) { event.data = match[1]; } else { event.data = ''; } _this2.trigger('data', event); return; } match = /^#ext-x-cue-out:?(.*)?$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'cue-out' }; if (match[1]) { event.data = match[1]; } else { event.data = ''; } _this2.trigger('data', event); return; } match = /^#ext-x-cue-in:?(.*)?$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'cue-in' }; if (match[1]) { event.data = match[1]; } else { event.data = ''; } _this2.trigger('data', event); return; } match = /^#ext-x-skip:(.*)$/.exec(newline); if (match && match[1]) { event = { type: 'tag', tagtype: 'skip' }; event.attributes = parseattributes(match[1]); if (event.attributes.hasownproperty('skipped-segments')) { event.attributes['skipped-segments'] = parseint(event.attributes['skipped-segments'], 10); } if (event.attributes.hasownproperty('recently-removed-dateranges')) { event.attributes['recently-removed-dateranges'] = event.attributes['recently-removed-dateranges'].split(tab); } _this2.trigger('data', event); return; } match = /^#ext-x-part:(.*)$/.exec(newline); if (match && match[1]) { event = { type: 'tag', tagtype: 'part' }; event.attributes = parseattributes(match[1]); ['duration'].foreach(function (key) { if (event.attributes.hasownproperty(key)) { event.attributes[key] = parsefloat(event.attributes[key]); } }); ['independent', 'gap'].foreach(function (key) { if (event.attributes.hasownproperty(key)) { event.attributes[key] = /yes/.test(event.attributes[key]); } }); if (event.attributes.hasownproperty('byterange')) { event.attributes.byterange = parsebyterange(event.attributes.byterange); } _this2.trigger('data', event); return; } match = /^#ext-x-server-control:(.*)$/.exec(newline); if (match && match[1]) { event = { type: 'tag', tagtype: 'server-control' }; event.attributes = parseattributes(match[1]); ['can-skip-until', 'part-hold-back', 'hold-back'].foreach(function (key) { if (event.attributes.hasownproperty(key)) { event.attributes[key] = parsefloat(event.attributes[key]); } }); ['can-skip-dateranges', 'can-block-reload'].foreach(function (key) { if (event.attributes.hasownproperty(key)) { event.attributes[key] = /yes/.test(event.attributes[key]); } }); _this2.trigger('data', event); return; } match = /^#ext-x-part-inf:(.*)$/.exec(newline); if (match && match[1]) { event = { type: 'tag', tagtype: 'part-inf' }; event.attributes = parseattributes(match[1]); ['part-target'].foreach(function (key) { if (event.attributes.hasownproperty(key)) { event.attributes[key] = parsefloat(event.attributes[key]); } }); _this2.trigger('data', event); return; } match = /^#ext-x-preload-hint:(.*)$/.exec(newline); if (match && match[1]) { event = { type: 'tag', tagtype: 'preload-hint' }; event.attributes = parseattributes(match[1]); ['byterange-start', 'byterange-length'].foreach(function (key) { if (event.attributes.hasownproperty(key)) { event.attributes[key] = parseint(event.attributes[key], 10); var subkey = key === 'byterange-length' ? 'length' : 'offset'; event.attributes.byterange = event.attributes.byterange || {}; event.attributes.byterange[subkey] = event.attributes[key]; // only keep the parsed byterange object. delete event.attributes[key]; } }); _this2.trigger('data', event); return; } match = /^#ext-x-rendition-report:(.*)$/.exec(newline); if (match && match[1]) { event = { type: 'tag', tagtype: 'rendition-report' }; event.attributes = parseattributes(match[1]); ['last-msn', 'last-part'].foreach(function (key) { if (event.attributes.hasownproperty(key)) { event.attributes[key] = parseint(event.attributes[key], 10); } }); _this2.trigger('data', event); return; } // unknown tag type _this2.trigger('data', { type: 'tag', data: newline.slice(4) }); }); } /** * add a parser for custom headers * * @param {object} options a map of options for the added parser * @param {regexp} options.expression a regular expression to match the custom header * @param {string} options.customtype the custom type to register to the output * @param {function} [options.dataparser] function to parse the line into an object * @param {boolean} [options.segment] should tag data be attached to the segment object */ ; _proto.addparser = function addparser(_ref) { var _this3 = this; var expression = _ref.expression, customtype = _ref.customtype, dataparser = _ref.dataparser, segment = _ref.segment; if (typeof dataparser !== 'function') { dataparser = function dataparser(line) { return line; }; } this.customparsers.push(function (line) { var match = expression.exec(line); if (match) { _this3.trigger('data', { type: 'custom', data: dataparser(line), customtype: customtype, segment: segment }); return true; } }); } /** * add a custom header mapper * * @param {object} options * @param {regexp} options.expression a regular expression to match the custom header * @param {function} options.map function to translate tag into a different tag */ ; _proto.addtagmapper = function addtagmapper(_ref2) { var expression = _ref2.expression, map = _ref2.map; var mapfn = function mapfn(line) { if (expression.test(line)) { return map(line); } return line; }; this.tagmappers.push(mapfn); }; return parsestream; }(_videojs_vhs_utils_es_stream_js__webpack_imported_module_1__[/* default */ "a"]); var camelcase = function camelcase(str) { return str.tolowercase().replace(/-(\w)/g, function (a) { return a[1].touppercase(); }); }; var camelcasekeys = function camelcasekeys(attributes) { var result = {}; object.keys(attributes).foreach(function (key) { result[camelcase(key)] = attributes[key]; }); return result; }; // set server-control hold back based upon targetduration and parttargetduration // we need this helper because defaults are based upon targetduration and // parttargetduration being set, but they may not be if server-control appears before // target durations are set. var setholdback = function setholdback(manifest) { var servercontrol = manifest.servercontrol, targetduration = manifest.targetduration, parttargetduration = manifest.parttargetduration; if (!servercontrol) { return; } var tag = '#ext-x-server-control'; var hb = 'holdback'; var phb = 'partholdback'; var mintargetduration = targetduration && targetduration * 3; var minpartduration = parttargetduration && parttargetduration * 2; if (targetduration && !servercontrol.hasownproperty(hb)) { servercontrol[hb] = mintargetduration; this.trigger('info', { message: tag + " defaulting hold-back to targetduration * 3 (" + mintargetduration + ")." }); } if (mintargetduration && servercontrol[hb] < mintargetduration) { this.trigger('warn', { message: tag + " clamping hold-back (" + servercontrol[hb] + ") to targetduration * 3 (" + mintargetduration + ")" }); servercontrol[hb] = mintargetduration; } // default no part hold back to part target duration * 3 if (parttargetduration && !servercontrol.hasownproperty(phb)) { servercontrol[phb] = parttargetduration * 3; this.trigger('info', { message: tag + " defaulting part-hold-back to parttargetduration * 3 (" + servercontrol[phb] + ")." }); } // if part hold back is too small default it to part target duration * 2 if (parttargetduration && servercontrol[phb] < minpartduration) { this.trigger('warn', { message: tag + " clamping part-hold-back (" + servercontrol[phb] + ") to parttargetduration * 2 (" + minpartduration + ")." }); servercontrol[phb] = minpartduration; } }; /** * a parser for m3u8 files. the current interpretation of the input is * exposed as a property `manifest` on parser objects. it's just two lines to * create and parse a manifest once you have the contents available as a string: * * ```js * var parser = new m3u8.parser(); * parser.push(xhr.responsetext); * ``` * * new input can later be applied to update the manifest object by calling * `push` again. * * the parser attempts to create a usable manifest object even if the * underlying input is somewhat nonsensical. it emits `info` and `warning` * events during the parse if it encounters input that seems invalid or * requires some property of the manifest object to be defaulted. * * @class parser * @extends stream */ var parser = /*#__pure__*/function (_stream) { _babel_runtime_helpers_inheritsloose__webpack_imported_module_0___default()(parser, _stream); function parser() { var _this; _this = _stream.call(this) || this; _this.linestream = new linestream(); _this.parsestream = new parsestream(); _this.linestream.pipe(_this.parsestream); /* eslint-disable consistent-this */ var self = _babel_runtime_helpers_assertthisinitialized__webpack_imported_module_3___default()(_this); /* eslint-enable consistent-this */ var uris = []; var currenturi = {}; // if specified, the active ext-x-map definition var currentmap; // if specified, the active decryption key var _key; var hasparts = false; var noop = function noop() {}; var defaultmediagroups = { 'audio': {}, 'video': {}, 'closed-captions': {}, 'subtitles': {} }; // this is the widevine uuid from dash if iop. the same exact string is // used in mpds with widevine encrypted streams. var widevineuuid = 'urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed'; // group segments into numbered timelines delineated by discontinuities var currenttimeline = 0; // the manifest is empty until the parse stream begins delivering data _this.manifest = { allowcache: true, discontinuitystarts: [], segments: [] }; // keep track of the last seen segment's byte range end, as segments are not required // to provide the offset, in which case it defaults to the next byte after the // previous segment var lastbyterangeend = 0; // keep track of the last seen part's byte range end. var lastpartbyterangeend = 0; _this.on('end', function () { // only add preloadsegment if we don't yet have a uri for it. // and we actually have parts/preloadhints if (currenturi.uri || !currenturi.parts && !currenturi.preloadhints) { return; } if (!currenturi.map && currentmap) { currenturi.map = currentmap; } if (!currenturi.key && _key) { currenturi.key = _key; } if (!currenturi.timeline && typeof currenttimeline === 'number') { currenturi.timeline = currenttimeline; } _this.manifest.preloadsegment = currenturi; }); // update the manifest with the m3u8 entry from the parse stream _this.parsestream.on('data', function (entry) { var mediagroup; var rendition; ({ tag: function tag() { // switch based on the tag type (({ version: function version() { if (entry.version) { this.manifest.version = entry.version; } }, 'allow-cache': function allowcache() { this.manifest.allowcache = entry.allowed; if (!('allowed' in entry)) { this.trigger('info', { message: 'defaulting allowcache to yes' }); this.manifest.allowcache = true; } }, byterange: function byterange() { var byterange = {}; if ('length' in entry) { currenturi.byterange = byterange; byterange.length = entry.length; if (!('offset' in entry)) { /* * from the latest spec (as of this writing): * https://tools.ietf.org/html/draft-pantos-http-live-streaming-23#section-4.3.2.2 * * same text since ext-x-byterange's introduction in draft 7: * https://tools.ietf.org/html/draft-pantos-http-live-streaming-07#section-3.3.1) * * "if o [offset] is not present, the sub-range begins at the next byte * following the sub-range of the previous media segment." */ entry.offset = lastbyterangeend; } } if ('offset' in entry) { currenturi.byterange = byterange; byterange.offset = entry.offset; } lastbyterangeend = byterange.offset + byterange.length; }, endlist: function endlist() { this.manifest.endlist = true; }, inf: function inf() { if (!('mediasequence' in this.manifest)) { this.manifest.mediasequence = 0; this.trigger('info', { message: 'defaulting media sequence to zero' }); } if (!('discontinuitysequence' in this.manifest)) { this.manifest.discontinuitysequence = 0; this.trigger('info', { message: 'defaulting discontinuity sequence to zero' }); } if (entry.duration > 0) { currenturi.duration = entry.duration; } if (entry.duration === 0) { currenturi.duration = 0.01; this.trigger('info', { message: 'updating zero segment duration to a small value' }); } this.manifest.segments = uris; }, key: function key() { if (!entry.attributes) { this.trigger('warn', { message: 'ignoring key declaration without attribute list' }); return; } // clear the active encryption key if (entry.attributes.method === 'none') { _key = null; return; } if (!entry.attributes.uri) { this.trigger('warn', { message: 'ignoring key declaration without uri' }); return; } if (entry.attributes.keyformat === 'com.apple.streamingkeydelivery') { this.manifest.contentprotection = this.manifest.contentprotection || {}; // todo: add full support for this. this.manifest.contentprotection['com.apple.fps.1_0'] = { attributes: entry.attributes }; return; } if (entry.attributes.keyformat === 'com.microsoft.playready') { this.manifest.contentprotection = this.manifest.contentprotection || {}; // todo: add full support for this. this.manifest.contentprotection['com.microsoft.playready'] = { uri: entry.attributes.uri }; return; } // check if the content is encrypted for widevine // widevine/hls spec: https://storage.googleapis.com/wvdocs/widevine_drm_hls.pdf if (entry.attributes.keyformat === widevineuuid) { var valid_methods = ['sample-aes', 'sample-aes-ctr', 'sample-aes-cenc']; if (valid_methods.indexof(entry.attributes.method) === -1) { this.trigger('warn', { message: 'invalid key method provided for widevine' }); return; } if (entry.attributes.method === 'sample-aes-cenc') { this.trigger('warn', { message: 'sample-aes-cenc is deprecated, please use sample-aes-ctr instead' }); } if (entry.attributes.uri.substring(0, 23) !== 'data:text/plain;base64,') { this.trigger('warn', { message: 'invalid key uri provided for widevine' }); return; } if (!(entry.attributes.keyid && entry.attributes.keyid.substring(0, 2) === '0x')) { this.trigger('warn', { message: 'invalid key id provided for widevine' }); return; } // if widevine key attributes are valid, store them as `contentprotection` // on the manifest to emulate widevine tag structure in a dash mpd this.manifest.contentprotection = this.manifest.contentprotection || {}; this.manifest.contentprotection['com.widevine.alpha'] = { attributes: { schemeiduri: entry.attributes.keyformat, // remove '0x' from the key id string keyid: entry.attributes.keyid.substring(2) }, // decode the base64-encoded pssh box pssh: object(_videojs_vhs_utils_es_decode_b64_to_uint8_array_js__webpack_imported_module_4__[/* default */ "a"])(entry.attributes.uri.split(',')[1]) }; return; } if (!entry.attributes.method) { this.trigger('warn', { message: 'defaulting key method to aes-128' }); } // setup an encryption key for upcoming segments _key = { method: entry.attributes.method || 'aes-128', uri: entry.attributes.uri }; if (typeof entry.attributes.iv !== 'undefined') { _key.iv = entry.attributes.iv; } }, 'media-sequence': function mediasequence() { if (!isfinite(entry.number)) { this.trigger('warn', { message: 'ignoring invalid media sequence: ' + entry.number }); return; } this.manifest.mediasequence = entry.number; }, 'discontinuity-sequence': function discontinuitysequence() { if (!isfinite(entry.number)) { this.trigger('warn', { message: 'ignoring invalid discontinuity sequence: ' + entry.number }); return; } this.manifest.discontinuitysequence = entry.number; currenttimeline = entry.number; }, 'playlist-type': function playlisttype() { if (!/vod|event/.test(entry.playlisttype)) { this.trigger('warn', { message: 'ignoring unknown playlist type: ' + entry.playlist }); return; } this.manifest.playlisttype = entry.playlisttype; }, map: function map() { currentmap = {}; if (entry.uri) { currentmap.uri = entry.uri; } if (entry.byterange) { currentmap.byterange = entry.byterange; } if (_key) { currentmap.key = _key; } }, 'stream-inf': function streaminf() { this.manifest.playlists = uris; this.manifest.mediagroups = this.manifest.mediagroups || defaultmediagroups; if (!entry.attributes) { this.trigger('warn', { message: 'ignoring empty stream-inf attributes' }); return; } if (!currenturi.attributes) { currenturi.attributes = {}; } _babel_runtime_helpers_extends__webpack_imported_module_2___default()(currenturi.attributes, entry.attributes); }, media: function media() { this.manifest.mediagroups = this.manifest.mediagroups || defaultmediagroups; if (!(entry.attributes && entry.attributes.type && entry.attributes['group-id'] && entry.attributes.name)) { this.trigger('warn', { message: 'ignoring incomplete or missing media group' }); return; } // find the media group, creating defaults as necessary var mediagrouptype = this.manifest.mediagroups[entry.attributes.type]; mediagrouptype[entry.attributes['group-id']] = mediagrouptype[entry.attributes['group-id']] || {}; mediagroup = mediagrouptype[entry.attributes['group-id']]; // collect the rendition metadata rendition = { default: /yes/i.test(entry.attributes.default) }; if (rendition.default) { rendition.autoselect = true; } else { rendition.autoselect = /yes/i.test(entry.attributes.autoselect); } if (entry.attributes.language) { rendition.language = entry.attributes.language; } if (entry.attributes.uri) { rendition.uri = entry.attributes.uri; } if (entry.attributes['instream-id']) { rendition.instreamid = entry.attributes['instream-id']; } if (entry.attributes.characteristics) { rendition.characteristics = entry.attributes.characteristics; } if (entry.attributes.forced) { rendition.forced = /yes/i.test(entry.attributes.forced); } // insert the new rendition mediagroup[entry.attributes.name] = rendition; }, discontinuity: function discontinuity() { currenttimeline += 1; currenturi.discontinuity = true; this.manifest.discontinuitystarts.push(uris.length); }, 'program-date-time': function programdatetime() { if (typeof this.manifest.datetimestring === 'undefined') { // program-date-time is a media-segment tag, but for backwards // compatibility, we add the first occurence of the program-date-time tag // to the manifest object // todo: consider removing this in future major version this.manifest.datetimestring = entry.datetimestring; this.manifest.datetimeobject = entry.datetimeobject; } currenturi.datetimestring = entry.datetimestring; currenturi.datetimeobject = entry.datetimeobject; }, targetduration: function targetduration() { if (!isfinite(entry.duration) || entry.duration < 0) { this.trigger('warn', { message: 'ignoring invalid target duration: ' + entry.duration }); return; } this.manifest.targetduration = entry.duration; setholdback.call(this, this.manifest); }, start: function start() { if (!entry.attributes || isnan(entry.attributes['time-offset'])) { this.trigger('warn', { message: 'ignoring start declaration without appropriate attribute list' }); return; } this.manifest.start = { timeoffset: entry.attributes['time-offset'], precise: entry.attributes.precise }; }, 'cue-out': function cueout() { currenturi.cueout = entry.data; }, 'cue-out-cont': function cueoutcont() { currenturi.cueoutcont = entry.data; }, 'cue-in': function cuein() { currenturi.cuein = entry.data; }, 'skip': function skip() { this.manifest.skip = camelcasekeys(entry.attributes); this.warnonmissingattributes_('#ext-x-skip', entry.attributes, ['skipped-segments']); }, 'part': function part() { var _this2 = this; hasparts = true; // parts are always specifed before a segment var segmentindex = this.manifest.segments.length; var part = camelcasekeys(entry.attributes); currenturi.parts = currenturi.parts || []; currenturi.parts.push(part); if (part.byterange) { if (!part.byterange.hasownproperty('offset')) { part.byterange.offset = lastpartbyterangeend; } lastpartbyterangeend = part.byterange.offset + part.byterange.length; } var partindex = currenturi.parts.length - 1; this.warnonmissingattributes_("#ext-x-part #" + partindex + " for segment #" + segmentindex, entry.attributes, ['uri', 'duration']); if (this.manifest.renditionreports) { this.manifest.renditionreports.foreach(function (r, i) { if (!r.hasownproperty('lastpart')) { _this2.trigger('warn', { message: "#ext-x-rendition-report #" + i + " lacks required attribute(s): last-part" }); } }); } }, 'server-control': function servercontrol() { var attrs = this.manifest.servercontrol = camelcasekeys(entry.attributes); if (!attrs.hasownproperty('canblockreload')) { attrs.canblockreload = false; this.trigger('info', { message: '#ext-x-server-control defaulting can-block-reload to false' }); } setholdback.call(this, this.manifest); if (attrs.canskipdateranges && !attrs.hasownproperty('canskipuntil')) { this.trigger('warn', { message: '#ext-x-server-control lacks required attribute can-skip-until which is required when can-skip-dateranges is set' }); } }, 'preload-hint': function preloadhint() { // parts are always specifed before a segment var segmentindex = this.manifest.segments.length; var hint = camelcasekeys(entry.attributes); var ispart = hint.type && hint.type === 'part'; currenturi.preloadhints = currenturi.preloadhints || []; currenturi.preloadhints.push(hint); if (hint.byterange) { if (!hint.byterange.hasownproperty('offset')) { // use last part byterange end or zero if not a part. hint.byterange.offset = ispart ? lastpartbyterangeend : 0; if (ispart) { lastpartbyterangeend = hint.byterange.offset + hint.byterange.length; } } } var index = currenturi.preloadhints.length - 1; this.warnonmissingattributes_("#ext-x-preload-hint #" + index + " for segment #" + segmentindex, entry.attributes, ['type', 'uri']); if (!hint.type) { return; } // search through all preload hints except for the current one for // a duplicate type. for (var i = 0; i < currenturi.preloadhints.length - 1; i++) { var otherhint = currenturi.preloadhints[i]; if (!otherhint.type) { continue; } if (otherhint.type === hint.type) { this.trigger('warn', { message: "#ext-x-preload-hint #" + index + " for segment #" + segmentindex + " has the same type " + hint.type + " as preload hint #" + i }); } } }, 'rendition-report': function renditionreport() { var report = camelcasekeys(entry.attributes); this.manifest.renditionreports = this.manifest.renditionreports || []; this.manifest.renditionreports.push(report); var index = this.manifest.renditionreports.length - 1; var required = ['last-msn', 'uri']; if (hasparts) { required.push('last-part'); } this.warnonmissingattributes_("#ext-x-rendition-report #" + index, entry.attributes, required); }, 'part-inf': function partinf() { this.manifest.partinf = camelcasekeys(entry.attributes); this.warnonmissingattributes_('#ext-x-part-inf', entry.attributes, ['part-target']); if (this.manifest.partinf.parttarget) { this.manifest.parttargetduration = this.manifest.partinf.parttarget; } setholdback.call(this, this.manifest); } })[entry.tagtype] || noop).call(self); }, uri: function uri() { currenturi.uri = entry.uri; uris.push(currenturi); // if no explicit duration was declared, use the target duration if (this.manifest.targetduration && !('duration' in currenturi)) { this.trigger('warn', { message: 'defaulting segment duration to the target duration' }); currenturi.duration = this.manifest.targetduration; } // annotate with encryption information, if necessary if (_key) { currenturi.key = _key; } currenturi.timeline = currenttimeline; // annotate with initialization segment information, if necessary if (currentmap) { currenturi.map = currentmap; } // reset the last byterange end as it needs to be 0 between parts lastpartbyterangeend = 0; // prepare for the next uri currenturi = {}; }, comment: function comment() {// comments are not important for playback }, custom: function custom() { // if this is segment-level data attach the output to the segment if (entry.segment) { currenturi.custom = currenturi.custom || {}; currenturi.custom[entry.customtype] = entry.data; // if this is manifest-level data attach to the top level manifest object } else { this.manifest.custom = this.manifest.custom || {}; this.manifest.custom[entry.customtype] = entry.data; } } })[entry.type].call(self); }); return _this; } var _proto = parser.prototype; _proto.warnonmissingattributes_ = function warnonmissingattributes_(identifier, attributes, required) { var missing = []; required.foreach(function (key) { if (!attributes.hasownproperty(key)) { missing.push(key); } }); if (missing.length) { this.trigger('warn', { message: identifier + " lacks required attribute(s): " + missing.join(', ') }); } } /** * parse the input string and update the manifest object. * * @param {string} chunk a potentially incomplete portion of the manifest */ ; _proto.push = function push(chunk) { this.linestream.push(chunk); } /** * flush any remaining input. this can be handy if the last line of an m3u8 * manifest did not contain a trailing newline but the file has been * completely received. */ ; _proto.end = function end() { // flush any buffered input this.linestream.push('\n'); this.trigger('end'); } /** * add an additional parser for non-standard tags * * @param {object} options a map of options for the added parser * @param {regexp} options.expression a regular expression to match the custom header * @param {string} options.type the type to register to the output * @param {function} [options.dataparser] function to parse the line into an object * @param {boolean} [options.segment] should tag data be attached to the segment object */ ; _proto.addparser = function addparser(options) { this.parsestream.addparser(options); } /** * add a custom header mapper * * @param {object} options * @param {regexp} options.expression a regular expression to match the custom header * @param {function} options.map function to translate tag into a different tag */ ; _proto.addtagmapper = function addtagmapper(options) { this.parsestream.addtagmapper(options); }; return parser; }(_videojs_vhs_utils_es_stream_js__webpack_imported_module_1__[/* default */ "a"]); /***/ }), /***/ 271: /***/ (function(module, exports, __webpack_require__) { var getuint64 = __webpack_require__(421).getuint64; var parsesidx = function(data) { var view = new dataview(data.buffer, data.byteoffset, data.bytelength), result = { version: data[0], flags: new uint8array(data.subarray(1, 4)), references: [], referenceid: view.getuint32(4), timescale: view.getuint32(8) }, i = 12; if (result.version === 0) { result.earliestpresentationtime = view.getuint32(i); result.firstoffset = view.getuint32(i + 4); i += 8; } else { // read 64 bits result.earliestpresentationtime = getuint64(data.subarray(i)); result.firstoffset = getuint64(data.subarray(i + 8)); i += 16; } i += 2; // reserved var referencecount = view.getuint16(i); i += 2; // start of references for (; referencecount > 0; i += 12, referencecount--) { result.references.push({ referencetype: (data[i] & 0x80) >>> 7, referencedsize: view.getuint32(i) & 0x7fffffff, subsegmentduration: view.getuint32(i + 4), startswithsap: !!(data[i + 8] & 0x80), saptype: (data[i + 8] & 0x70) >>> 4, sapdeltatime: view.getuint32(i + 8) & 0x0fffffff }); } return result; }; module.exports = parsesidx; /***/ }), /***/ 274: /***/ (function(module, exports, __webpack_require__) { /* webpack var injection */(function(process, global) {var __webpack_amd_define_result__;/** * [js-md5]{@link https://github.com/emn178/js-md5} * * @namespace md5 * @version 0.7.3 * @author chen, yi-cyuan [emn178@gmail.com] * @copyright chen, yi-cyuan 2014-2017 * @license mit */ (function () { 'use strict'; var error = 'input is invalid type'; var window = typeof window === 'object'; var root = window ? window : {}; if (root.js_md5_no_window) { window = false; } var web_worker = !window && typeof self === 'object'; var node_js = !root.js_md5_no_node_js && typeof process === 'object' && process.versions && process.versions.node; if (node_js) { root = global; } else if (web_worker) { root = self; } var common_js = !root.js_md5_no_common_js && typeof module === 'object' && module.exports; var amd = true && __webpack_require__(442); var array_buffer = !root.js_md5_no_array_buffer && typeof arraybuffer !== 'undefined'; var hex_chars = '0123456789abcdef'.split(''); var extra = [128, 32768, 8388608, -2147483648]; var shift = [0, 8, 16, 24]; var output_types = ['hex', 'array', 'digest', 'buffer', 'arraybuffer', 'base64']; var base64_encode_char = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); var blocks = [], buffer8; if (array_buffer) { var buffer = new arraybuffer(68); buffer8 = new uint8array(buffer); blocks = new uint32array(buffer); } if (root.js_md5_no_node_js || !array.isarray) { array.isarray = function (obj) { return object.prototype.tostring.call(obj) === '[object array]'; }; } if (array_buffer && (root.js_md5_no_array_buffer_is_view || !arraybuffer.isview)) { arraybuffer.isview = function (obj) { return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === arraybuffer; }; } /** * @method hex * @memberof md5 * @description output hash as hex string * @param {string|array|uint8array|arraybuffer} message message to hash * @returns {string} hex string * @example * md5.hex('the quick brown fox jumps over the lazy dog'); * // equal to * md5('the quick brown fox jumps over the lazy dog'); */ /** * @method digest * @memberof md5 * @description output hash as bytes array * @param {string|array|uint8array|arraybuffer} message message to hash * @returns {array} bytes array * @example * md5.digest('the quick brown fox jumps over the lazy dog'); */ /** * @method array * @memberof md5 * @description output hash as bytes array * @param {string|array|uint8array|arraybuffer} message message to hash * @returns {array} bytes array * @example * md5.array('the quick brown fox jumps over the lazy dog'); */ /** * @method arraybuffer * @memberof md5 * @description output hash as arraybuffer * @param {string|array|uint8array|arraybuffer} message message to hash * @returns {arraybuffer} arraybuffer * @example * md5.arraybuffer('the quick brown fox jumps over the lazy dog'); */ /** * @method buffer * @deprecated this maybe confuse with buffer in node.js. please use arraybuffer instead. * @memberof md5 * @description output hash as arraybuffer * @param {string|array|uint8array|arraybuffer} message message to hash * @returns {arraybuffer} arraybuffer * @example * md5.buffer('the quick brown fox jumps over the lazy dog'); */ /** * @method base64 * @memberof md5 * @description output hash as base64 string * @param {string|array|uint8array|arraybuffer} message message to hash * @returns {string} base64 string * @example * md5.base64('the quick brown fox jumps over the lazy dog'); */ var createoutputmethod = function (outputtype) { return function (message) { return new md5(true).update(message)[outputtype](); }; }; /** * @method create * @memberof md5 * @description create md5 object * @returns {md5} md5 object. * @example * var hash = md5.create(); */ /** * @method update * @memberof md5 * @description create and update md5 object * @param {string|array|uint8array|arraybuffer} message message to hash * @returns {md5} md5 object. * @example * var hash = md5.update('the quick brown fox jumps over the lazy dog'); * // equal to * var hash = md5.create(); * hash.update('the quick brown fox jumps over the lazy dog'); */ var createmethod = function () { var method = createoutputmethod('hex'); if (node_js) { method = nodewrap(method); } method.create = function () { return new md5(); }; method.update = function (message) { return method.create().update(message); }; for (var i = 0; i < output_types.length; ++i) { var type = output_types[i]; method[type] = createoutputmethod(type); } return method; }; var nodewrap = function (method) { var crypto = eval("require('crypto')"); var buffer = eval("require('buffer').buffer"); var nodemethod = function (message) { if (typeof message === 'string') { return crypto.createhash('md5').update(message, 'utf8').digest('hex'); } else { if (message === null || message === undefined) { throw error; } else if (message.constructor === arraybuffer) { message = new uint8array(message); } } if (array.isarray(message) || arraybuffer.isview(message) || message.constructor === buffer) { return crypto.createhash('md5').update(new buffer(message)).digest('hex'); } else { return method(message); } }; return nodemethod; }; /** * md5 class * @class md5 * @description this is internal class. * @see {@link md5.create} */ function md5(sharedmemory) { if (sharedmemory) { blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; this.blocks = blocks; this.buffer8 = buffer8; } else { if (array_buffer) { var buffer = new arraybuffer(68); this.buffer8 = new uint8array(buffer); this.blocks = new uint32array(buffer); } else { this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; } } this.h0 = this.h1 = this.h2 = this.h3 = this.start = this.bytes = this.hbytes = 0; this.finalized = this.hashed = false; this.first = true; } /** * @method update * @memberof md5 * @instance * @description update hash * @param {string|array|uint8array|arraybuffer} message message to hash * @returns {md5} md5 object. * @see {@link md5.update} */ md5.prototype.update = function (message) { if (this.finalized) { return; } var notstring, type = typeof message; if (type !== 'string') { if (type === 'object') { if (message === null) { throw error; } else if (array_buffer && message.constructor === arraybuffer) { message = new uint8array(message); } else if (!array.isarray(message)) { if (!array_buffer || !arraybuffer.isview(message)) { throw error; } } } else { throw error; } notstring = true; } var code, index = 0, i, length = message.length, blocks = this.blocks; var buffer8 = this.buffer8; while (index < length) { if (this.hashed) { this.hashed = false; blocks[0] = blocks[16]; blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; } if (notstring) { if (array_buffer) { for (i = this.start; index < length && i < 64; ++index) { buffer8[i++] = message[index]; } } else { for (i = this.start; index < length && i < 64; ++index) { blocks[i >> 2] |= message[index] << shift[i++ & 3]; } } } else { if (array_buffer) { for (i = this.start; index < length && i < 64; ++index) { code = message.charcodeat(index); if (code < 0x80) { buffer8[i++] = code; } else if (code < 0x800) { buffer8[i++] = 0xc0 | (code >> 6); buffer8[i++] = 0x80 | (code & 0x3f); } else if (code < 0xd800 || code >= 0xe000) { buffer8[i++] = 0xe0 | (code >> 12); buffer8[i++] = 0x80 | ((code >> 6) & 0x3f); buffer8[i++] = 0x80 | (code & 0x3f); } else { code = 0x10000 + (((code & 0x3ff) << 10) | (message.charcodeat(++index) & 0x3ff)); buffer8[i++] = 0xf0 | (code >> 18); buffer8[i++] = 0x80 | ((code >> 12) & 0x3f); buffer8[i++] = 0x80 | ((code >> 6) & 0x3f); buffer8[i++] = 0x80 | (code & 0x3f); } } } else { for (i = this.start; index < length && i < 64; ++index) { code = message.charcodeat(index); if (code < 0x80) { blocks[i >> 2] |= code << shift[i++ & 3]; } else if (code < 0x800) { blocks[i >> 2] |= (0xc0 | (code >> 6)) << shift[i++ & 3]; blocks[i >> 2] |= (0x80 | (code & 0x3f)) << shift[i++ & 3]; } else if (code < 0xd800 || code >= 0xe000) { blocks[i >> 2] |= (0xe0 | (code >> 12)) << shift[i++ & 3]; blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << shift[i++ & 3]; blocks[i >> 2] |= (0x80 | (code & 0x3f)) << shift[i++ & 3]; } else { code = 0x10000 + (((code & 0x3ff) << 10) | (message.charcodeat(++index) & 0x3ff)); blocks[i >> 2] |= (0xf0 | (code >> 18)) << shift[i++ & 3]; blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << shift[i++ & 3]; blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << shift[i++ & 3]; blocks[i >> 2] |= (0x80 | (code & 0x3f)) << shift[i++ & 3]; } } } } this.lastbyteindex = i; this.bytes += i - this.start; if (i >= 64) { this.start = i - 64; this.hash(); this.hashed = true; } else { this.start = i; } } if (this.bytes > 4294967295) { this.hbytes += this.bytes / 4294967296 << 0; this.bytes = this.bytes % 4294967296; } return this; }; md5.prototype.finalize = function () { if (this.finalized) { return; } this.finalized = true; var blocks = this.blocks, i = this.lastbyteindex; blocks[i >> 2] |= extra[i & 3]; if (i >= 56) { if (!this.hashed) { this.hash(); } blocks[0] = blocks[16]; blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; } blocks[14] = this.bytes << 3; blocks[15] = this.hbytes << 3 | this.bytes >>> 29; this.hash(); }; md5.prototype.hash = function () { var a, b, c, d, bc, da, blocks = this.blocks; if (this.first) { a = blocks[0] - 680876937; a = (a << 7 | a >>> 25) - 271733879 << 0; d = (-1732584194 ^ a & 2004318071) + blocks[1] - 117830708; d = (d << 12 | d >>> 20) + a << 0; c = (-271733879 ^ (d & (a ^ -271733879))) + blocks[2] - 1126478375; c = (c << 17 | c >>> 15) + d << 0; b = (a ^ (c & (d ^ a))) + blocks[3] - 1316259209; b = (b << 22 | b >>> 10) + c << 0; } else { a = this.h0; b = this.h1; c = this.h2; d = this.h3; a += (d ^ (b & (c ^ d))) + blocks[0] - 680876936; a = (a << 7 | a >>> 25) + b << 0; d += (c ^ (a & (b ^ c))) + blocks[1] - 389564586; d = (d << 12 | d >>> 20) + a << 0; c += (b ^ (d & (a ^ b))) + blocks[2] + 606105819; c = (c << 17 | c >>> 15) + d << 0; b += (a ^ (c & (d ^ a))) + blocks[3] - 1044525330; b = (b << 22 | b >>> 10) + c << 0; } a += (d ^ (b & (c ^ d))) + blocks[4] - 176418897; a = (a << 7 | a >>> 25) + b << 0; d += (c ^ (a & (b ^ c))) + blocks[5] + 1200080426; d = (d << 12 | d >>> 20) + a << 0; c += (b ^ (d & (a ^ b))) + blocks[6] - 1473231341; c = (c << 17 | c >>> 15) + d << 0; b += (a ^ (c & (d ^ a))) + blocks[7] - 45705983; b = (b << 22 | b >>> 10) + c << 0; a += (d ^ (b & (c ^ d))) + blocks[8] + 1770035416; a = (a << 7 | a >>> 25) + b << 0; d += (c ^ (a & (b ^ c))) + blocks[9] - 1958414417; d = (d << 12 | d >>> 20) + a << 0; c += (b ^ (d & (a ^ b))) + blocks[10] - 42063; c = (c << 17 | c >>> 15) + d << 0; b += (a ^ (c & (d ^ a))) + blocks[11] - 1990404162; b = (b << 22 | b >>> 10) + c << 0; a += (d ^ (b & (c ^ d))) + blocks[12] + 1804603682; a = (a << 7 | a >>> 25) + b << 0; d += (c ^ (a & (b ^ c))) + blocks[13] - 40341101; d = (d << 12 | d >>> 20) + a << 0; c += (b ^ (d & (a ^ b))) + blocks[14] - 1502002290; c = (c << 17 | c >>> 15) + d << 0; b += (a ^ (c & (d ^ a))) + blocks[15] + 1236535329; b = (b << 22 | b >>> 10) + c << 0; a += (c ^ (d & (b ^ c))) + blocks[1] - 165796510; a = (a << 5 | a >>> 27) + b << 0; d += (b ^ (c & (a ^ b))) + blocks[6] - 1069501632; d = (d << 9 | d >>> 23) + a << 0; c += (a ^ (b & (d ^ a))) + blocks[11] + 643717713; c = (c << 14 | c >>> 18) + d << 0; b += (d ^ (a & (c ^ d))) + blocks[0] - 373897302; b = (b << 20 | b >>> 12) + c << 0; a += (c ^ (d & (b ^ c))) + blocks[5] - 701558691; a = (a << 5 | a >>> 27) + b << 0; d += (b ^ (c & (a ^ b))) + blocks[10] + 38016083; d = (d << 9 | d >>> 23) + a << 0; c += (a ^ (b & (d ^ a))) + blocks[15] - 660478335; c = (c << 14 | c >>> 18) + d << 0; b += (d ^ (a & (c ^ d))) + blocks[4] - 405537848; b = (b << 20 | b >>> 12) + c << 0; a += (c ^ (d & (b ^ c))) + blocks[9] + 568446438; a = (a << 5 | a >>> 27) + b << 0; d += (b ^ (c & (a ^ b))) + blocks[14] - 1019803690; d = (d << 9 | d >>> 23) + a << 0; c += (a ^ (b & (d ^ a))) + blocks[3] - 187363961; c = (c << 14 | c >>> 18) + d << 0; b += (d ^ (a & (c ^ d))) + blocks[8] + 1163531501; b = (b << 20 | b >>> 12) + c << 0; a += (c ^ (d & (b ^ c))) + blocks[13] - 1444681467; a = (a << 5 | a >>> 27) + b << 0; d += (b ^ (c & (a ^ b))) + blocks[2] - 51403784; d = (d << 9 | d >>> 23) + a << 0; c += (a ^ (b & (d ^ a))) + blocks[7] + 1735328473; c = (c << 14 | c >>> 18) + d << 0; b += (d ^ (a & (c ^ d))) + blocks[12] - 1926607734; b = (b << 20 | b >>> 12) + c << 0; bc = b ^ c; a += (bc ^ d) + blocks[5] - 378558; a = (a << 4 | a >>> 28) + b << 0; d += (bc ^ a) + blocks[8] - 2022574463; d = (d << 11 | d >>> 21) + a << 0; da = d ^ a; c += (da ^ b) + blocks[11] + 1839030562; c = (c << 16 | c >>> 16) + d << 0; b += (da ^ c) + blocks[14] - 35309556; b = (b << 23 | b >>> 9) + c << 0; bc = b ^ c; a += (bc ^ d) + blocks[1] - 1530992060; a = (a << 4 | a >>> 28) + b << 0; d += (bc ^ a) + blocks[4] + 1272893353; d = (d << 11 | d >>> 21) + a << 0; da = d ^ a; c += (da ^ b) + blocks[7] - 155497632; c = (c << 16 | c >>> 16) + d << 0; b += (da ^ c) + blocks[10] - 1094730640; b = (b << 23 | b >>> 9) + c << 0; bc = b ^ c; a += (bc ^ d) + blocks[13] + 681279174; a = (a << 4 | a >>> 28) + b << 0; d += (bc ^ a) + blocks[0] - 358537222; d = (d << 11 | d >>> 21) + a << 0; da = d ^ a; c += (da ^ b) + blocks[3] - 722521979; c = (c << 16 | c >>> 16) + d << 0; b += (da ^ c) + blocks[6] + 76029189; b = (b << 23 | b >>> 9) + c << 0; bc = b ^ c; a += (bc ^ d) + blocks[9] - 640364487; a = (a << 4 | a >>> 28) + b << 0; d += (bc ^ a) + blocks[12] - 421815835; d = (d << 11 | d >>> 21) + a << 0; da = d ^ a; c += (da ^ b) + blocks[15] + 530742520; c = (c << 16 | c >>> 16) + d << 0; b += (da ^ c) + blocks[2] - 995338651; b = (b << 23 | b >>> 9) + c << 0; a += (c ^ (b | ~d)) + blocks[0] - 198630844; a = (a << 6 | a >>> 26) + b << 0; d += (b ^ (a | ~c)) + blocks[7] + 1126891415; d = (d << 10 | d >>> 22) + a << 0; c += (a ^ (d | ~b)) + blocks[14] - 1416354905; c = (c << 15 | c >>> 17) + d << 0; b += (d ^ (c | ~a)) + blocks[5] - 57434055; b = (b << 21 | b >>> 11) + c << 0; a += (c ^ (b | ~d)) + blocks[12] + 1700485571; a = (a << 6 | a >>> 26) + b << 0; d += (b ^ (a | ~c)) + blocks[3] - 1894986606; d = (d << 10 | d >>> 22) + a << 0; c += (a ^ (d | ~b)) + blocks[10] - 1051523; c = (c << 15 | c >>> 17) + d << 0; b += (d ^ (c | ~a)) + blocks[1] - 2054922799; b = (b << 21 | b >>> 11) + c << 0; a += (c ^ (b | ~d)) + blocks[8] + 1873313359; a = (a << 6 | a >>> 26) + b << 0; d += (b ^ (a | ~c)) + blocks[15] - 30611744; d = (d << 10 | d >>> 22) + a << 0; c += (a ^ (d | ~b)) + blocks[6] - 1560198380; c = (c << 15 | c >>> 17) + d << 0; b += (d ^ (c | ~a)) + blocks[13] + 1309151649; b = (b << 21 | b >>> 11) + c << 0; a += (c ^ (b | ~d)) + blocks[4] - 145523070; a = (a << 6 | a >>> 26) + b << 0; d += (b ^ (a | ~c)) + blocks[11] - 1120210379; d = (d << 10 | d >>> 22) + a << 0; c += (a ^ (d | ~b)) + blocks[2] + 718787259; c = (c << 15 | c >>> 17) + d << 0; b += (d ^ (c | ~a)) + blocks[9] - 343485551; b = (b << 21 | b >>> 11) + c << 0; if (this.first) { this.h0 = a + 1732584193 << 0; this.h1 = b - 271733879 << 0; this.h2 = c - 1732584194 << 0; this.h3 = d + 271733878 << 0; this.first = false; } else { this.h0 = this.h0 + a << 0; this.h1 = this.h1 + b << 0; this.h2 = this.h2 + c << 0; this.h3 = this.h3 + d << 0; } }; /** * @method hex * @memberof md5 * @instance * @description output hash as hex string * @returns {string} hex string * @see {@link md5.hex} * @example * hash.hex(); */ md5.prototype.hex = function () { this.finalize(); var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3; return hex_chars[(h0 >> 4) & 0x0f] + hex_chars[h0 & 0x0f] + hex_chars[(h0 >> 12) & 0x0f] + hex_chars[(h0 >> 8) & 0x0f] + hex_chars[(h0 >> 20) & 0x0f] + hex_chars[(h0 >> 16) & 0x0f] + hex_chars[(h0 >> 28) & 0x0f] + hex_chars[(h0 >> 24) & 0x0f] + hex_chars[(h1 >> 4) & 0x0f] + hex_chars[h1 & 0x0f] + hex_chars[(h1 >> 12) & 0x0f] + hex_chars[(h1 >> 8) & 0x0f] + hex_chars[(h1 >> 20) & 0x0f] + hex_chars[(h1 >> 16) & 0x0f] + hex_chars[(h1 >> 28) & 0x0f] + hex_chars[(h1 >> 24) & 0x0f] + hex_chars[(h2 >> 4) & 0x0f] + hex_chars[h2 & 0x0f] + hex_chars[(h2 >> 12) & 0x0f] + hex_chars[(h2 >> 8) & 0x0f] + hex_chars[(h2 >> 20) & 0x0f] + hex_chars[(h2 >> 16) & 0x0f] + hex_chars[(h2 >> 28) & 0x0f] + hex_chars[(h2 >> 24) & 0x0f] + hex_chars[(h3 >> 4) & 0x0f] + hex_chars[h3 & 0x0f] + hex_chars[(h3 >> 12) & 0x0f] + hex_chars[(h3 >> 8) & 0x0f] + hex_chars[(h3 >> 20) & 0x0f] + hex_chars[(h3 >> 16) & 0x0f] + hex_chars[(h3 >> 28) & 0x0f] + hex_chars[(h3 >> 24) & 0x0f]; }; /** * @method tostring * @memberof md5 * @instance * @description output hash as hex string * @returns {string} hex string * @see {@link md5.hex} * @example * hash.tostring(); */ md5.prototype.tostring = md5.prototype.hex; /** * @method digest * @memberof md5 * @instance * @description output hash as bytes array * @returns {array} bytes array * @see {@link md5.digest} * @example * hash.digest(); */ md5.prototype.digest = function () { this.finalize(); var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3; return [ h0 & 0xff, (h0 >> 8) & 0xff, (h0 >> 16) & 0xff, (h0 >> 24) & 0xff, h1 & 0xff, (h1 >> 8) & 0xff, (h1 >> 16) & 0xff, (h1 >> 24) & 0xff, h2 & 0xff, (h2 >> 8) & 0xff, (h2 >> 16) & 0xff, (h2 >> 24) & 0xff, h3 & 0xff, (h3 >> 8) & 0xff, (h3 >> 16) & 0xff, (h3 >> 24) & 0xff ]; }; /** * @method array * @memberof md5 * @instance * @description output hash as bytes array * @returns {array} bytes array * @see {@link md5.array} * @example * hash.array(); */ md5.prototype.array = md5.prototype.digest; /** * @method arraybuffer * @memberof md5 * @instance * @description output hash as arraybuffer * @returns {arraybuffer} arraybuffer * @see {@link md5.arraybuffer} * @example * hash.arraybuffer(); */ md5.prototype.arraybuffer = function () { this.finalize(); var buffer = new arraybuffer(16); var blocks = new uint32array(buffer); blocks[0] = this.h0; blocks[1] = this.h1; blocks[2] = this.h2; blocks[3] = this.h3; return buffer; }; /** * @method buffer * @deprecated this maybe confuse with buffer in node.js. please use arraybuffer instead. * @memberof md5 * @instance * @description output hash as arraybuffer * @returns {arraybuffer} arraybuffer * @see {@link md5.buffer} * @example * hash.buffer(); */ md5.prototype.buffer = md5.prototype.arraybuffer; /** * @method base64 * @memberof md5 * @instance * @description output hash as base64 string * @returns {string} base64 string * @see {@link md5.base64} * @example * hash.base64(); */ md5.prototype.base64 = function () { var v1, v2, v3, base64str = '', bytes = this.array(); for (var i = 0; i < 15;) { v1 = bytes[i++]; v2 = bytes[i++]; v3 = bytes[i++]; base64str += base64_encode_char[v1 >>> 2] + base64_encode_char[(v1 << 4 | v2 >>> 4) & 63] + base64_encode_char[(v2 << 2 | v3 >>> 6) & 63] + base64_encode_char[v3 & 63]; } v1 = bytes[i]; base64str += base64_encode_char[v1 >>> 2] + base64_encode_char[(v1 << 4) & 63] + '=='; return base64str; }; var exports = createmethod(); if (common_js) { module.exports = exports; } else { /** * @method md5 * @description md5 hash function, export to global in browsers. * @param {string|array|uint8array|arraybuffer} message message to hash * @returns {string} md5 hashes * @example * md5(''); // d41d8cd98f00b204e9800998ecf8427e * md5('the quick brown fox jumps over the lazy dog'); // 9e107d9d372bb6826bd81d3542a419d6 * md5('the quick brown fox jumps over the lazy dog.'); // e4d909c290d0fb1ca068ffaddf22cbd0 * * // it also supports utf-8 encoding * md5('中文'); // a7bac2239fcdcb3a067903d8077c4a07 * * // it also supports byte `array`, `uint8array`, `arraybuffer` * md5([]); // d41d8cd98f00b204e9800998ecf8427e * md5(new uint8array([])); // d41d8cd98f00b204e9800998ecf8427e */ root.md5 = exports; if (amd) { !(__webpack_amd_define_result__ = (function () { return exports; }).call(exports, __webpack_require__, exports, module), __webpack_amd_define_result__ !== undefined && (module.exports = __webpack_amd_define_result__)); } } })(); /* webpack var injection */}.call(this, __webpack_require__(154), __webpack_require__(25))) /***/ }), /***/ 373: /***/ (function(module, exports, __webpack_require__) { var stack = __webpack_require__(374), arrayeach = __webpack_require__(380), assignvalue = __webpack_require__(248), baseassign = __webpack_require__(383), baseassignin = __webpack_require__(384), clonebuffer = __webpack_require__(385), copyarray = __webpack_require__(388), copysymbols = __webpack_require__(389), copysymbolsin = __webpack_require__(391), getallkeys = __webpack_require__(393), getallkeysin = __webpack_require__(394), gettag = __webpack_require__(395), initclonearray = __webpack_require__(396), initclonebytag = __webpack_require__(397), initcloneobject = __webpack_require__(398), isarray = __webpack_require__(402), isbuffer = __webpack_require__(403), ismap = __webpack_require__(404), isobject = __webpack_require__(253), isset = __webpack_require__(405), keys = __webpack_require__(250), keysin = __webpack_require__(251); /** used to compose bitmasks for cloning. */ var clone_deep_flag = 1, clone_flat_flag = 2, clone_symbols_flag = 4; /** `object#tostring` result references. */ var argstag = '[object arguments]', arraytag = '[object array]', booltag = '[object boolean]', datetag = '[object date]', errortag = '[object error]', functag = '[object function]', gentag = '[object generatorfunction]', maptag = '[object map]', numbertag = '[object number]', objecttag = '[object object]', regexptag = '[object regexp]', settag = '[object set]', stringtag = '[object string]', symboltag = '[object symbol]', weakmaptag = '[object weakmap]'; var arraybuffertag = '[object arraybuffer]', dataviewtag = '[object dataview]', float32tag = '[object float32array]', float64tag = '[object float64array]', int8tag = '[object int8array]', int16tag = '[object int16array]', int32tag = '[object int32array]', uint8tag = '[object uint8array]', uint8clampedtag = '[object uint8clampedarray]', uint16tag = '[object uint16array]', uint32tag = '[object uint32array]'; /** used to identify `tostringtag` values supported by `_.clone`. */ var cloneabletags = {}; cloneabletags[argstag] = cloneabletags[arraytag] = cloneabletags[arraybuffertag] = cloneabletags[dataviewtag] = cloneabletags[booltag] = cloneabletags[datetag] = cloneabletags[float32tag] = cloneabletags[float64tag] = cloneabletags[int8tag] = cloneabletags[int16tag] = cloneabletags[int32tag] = cloneabletags[maptag] = cloneabletags[numbertag] = cloneabletags[objecttag] = cloneabletags[regexptag] = cloneabletags[settag] = cloneabletags[stringtag] = cloneabletags[symboltag] = cloneabletags[uint8tag] = cloneabletags[uint8clampedtag] = cloneabletags[uint16tag] = cloneabletags[uint32tag] = true; cloneabletags[errortag] = cloneabletags[functag] = cloneabletags[weakmaptag] = false; /** * the base implementation of `_.clone` and `_.clonedeep` which tracks * traversed objects. * * @private * @param {*} value the value to clone. * @param {boolean} bitmask the bitmask flags. * 1 - deep clone * 2 - flatten inherited properties * 4 - clone symbols * @param {function} [customizer] the function to customize cloning. * @param {string} [key] the key of `value`. * @param {object} [object] the parent object of `value`. * @param {object} [stack] tracks traversed objects and their clone counterparts. * @returns {*} returns the cloned value. */ function baseclone(value, bitmask, customizer, key, object, stack) { var result, isdeep = bitmask & clone_deep_flag, isflat = bitmask & clone_flat_flag, isfull = bitmask & clone_symbols_flag; if (customizer) { result = object ? customizer(value, key, object, stack) : customizer(value); } if (result !== undefined) { return result; } if (!isobject(value)) { return value; } var isarr = isarray(value); if (isarr) { result = initclonearray(value); if (!isdeep) { return copyarray(value, result); } } else { var tag = gettag(value), isfunc = tag == functag || tag == gentag; if (isbuffer(value)) { return clonebuffer(value, isdeep); } if (tag == objecttag || tag == argstag || (isfunc && !object)) { result = (isflat || isfunc) ? {} : initcloneobject(value); if (!isdeep) { return isflat ? copysymbolsin(value, baseassignin(result, value)) : copysymbols(value, baseassign(result, value)); } } else { if (!cloneabletags[tag]) { return object ? value : {}; } result = initclonebytag(value, tag, isdeep); } } // check for circular references and return its corresponding clone. stack || (stack = new stack); var stacked = stack.get(value); if (stacked) { return stacked; } stack.set(value, result); if (isset(value)) { value.foreach(function(subvalue) { result.add(baseclone(subvalue, bitmask, customizer, subvalue, value, stack)); }); } else if (ismap(value)) { value.foreach(function(subvalue, key) { result.set(key, baseclone(subvalue, bitmask, customizer, key, value, stack)); }); } var keysfunc = isfull ? (isflat ? getallkeysin : getallkeys) : (isflat ? keysin : keys); var props = isarr ? undefined : keysfunc(value); arrayeach(props || value, function(subvalue, key) { if (props) { key = subvalue; subvalue = value[key]; } // recursively populate clone (susceptible to call stack limits). assignvalue(result, key, baseclone(subvalue, bitmask, customizer, key, value, stack)); }); return result; } module.exports = baseclone; /***/ }), /***/ 374: /***/ (function(module, exports, __webpack_require__) { var listcacheclear = __webpack_require__(375), listcachedelete = __webpack_require__(376), listcacheget = __webpack_require__(377), listcachehas = __webpack_require__(378), listcacheset = __webpack_require__(379); /** * creates an list cache object. * * @private * @constructor * @param {array} [entries] the key-value pairs to cache. */ function listcache(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } // add methods to `listcache`. listcache.prototype.clear = listcacheclear; listcache.prototype['delete'] = listcachedelete; listcache.prototype.get = listcacheget; listcache.prototype.has = listcachehas; listcache.prototype.set = listcacheset; module.exports = listcache; /***/ }), /***/ 375: /***/ (function(module, exports) { /** * removes all key-value entries from the list cache. * * @private * @name clear * @memberof listcache */ function listcacheclear() { this.__data__ = []; this.size = 0; } module.exports = listcacheclear; /***/ }), /***/ 376: /***/ (function(module, exports, __webpack_require__) { var associndexof = __webpack_require__(122); /** used for built-in method references. */ var arrayproto = array.prototype; /** built-in value references. */ var splice = arrayproto.splice; /** * removes `key` and its value from the list cache. * * @private * @name delete * @memberof listcache * @param {string} key the key of the value to remove. * @returns {boolean} returns `true` if the entry was removed, else `false`. */ function listcachedelete(key) { var data = this.__data__, index = associndexof(data, key); if (index < 0) { return false; } var lastindex = data.length - 1; if (index == lastindex) { data.pop(); } else { splice.call(data, index, 1); } --this.size; return true; } module.exports = listcachedelete; /***/ }), /***/ 377: /***/ (function(module, exports, __webpack_require__) { var associndexof = __webpack_require__(122); /** * gets the list cache value for `key`. * * @private * @name get * @memberof listcache * @param {string} key the key of the value to get. * @returns {*} returns the entry value. */ function listcacheget(key) { var data = this.__data__, index = associndexof(data, key); return index < 0 ? undefined : data[index][1]; } module.exports = listcacheget; /***/ }), /***/ 378: /***/ (function(module, exports, __webpack_require__) { var associndexof = __webpack_require__(122); /** * checks if a list cache value for `key` exists. * * @private * @name has * @memberof listcache * @param {string} key the key of the entry to check. * @returns {boolean} returns `true` if an entry for `key` exists, else `false`. */ function listcachehas(key) { return associndexof(this.__data__, key) > -1; } module.exports = listcachehas; /***/ }), /***/ 379: /***/ (function(module, exports, __webpack_require__) { var associndexof = __webpack_require__(122); /** * sets the list cache `key` to `value`. * * @private * @name set * @memberof listcache * @param {string} key the key of the value to set. * @param {*} value the value to set. * @returns {object} returns the list cache instance. */ function listcacheset(key, value) { var data = this.__data__, index = associndexof(data, key); if (index < 0) { ++this.size; data.push([key, value]); } else { data[index][1] = value; } return this; } module.exports = listcacheset; /***/ }), /***/ 380: /***/ (function(module, exports) { /** * a specialized version of `_.foreach` for arrays without support for * iteratee shorthands. * * @private * @param {array} [array] the array to iterate over. * @param {function} iteratee the function invoked per iteration. * @returns {array} returns `array`. */ function arrayeach(array, iteratee) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (iteratee(array[index], index, array) === false) { break; } } return array; } module.exports = arrayeach; /***/ }), /***/ 381: /***/ (function(module, exports, __webpack_require__) { var getnative = __webpack_require__(382); var defineproperty = (function() { try { var func = getnative(object, 'defineproperty'); func({}, '', {}); return func; } catch (e) {} }()); module.exports = defineproperty; /***/ }), /***/ 382: /***/ (function(module, exports) { /** * gets the value at `key` of `object`. * * @private * @param {object} [object] the object to query. * @param {string} key the key of the property to get. * @returns {*} returns the property value. */ function getvalue(object, key) { return object == null ? undefined : object[key]; } module.exports = getvalue; /***/ }), /***/ 383: /***/ (function(module, exports, __webpack_require__) { var copyobject = __webpack_require__(123), keys = __webpack_require__(250); /** * the base implementation of `_.assign` without support for multiple sources * or `customizer` functions. * * @private * @param {object} object the destination object. * @param {object} source the source object. * @returns {object} returns `object`. */ function baseassign(object, source) { return object && copyobject(source, keys(source), object); } module.exports = baseassign; /***/ }), /***/ 384: /***/ (function(module, exports, __webpack_require__) { var copyobject = __webpack_require__(123), keysin = __webpack_require__(251); /** * the base implementation of `_.assignin` without support for multiple sources * or `customizer` functions. * * @private * @param {object} object the destination object. * @param {object} source the source object. * @returns {object} returns `object`. */ function baseassignin(object, source) { return object && copyobject(source, keysin(source), object); } module.exports = baseassignin; /***/ }), /***/ 385: /***/ (function(module, exports, __webpack_require__) { /* webpack var injection */(function(module) {var root = __webpack_require__(386); /** detect free variable `exports`. */ var freeexports = true && exports && !exports.nodetype && exports; /** detect free variable `module`. */ var freemodule = freeexports && typeof module == 'object' && module && !module.nodetype && module; /** detect the popular commonjs extension `module.exports`. */ var moduleexports = freemodule && freemodule.exports === freeexports; /** built-in value references. */ var buffer = moduleexports ? root.buffer : undefined, allocunsafe = buffer ? buffer.allocunsafe : undefined; /** * creates a clone of `buffer`. * * @private * @param {buffer} buffer the buffer to clone. * @param {boolean} [isdeep] specify a deep clone. * @returns {buffer} returns the cloned buffer. */ function clonebuffer(buffer, isdeep) { if (isdeep) { return buffer.slice(); } var length = buffer.length, result = allocunsafe ? allocunsafe(length) : new buffer.constructor(length); buffer.copy(result); return result; } module.exports = clonebuffer; /* webpack var injection */}.call(this, __webpack_require__(252)(module))) /***/ }), /***/ 386: /***/ (function(module, exports, __webpack_require__) { var freeglobal = __webpack_require__(387); /** detect free variable `self`. */ var freeself = typeof self == 'object' && self && self.object === object && self; /** used as a reference to the global object. */ var root = freeglobal || freeself || function('return this')(); module.exports = root; /***/ }), /***/ 387: /***/ (function(module, exports, __webpack_require__) { /* webpack var injection */(function(global) {/** detect free variable `global` from node.js. */ var freeglobal = typeof global == 'object' && global && global.object === object && global; module.exports = freeglobal; /* webpack var injection */}.call(this, __webpack_require__(25))) /***/ }), /***/ 388: /***/ (function(module, exports) { /** * copies the values of `source` to `array`. * * @private * @param {array} source the array to copy values from. * @param {array} [array=[]] the array to copy values to. * @returns {array} returns `array`. */ function copyarray(source, array) { var index = -1, length = source.length; array || (array = array(length)); while (++index < length) { array[index] = source[index]; } return array; } module.exports = copyarray; /***/ }), /***/ 389: /***/ (function(module, exports, __webpack_require__) { var copyobject = __webpack_require__(123), getsymbols = __webpack_require__(390); /** * copies own symbols of `source` to `object`. * * @private * @param {object} source the object to copy symbols from. * @param {object} [object={}] the object to copy symbols to. * @returns {object} returns `object`. */ function copysymbols(source, object) { return copyobject(source, getsymbols(source), object); } module.exports = copysymbols; /***/ }), /***/ 390: /***/ (function(module, exports) { /** * this method returns a new empty array. * * @static * @memberof _ * @since 4.13.0 * @category util * @returns {array} returns the new empty array. * @example * * var arrays = _.times(2, _.stubarray); * * console.log(arrays); * // => [[], []] * * console.log(arrays[0] === arrays[1]); * // => false */ function stubarray() { return []; } module.exports = stubarray; /***/ }), /***/ 391: /***/ (function(module, exports, __webpack_require__) { var copyobject = __webpack_require__(123), getsymbolsin = __webpack_require__(392); /** * copies own and inherited symbols of `source` to `object`. * * @private * @param {object} source the object to copy symbols from. * @param {object} [object={}] the object to copy symbols to. * @returns {object} returns `object`. */ function copysymbolsin(source, object) { return copyobject(source, getsymbolsin(source), object); } module.exports = copysymbolsin; /***/ }), /***/ 392: /***/ (function(module, exports) { /** * this method returns a new empty array. * * @static * @memberof _ * @since 4.13.0 * @category util * @returns {array} returns the new empty array. * @example * * var arrays = _.times(2, _.stubarray); * * console.log(arrays); * // => [[], []] * * console.log(arrays[0] === arrays[1]); * // => false */ function stubarray() { return []; } module.exports = stubarray; /***/ }), /***/ 393: /***/ (function(module, exports, __webpack_require__) { var overarg = __webpack_require__(156); /* built-in method references for those with the same name as other `lodash` methods. */ var nativekeys = overarg(object.keys, object); module.exports = nativekeys; /***/ }), /***/ 394: /***/ (function(module, exports) { /** * this function is like * [`object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) * except that it includes inherited enumerable properties. * * @private * @param {object} object the object to query. * @returns {array} returns the array of property names. */ function nativekeysin(object) { var result = []; if (object != null) { for (var key in object(object)) { result.push(key); } } return result; } module.exports = nativekeysin; /***/ }), /***/ 395: /***/ (function(module, exports) { /** used for built-in method references. */ var objectproto = object.prototype; /** * used to resolve the * [`tostringtag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeobjecttostring = objectproto.tostring; /** * converts `value` to a string using `object.prototype.tostring`. * * @private * @param {*} value the value to convert. * @returns {string} returns the converted string. */ function objecttostring(value) { return nativeobjecttostring.call(value); } module.exports = objecttostring; /***/ }), /***/ 396: /***/ (function(module, exports) { /** used for built-in method references. */ var objectproto = object.prototype; /** used to check objects for own properties. */ var hasownproperty = objectproto.hasownproperty; /** * initializes an array clone. * * @private * @param {array} array the array to clone. * @returns {array} returns the initialized clone. */ function initclonearray(array) { var length = array.length, result = new array.constructor(length); // add properties assigned by `regexp#exec`. if (length && typeof array[0] == 'string' && hasownproperty.call(array, 'index')) { result.index = array.index; result.input = array.input; } return result; } module.exports = initclonearray; /***/ }), /***/ 397: /***/ (function(module, exports) { /** * this method returns the first argument it receives. * * @static * @since 0.1.0 * @memberof _ * @category util * @param {*} value any value. * @returns {*} returns `value`. * @example * * var object = { 'a': 1 }; * * console.log(_.identity(object) === object); * // => true */ function identity(value) { return value; } module.exports = identity; /***/ }), /***/ 398: /***/ (function(module, exports, __webpack_require__) { var basecreate = __webpack_require__(399), getprototype = __webpack_require__(400), isprototype = __webpack_require__(401); /** * initializes an object clone. * * @private * @param {object} object the object to clone. * @returns {object} returns the initialized clone. */ function initcloneobject(object) { return (typeof object.constructor == 'function' && !isprototype(object)) ? basecreate(getprototype(object)) : {}; } module.exports = initcloneobject; /***/ }), /***/ 399: /***/ (function(module, exports, __webpack_require__) { var isobject = __webpack_require__(253); /** built-in value references. */ var objectcreate = object.create; /** * the base implementation of `_.create` without support for assigning * properties to the created object. * * @private * @param {object} proto the object to inherit from. * @returns {object} returns the new object. */ var basecreate = (function() { function object() {} return function(proto) { if (!isobject(proto)) { return {}; } if (objectcreate) { return objectcreate(proto); } object.prototype = proto; var result = new object; object.prototype = undefined; return result; }; }()); module.exports = basecreate; /***/ }), /***/ 400: /***/ (function(module, exports, __webpack_require__) { var overarg = __webpack_require__(156); /** built-in value references. */ var getprototype = overarg(object.getprototypeof, object); module.exports = getprototype; /***/ }), /***/ 401: /***/ (function(module, exports) { /** * this method returns `false`. * * @static * @memberof _ * @since 4.13.0 * @category util * @returns {boolean} returns `false`. * @example * * _.times(2, _.stubfalse); * // => [false, false] */ function stubfalse() { return false; } module.exports = stubfalse; /***/ }), /***/ 402: /***/ (function(module, exports) { /** * checks if `value` is classified as an `array` object. * * @static * @memberof _ * @since 0.1.0 * @category lang * @param {*} value the value to check. * @returns {boolean} returns `true` if `value` is an array, else `false`. * @example * * _.isarray([1, 2, 3]); * // => true * * _.isarray(document.body.children); * // => false * * _.isarray('abc'); * // => false * * _.isarray(_.noop); * // => false */ var isarray = array.isarray; module.exports = isarray; /***/ }), /***/ 403: /***/ (function(module, exports) { /** * this method returns `false`. * * @static * @memberof _ * @since 4.13.0 * @category util * @returns {boolean} returns `false`. * @example * * _.times(2, _.stubfalse); * // => [false, false] */ function stubfalse() { return false; } module.exports = stubfalse; /***/ }), /***/ 404: /***/ (function(module, exports) { /** * this method returns `false`. * * @static * @memberof _ * @since 4.13.0 * @category util * @returns {boolean} returns `false`. * @example * * _.times(2, _.stubfalse); * // => [false, false] */ function stubfalse() { return false; } module.exports = stubfalse; /***/ }), /***/ 405: /***/ (function(module, exports) { /** * this method returns `false`. * * @static * @memberof _ * @since 4.13.0 * @category util * @returns {boolean} returns `false`. * @example * * _.times(2, _.stubfalse); * // => [false, false] */ function stubfalse() { return false; } module.exports = stubfalse; /***/ }), /***/ 421: /***/ (function(module, exports) { var max_uint32 = math.pow(2, 32); var getuint64 = function(uint8) { var dv = new dataview(uint8.buffer, uint8.byteoffset, uint8.bytelength); var value; if (dv.getbiguint64) { value = dv.getbiguint64(0); if (value < number.max_safe_integer) { return number(value); } return value; } return (dv.getuint32(0) * max_uint32) + dv.getuint32(4); }; module.exports = { getuint64: getuint64, max_uint32: max_uint32 }; /***/ }), /***/ 426: /***/ (function(module, exports, __webpack_require__) { "use strict"; var getsidechannel = __webpack_require__(427); var utils = __webpack_require__(255); var formats = __webpack_require__(159); var has = object.prototype.hasownproperty; var arrayprefixgenerators = { brackets: function brackets(prefix) { return prefix + '[]'; }, comma: 'comma', indices: function indices(prefix, key) { return prefix + '[' + key + ']'; }, repeat: function repeat(prefix) { return prefix; } }; var isarray = array.isarray; var push = array.prototype.push; var pushtoarray = function (arr, valueorarray) { push.apply(arr, isarray(valueorarray) ? valueorarray : [valueorarray]); }; var toiso = date.prototype.toisostring; var defaultformat = formats['default']; var defaults = { addqueryprefix: false, allowdots: false, charset: 'utf-8', charsetsentinel: false, delimiter: '&', encode: true, encoder: utils.encode, encodevaluesonly: false, format: defaultformat, formatter: formats.formatters[defaultformat], // deprecated indices: false, serializedate: function serializedate(date) { return toiso.call(date); }, skipnulls: false, strictnullhandling: false }; var isnonnullishprimitive = function isnonnullishprimitive(v) { return typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean' || typeof v === 'symbol' || typeof v === 'bigint'; }; var sentinel = {}; var stringify = function stringify( object, prefix, generatearrayprefix, commaroundtrip, strictnullhandling, skipnulls, encoder, filter, sort, allowdots, serializedate, format, formatter, encodevaluesonly, charset, sidechannel ) { var obj = object; var tmpsc = sidechannel; var step = 0; var findflag = false; while ((tmpsc = tmpsc.get(sentinel)) !== void undefined && !findflag) { // where object last appeared in the ref tree var pos = tmpsc.get(object); step += 1; if (typeof pos !== 'undefined') { if (pos === step) { throw new rangeerror('cyclic object value'); } else { findflag = true; // break while } } if (typeof tmpsc.get(sentinel) === 'undefined') { step = 0; } } if (typeof filter === 'function') { obj = filter(prefix, obj); } else if (obj instanceof date) { obj = serializedate(obj); } else if (generatearrayprefix === 'comma' && isarray(obj)) { obj = utils.maybemap(obj, function (value) { if (value instanceof date) { return serializedate(value); } return value; }); } if (obj === null) { if (strictnullhandling) { return encoder && !encodevaluesonly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix; } obj = ''; } if (isnonnullishprimitive(obj) || utils.isbuffer(obj)) { if (encoder) { var keyvalue = encodevaluesonly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format); return [formatter(keyvalue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))]; } return [formatter(prefix) + '=' + formatter(string(obj))]; } var values = []; if (typeof obj === 'undefined') { return values; } var objkeys; if (generatearrayprefix === 'comma' && isarray(obj)) { // we need to join elements in if (encodevaluesonly && encoder) { obj = utils.maybemap(obj, encoder); } objkeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }]; } else if (isarray(filter)) { objkeys = filter; } else { var keys = object.keys(obj); objkeys = sort ? keys.sort(sort) : keys; } var adjustedprefix = commaroundtrip && isarray(obj) && obj.length === 1 ? prefix + '[]' : prefix; for (var j = 0; j < objkeys.length; ++j) { var key = objkeys[j]; var value = typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key]; if (skipnulls && value === null) { continue; } var keyprefix = isarray(obj) ? typeof generatearrayprefix === 'function' ? generatearrayprefix(adjustedprefix, key) : adjustedprefix : adjustedprefix + (allowdots ? '.' + key : '[' + key + ']'); sidechannel.set(object, step); var valuesidechannel = getsidechannel(); valuesidechannel.set(sentinel, sidechannel); pushtoarray(values, stringify( value, keyprefix, generatearrayprefix, commaroundtrip, strictnullhandling, skipnulls, generatearrayprefix === 'comma' && encodevaluesonly && isarray(obj) ? null : encoder, filter, sort, allowdots, serializedate, format, formatter, encodevaluesonly, charset, valuesidechannel )); } return values; }; var normalizestringifyoptions = function normalizestringifyoptions(opts) { if (!opts) { return defaults; } if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') { throw new typeerror('encoder has to be a function.'); } var charset = opts.charset || defaults.charset; if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { throw new typeerror('the charset option must be either utf-8, iso-8859-1, or undefined'); } var format = formats['default']; if (typeof opts.format !== 'undefined') { if (!has.call(formats.formatters, opts.format)) { throw new typeerror('unknown format option provided.'); } format = opts.format; } var formatter = formats.formatters[format]; var filter = defaults.filter; if (typeof opts.filter === 'function' || isarray(opts.filter)) { filter = opts.filter; } return { addqueryprefix: typeof opts.addqueryprefix === 'boolean' ? opts.addqueryprefix : defaults.addqueryprefix, allowdots: typeof opts.allowdots === 'undefined' ? defaults.allowdots : !!opts.allowdots, charset: charset, charsetsentinel: typeof opts.charsetsentinel === 'boolean' ? opts.charsetsentinel : defaults.charsetsentinel, delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter, encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode, encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder, encodevaluesonly: typeof opts.encodevaluesonly === 'boolean' ? opts.encodevaluesonly : defaults.encodevaluesonly, filter: filter, format: format, formatter: formatter, serializedate: typeof opts.serializedate === 'function' ? opts.serializedate : defaults.serializedate, skipnulls: typeof opts.skipnulls === 'boolean' ? opts.skipnulls : defaults.skipnulls, sort: typeof opts.sort === 'function' ? opts.sort : null, strictnullhandling: typeof opts.strictnullhandling === 'boolean' ? opts.strictnullhandling : defaults.strictnullhandling }; }; module.exports = function (object, opts) { var obj = object; var options = normalizestringifyoptions(opts); var objkeys; var filter; if (typeof options.filter === 'function') { filter = options.filter; obj = filter('', obj); } else if (isarray(options.filter)) { filter = options.filter; objkeys = filter; } var keys = []; if (typeof obj !== 'object' || obj === null) { return ''; } var arrayformat; if (opts && opts.arrayformat in arrayprefixgenerators) { arrayformat = opts.arrayformat; } else if (opts && 'indices' in opts) { arrayformat = opts.indices ? 'indices' : 'repeat'; } else { arrayformat = 'indices'; } var generatearrayprefix = arrayprefixgenerators[arrayformat]; if (opts && 'commaroundtrip' in opts && typeof opts.commaroundtrip !== 'boolean') { throw new typeerror('`commaroundtrip` must be a boolean, or absent'); } var commaroundtrip = generatearrayprefix === 'comma' && opts && opts.commaroundtrip; if (!objkeys) { objkeys = object.keys(obj); } if (options.sort) { objkeys.sort(options.sort); } var sidechannel = getsidechannel(); for (var i = 0; i < objkeys.length; ++i) { var key = objkeys[i]; if (options.skipnulls && obj[key] === null) { continue; } pushtoarray(keys, stringify( obj[key], key, generatearrayprefix, commaroundtrip, options.strictnullhandling, options.skipnulls, options.encode ? options.encoder : null, options.filter, options.sort, options.allowdots, options.serializedate, options.format, options.formatter, options.encodevaluesonly, options.charset, sidechannel )); } var joined = keys.join(options.delimiter); var prefix = options.addqueryprefix === true ? '?' : ''; if (options.charsetsentinel) { if (options.charset === 'iso-8859-1') { // encodeuricomponent('✓'), the "numeric entity" representation of a checkmark prefix += 'utf8=%26%2310003%3b&'; } else { // encodeuricomponent('✓') prefix += 'utf8=%e2%9c%93&'; } } return joined.length > 0 ? prefix + joined : ''; }; /***/ }), /***/ 435: /***/ (function(module, exports, __webpack_require__) { var hasmap = typeof map === 'function' && map.prototype; var mapsizedescriptor = object.getownpropertydescriptor && hasmap ? object.getownpropertydescriptor(map.prototype, 'size') : null; var mapsize = hasmap && mapsizedescriptor && typeof mapsizedescriptor.get === 'function' ? mapsizedescriptor.get : null; var mapforeach = hasmap && map.prototype.foreach; var hasset = typeof set === 'function' && set.prototype; var setsizedescriptor = object.getownpropertydescriptor && hasset ? object.getownpropertydescriptor(set.prototype, 'size') : null; var setsize = hasset && setsizedescriptor && typeof setsizedescriptor.get === 'function' ? setsizedescriptor.get : null; var setforeach = hasset && set.prototype.foreach; var hasweakmap = typeof weakmap === 'function' && weakmap.prototype; var weakmaphas = hasweakmap ? weakmap.prototype.has : null; var hasweakset = typeof weakset === 'function' && weakset.prototype; var weaksethas = hasweakset ? weakset.prototype.has : null; var hasweakref = typeof weakref === 'function' && weakref.prototype; var weakrefderef = hasweakref ? weakref.prototype.deref : null; var booleanvalueof = boolean.prototype.valueof; var objecttostring = object.prototype.tostring; var functiontostring = function.prototype.tostring; var $match = string.prototype.match; var $slice = string.prototype.slice; var $replace = string.prototype.replace; var $touppercase = string.prototype.touppercase; var $tolowercase = string.prototype.tolowercase; var $test = regexp.prototype.test; var $concat = array.prototype.concat; var $join = array.prototype.join; var $arrslice = array.prototype.slice; var $floor = math.floor; var bigintvalueof = typeof bigint === 'function' ? bigint.prototype.valueof : null; var gops = object.getownpropertysymbols; var symtostring = typeof symbol === 'function' && typeof symbol.iterator === 'symbol' ? symbol.prototype.tostring : null; var hasshammedsymbols = typeof symbol === 'function' && typeof symbol.iterator === 'object'; // ie, `has-tostringtag/shams var tostringtag = typeof symbol === 'function' && symbol.tostringtag && (typeof symbol.tostringtag === hasshammedsymbols ? 'object' : 'symbol') ? symbol.tostringtag : null; var isenumerable = object.prototype.propertyisenumerable; var gpo = (typeof reflect === 'function' ? reflect.getprototypeof : object.getprototypeof) || ( [].__proto__ === array.prototype // eslint-disable-line no-proto ? function (o) { return o.__proto__; // eslint-disable-line no-proto } : null ); function addnumericseparator(num, str) { if ( num === infinity || num === -infinity || num !== num || (num && num > -1000 && num < 1000) || $test.call(/e/, str) ) { return str; } var sepregex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g; if (typeof num === 'number') { var int = num < 0 ? -$floor(-num) : $floor(num); // trunc(num) if (int !== num) { var intstr = string(int); var dec = $slice.call(str, intstr.length + 1); return $replace.call(intstr, sepregex, '$&_') + '.' + $replace.call($replace.call(dec, /([0-9]{3})/g, '$&_'), /_$/, ''); } } return $replace.call(str, sepregex, '$&_'); } var utilinspect = __webpack_require__(436); var inspectcustom = utilinspect.custom; var inspectsymbol = issymbol(inspectcustom) ? inspectcustom : null; module.exports = function inspect_(obj, options, depth, seen) { var opts = options || {}; if (has(opts, 'quotestyle') && (opts.quotestyle !== 'single' && opts.quotestyle !== 'double')) { throw new typeerror('option "quotestyle" must be "single" or "double"'); } if ( has(opts, 'maxstringlength') && (typeof opts.maxstringlength === 'number' ? opts.maxstringlength < 0 && opts.maxstringlength !== infinity : opts.maxstringlength !== null ) ) { throw new typeerror('option "maxstringlength", if provided, must be a positive integer, infinity, or `null`'); } var custominspect = has(opts, 'custominspect') ? opts.custominspect : true; if (typeof custominspect !== 'boolean' && custominspect !== 'symbol') { throw new typeerror('option "custominspect", if provided, must be `true`, `false`, or `\'symbol\'`'); } if ( has(opts, 'indent') && opts.indent !== null && opts.indent !== '\t' && !(parseint(opts.indent, 10) === opts.indent && opts.indent > 0) ) { throw new typeerror('option "indent" must be "\\t", an integer > 0, or `null`'); } if (has(opts, 'numericseparator') && typeof opts.numericseparator !== 'boolean') { throw new typeerror('option "numericseparator", if provided, must be `true` or `false`'); } var numericseparator = opts.numericseparator; if (typeof obj === 'undefined') { return 'undefined'; } if (obj === null) { return 'null'; } if (typeof obj === 'boolean') { return obj ? 'true' : 'false'; } if (typeof obj === 'string') { return inspectstring(obj, opts); } if (typeof obj === 'number') { if (obj === 0) { return infinity / obj > 0 ? '0' : '-0'; } var str = string(obj); return numericseparator ? addnumericseparator(obj, str) : str; } if (typeof obj === 'bigint') { var bigintstr = string(obj) + 'n'; return numericseparator ? addnumericseparator(obj, bigintstr) : bigintstr; } var maxdepth = typeof opts.depth === 'undefined' ? 5 : opts.depth; if (typeof depth === 'undefined') { depth = 0; } if (depth >= maxdepth && maxdepth > 0 && typeof obj === 'object') { return isarray(obj) ? '[array]' : '[object]'; } var indent = getindent(opts, depth); if (typeof seen === 'undefined') { seen = []; } else if (indexof(seen, obj) >= 0) { return '[circular]'; } function inspect(value, from, noindent) { if (from) { seen = $arrslice.call(seen); seen.push(from); } if (noindent) { var newopts = { depth: opts.depth }; if (has(opts, 'quotestyle')) { newopts.quotestyle = opts.quotestyle; } return inspect_(value, newopts, depth + 1, seen); } return inspect_(value, opts, depth + 1, seen); } if (typeof obj === 'function' && !isregexp(obj)) { // in older engines, regexes are callable var name = nameof(obj); var keys = arrobjkeys(obj, inspect); return '[function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + $join.call(keys, ', ') + ' }' : ''); } if (issymbol(obj)) { var symstring = hasshammedsymbols ? $replace.call(string(obj), /^(symbol\(.*\))_[^)]*$/, '$1') : symtostring.call(obj); return typeof obj === 'object' && !hasshammedsymbols ? markboxed(symstring) : symstring; } if (iselement(obj)) { var s = '<' + $tolowercase.call(string(obj.nodename)); var attrs = obj.attributes || []; for (var i = 0; i < attrs.length; i++) { s += ' ' + attrs[i].name + '=' + wrapquotes(quote(attrs[i].value), 'double', opts); } s += '>'; if (obj.childnodes && obj.childnodes.length) { s += '...'; } s += ''; return s; } if (isarray(obj)) { if (obj.length === 0) { return '[]'; } var xs = arrobjkeys(obj, inspect); if (indent && !singlelinevalues(xs)) { return '[' + indentedjoin(xs, indent) + ']'; } return '[ ' + $join.call(xs, ', ') + ' ]'; } if (iserror(obj)) { var parts = arrobjkeys(obj, inspect); if (!('cause' in error.prototype) && 'cause' in obj && !isenumerable.call(obj, 'cause')) { return '{ [' + string(obj) + '] ' + $join.call($concat.call('[cause]: ' + inspect(obj.cause), parts), ', ') + ' }'; } if (parts.length === 0) { return '[' + string(obj) + ']'; } return '{ [' + string(obj) + '] ' + $join.call(parts, ', ') + ' }'; } if (typeof obj === 'object' && custominspect) { if (inspectsymbol && typeof obj[inspectsymbol] === 'function' && utilinspect) { return utilinspect(obj, { depth: maxdepth - depth }); } else if (custominspect !== 'symbol' && typeof obj.inspect === 'function') { return obj.inspect(); } } if (ismap(obj)) { var mapparts = []; if (mapforeach) { mapforeach.call(obj, function (value, key) { mapparts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj)); }); } return collectionof('map', mapsize.call(obj), mapparts, indent); } if (isset(obj)) { var setparts = []; if (setforeach) { setforeach.call(obj, function (value) { setparts.push(inspect(value, obj)); }); } return collectionof('set', setsize.call(obj), setparts, indent); } if (isweakmap(obj)) { return weakcollectionof('weakmap'); } if (isweakset(obj)) { return weakcollectionof('weakset'); } if (isweakref(obj)) { return weakcollectionof('weakref'); } if (isnumber(obj)) { return markboxed(inspect(number(obj))); } if (isbigint(obj)) { return markboxed(inspect(bigintvalueof.call(obj))); } if (isboolean(obj)) { return markboxed(booleanvalueof.call(obj)); } if (isstring(obj)) { return markboxed(inspect(string(obj))); } if (!isdate(obj) && !isregexp(obj)) { var ys = arrobjkeys(obj, inspect); var isplainobject = gpo ? gpo(obj) === object.prototype : obj instanceof object || obj.constructor === object; var prototag = obj instanceof object ? '' : 'null prototype'; var stringtag = !isplainobject && tostringtag && object(obj) === obj && tostringtag in obj ? $slice.call(tostr(obj), 8, -1) : prototag ? 'object' : ''; var constructortag = isplainobject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : ''; var tag = constructortag + (stringtag || prototag ? '[' + $join.call($concat.call([], stringtag || [], prototag || []), ': ') + '] ' : ''); if (ys.length === 0) { return tag + '{}'; } if (indent) { return tag + '{' + indentedjoin(ys, indent) + '}'; } return tag + '{ ' + $join.call(ys, ', ') + ' }'; } return string(obj); }; function wrapquotes(s, defaultstyle, opts) { var quotechar = (opts.quotestyle || defaultstyle) === 'double' ? '"' : "'"; return quotechar + s + quotechar; } function quote(s) { return $replace.call(string(s), /"/g, '"'); } function isarray(obj) { return tostr(obj) === '[object array]' && (!tostringtag || !(typeof obj === 'object' && tostringtag in obj)); } function isdate(obj) { return tostr(obj) === '[object date]' && (!tostringtag || !(typeof obj === 'object' && tostringtag in obj)); } function isregexp(obj) { return tostr(obj) === '[object regexp]' && (!tostringtag || !(typeof obj === 'object' && tostringtag in obj)); } function iserror(obj) { return tostr(obj) === '[object error]' && (!tostringtag || !(typeof obj === 'object' && tostringtag in obj)); } function isstring(obj) { return tostr(obj) === '[object string]' && (!tostringtag || !(typeof obj === 'object' && tostringtag in obj)); } function isnumber(obj) { return tostr(obj) === '[object number]' && (!tostringtag || !(typeof obj === 'object' && tostringtag in obj)); } function isboolean(obj) { return tostr(obj) === '[object boolean]' && (!tostringtag || !(typeof obj === 'object' && tostringtag in obj)); } // symbol and bigint do have symbol.tostringtag by spec, so that can't be used to eliminate false positives function issymbol(obj) { if (hasshammedsymbols) { return obj && typeof obj === 'object' && obj instanceof symbol; } if (typeof obj === 'symbol') { return true; } if (!obj || typeof obj !== 'object' || !symtostring) { return false; } try { symtostring.call(obj); return true; } catch (e) {} return false; } function isbigint(obj) { if (!obj || typeof obj !== 'object' || !bigintvalueof) { return false; } try { bigintvalueof.call(obj); return true; } catch (e) {} return false; } var hasown = object.prototype.hasownproperty || function (key) { return key in this; }; function has(obj, key) { return hasown.call(obj, key); } function tostr(obj) { return objecttostring.call(obj); } function nameof(f) { if (f.name) { return f.name; } var m = $match.call(functiontostring.call(f), /^function\s*([\w$]+)/); if (m) { return m[1]; } return null; } function indexof(xs, x) { if (xs.indexof) { return xs.indexof(x); } for (var i = 0, l = xs.length; i < l; i++) { if (xs[i] === x) { return i; } } return -1; } function ismap(x) { if (!mapsize || !x || typeof x !== 'object') { return false; } try { mapsize.call(x); try { setsize.call(x); } catch (s) { return true; } return x instanceof map; // core-js workaround, pre-v2.5.0 } catch (e) {} return false; } function isweakmap(x) { if (!weakmaphas || !x || typeof x !== 'object') { return false; } try { weakmaphas.call(x, weakmaphas); try { weaksethas.call(x, weaksethas); } catch (s) { return true; } return x instanceof weakmap; // core-js workaround, pre-v2.5.0 } catch (e) {} return false; } function isweakref(x) { if (!weakrefderef || !x || typeof x !== 'object') { return false; } try { weakrefderef.call(x); return true; } catch (e) {} return false; } function isset(x) { if (!setsize || !x || typeof x !== 'object') { return false; } try { setsize.call(x); try { mapsize.call(x); } catch (m) { return true; } return x instanceof set; // core-js workaround, pre-v2.5.0 } catch (e) {} return false; } function isweakset(x) { if (!weaksethas || !x || typeof x !== 'object') { return false; } try { weaksethas.call(x, weaksethas); try { weakmaphas.call(x, weakmaphas); } catch (s) { return true; } return x instanceof weakset; // core-js workaround, pre-v2.5.0 } catch (e) {} return false; } function iselement(x) { if (!x || typeof x !== 'object') { return false; } if (typeof htmlelement !== 'undefined' && x instanceof htmlelement) { return true; } return typeof x.nodename === 'string' && typeof x.getattribute === 'function'; } function inspectstring(str, opts) { if (str.length > opts.maxstringlength) { var remaining = str.length - opts.maxstringlength; var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : ''); return inspectstring($slice.call(str, 0, opts.maxstringlength), opts) + trailer; } // eslint-disable-next-line no-control-regex var s = $replace.call($replace.call(str, /(['\\])/g, '\\$1'), /[\x00-\x1f]/g, lowbyte); return wrapquotes(s, 'single', opts); } function lowbyte(c) { var n = c.charcodeat(0); var x = { 8: 'b', 9: 't', 10: 'n', 12: 'f', 13: 'r' }[n]; if (x) { return '\\' + x; } return '\\x' + (n < 0x10 ? '0' : '') + $touppercase.call(n.tostring(16)); } function markboxed(str) { return 'object(' + str + ')'; } function weakcollectionof(type) { return type + ' { ? }'; } function collectionof(type, size, entries, indent) { var joinedentries = indent ? indentedjoin(entries, indent) : $join.call(entries, ', '); return type + ' (' + size + ') {' + joinedentries + '}'; } function singlelinevalues(xs) { for (var i = 0; i < xs.length; i++) { if (indexof(xs[i], '\n') >= 0) { return false; } } return true; } function getindent(opts, depth) { var baseindent; if (opts.indent === '\t') { baseindent = '\t'; } else if (typeof opts.indent === 'number' && opts.indent > 0) { baseindent = $join.call(array(opts.indent + 1), ' '); } else { return null; } return { base: baseindent, prev: $join.call(array(depth + 1), baseindent) }; } function indentedjoin(xs, indent) { if (xs.length === 0) { return ''; } var linejoiner = '\n' + indent.prev + indent.base; return linejoiner + $join.call(xs, ',' + linejoiner) + '\n' + indent.prev; } function arrobjkeys(obj, inspect) { var isarr = isarray(obj); var xs = []; if (isarr) { xs.length = obj.length; for (var i = 0; i < obj.length; i++) { xs[i] = has(obj, i) ? inspect(obj[i], obj) : ''; } } var syms = typeof gops === 'function' ? gops(obj) : []; var symmap; if (hasshammedsymbols) { symmap = {}; for (var k = 0; k < syms.length; k++) { symmap['$' + syms[k]] = syms[k]; } } for (var key in obj) { // eslint-disable-line no-restricted-syntax if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue if (isarr && string(number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue if (hasshammedsymbols && symmap['$' + key] instanceof symbol) { // this is to prevent shammed symbols, which are stored as strings, from being included in the string key section continue; // eslint-disable-line no-restricted-syntax, no-continue } else if ($test.call(/[^\w$]/, key)) { xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj)); } else { xs.push(key + ': ' + inspect(obj[key], obj)); } } if (typeof gops === 'function') { for (var j = 0; j < syms.length; j++) { if (isenumerable.call(obj, syms[j])) { xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj)); } } } return xs; } /***/ }), /***/ 437: /***/ (function(module, exports, __webpack_require__) { "use strict"; var utils = __webpack_require__(255); var has = object.prototype.hasownproperty; var isarray = array.isarray; var defaults = { allowdots: false, allowprototypes: false, allowsparse: false, arraylimit: 20, charset: 'utf-8', charsetsentinel: false, comma: false, decoder: utils.decode, delimiter: '&', depth: 5, ignorequeryprefix: false, interpretnumericentities: false, parameterlimit: 1000, parsearrays: true, plainobjects: false, strictnullhandling: false }; var interpretnumericentities = function (str) { return str.replace(/&#(\d+);/g, function ($0, numberstr) { return string.fromcharcode(parseint(numberstr, 10)); }); }; var parsearrayvalue = function (val, options) { if (val && typeof val === 'string' && options.comma && val.indexof(',') > -1) { return val.split(','); } return val; }; // this is what browsers will submit when the ✓ character occurs in an // application/x-www-form-urlencoded body and the encoding of the page containing // the form is iso-8859-1, or when the submitted form has an accept-charset // attribute of iso-8859-1. presumably also with other charsets that do not contain // the ✓ character, such as us-ascii. var isosentinel = 'utf8=%26%2310003%3b'; // encodeuricomponent('✓') // these are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded. var charsetsentinel = 'utf8=%e2%9c%93'; // encodeuricomponent('✓') var parsevalues = function parsequerystringvalues(str, options) { var obj = { __proto__: null }; var cleanstr = options.ignorequeryprefix ? str.replace(/^\?/, '') : str; var limit = options.parameterlimit === infinity ? undefined : options.parameterlimit; var parts = cleanstr.split(options.delimiter, limit); var skipindex = -1; // keep track of where the utf8 sentinel was found var i; var charset = options.charset; if (options.charsetsentinel) { for (i = 0; i < parts.length; ++i) { if (parts[i].indexof('utf8=') === 0) { if (parts[i] === charsetsentinel) { charset = 'utf-8'; } else if (parts[i] === isosentinel) { charset = 'iso-8859-1'; } skipindex = i; i = parts.length; // the eslint settings do not allow break; } } } for (i = 0; i < parts.length; ++i) { if (i === skipindex) { continue; } var part = parts[i]; var bracketequalspos = part.indexof(']='); var pos = bracketequalspos === -1 ? part.indexof('=') : bracketequalspos + 1; var key, val; if (pos === -1) { key = options.decoder(part, defaults.decoder, charset, 'key'); val = options.strictnullhandling ? null : ''; } else { key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key'); val = utils.maybemap( parsearrayvalue(part.slice(pos + 1), options), function (encodedval) { return options.decoder(encodedval, defaults.decoder, charset, 'value'); } ); } if (val && options.interpretnumericentities && charset === 'iso-8859-1') { val = interpretnumericentities(val); } if (part.indexof('[]=') > -1) { val = isarray(val) ? [val] : val; } if (has.call(obj, key)) { obj[key] = utils.combine(obj[key], val); } else { obj[key] = val; } } return obj; }; var parseobject = function (chain, val, options, valuesparsed) { var leaf = valuesparsed ? val : parsearrayvalue(val, options); for (var i = chain.length - 1; i >= 0; --i) { var obj; var root = chain[i]; if (root === '[]' && options.parsearrays) { obj = [].concat(leaf); } else { obj = options.plainobjects ? object.create(null) : {}; var cleanroot = root.charat(0) === '[' && root.charat(root.length - 1) === ']' ? root.slice(1, -1) : root; var index = parseint(cleanroot, 10); if (!options.parsearrays && cleanroot === '') { obj = { 0: leaf }; } else if ( !isnan(index) && root !== cleanroot && string(index) === cleanroot && index >= 0 && (options.parsearrays && index <= options.arraylimit) ) { obj = []; obj[index] = leaf; } else if (cleanroot !== '__proto__') { obj[cleanroot] = leaf; } } leaf = obj; } return leaf; }; var parsekeys = function parsequerystringkeys(givenkey, val, options, valuesparsed) { if (!givenkey) { return; } // transform dot notation to bracket notation var key = options.allowdots ? givenkey.replace(/\.([^.[]+)/g, '[$1]') : givenkey; // the regex chunks var brackets = /(\[[^[\]]*])/; var child = /(\[[^[\]]*])/g; // get the parent var segment = options.depth > 0 && brackets.exec(key); var parent = segment ? key.slice(0, segment.index) : key; // stash the parent if it exists var keys = []; if (parent) { // if we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties if (!options.plainobjects && has.call(object.prototype, parent)) { if (!options.allowprototypes) { return; } } keys.push(parent); } // loop through children appending to the array until we hit depth var i = 0; while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) { i += 1; if (!options.plainobjects && has.call(object.prototype, segment[1].slice(1, -1))) { if (!options.allowprototypes) { return; } } keys.push(segment[1]); } // if there's a remainder, just add whatever is left if (segment) { keys.push('[' + key.slice(segment.index) + ']'); } return parseobject(keys, val, options, valuesparsed); }; var normalizeparseoptions = function normalizeparseoptions(opts) { if (!opts) { return defaults; } if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') { throw new typeerror('decoder has to be a function.'); } if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { throw new typeerror('the charset option must be either utf-8, iso-8859-1, or undefined'); } var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset; return { allowdots: typeof opts.allowdots === 'undefined' ? defaults.allowdots : !!opts.allowdots, allowprototypes: typeof opts.allowprototypes === 'boolean' ? opts.allowprototypes : defaults.allowprototypes, allowsparse: typeof opts.allowsparse === 'boolean' ? opts.allowsparse : defaults.allowsparse, arraylimit: typeof opts.arraylimit === 'number' ? opts.arraylimit : defaults.arraylimit, charset: charset, charsetsentinel: typeof opts.charsetsentinel === 'boolean' ? opts.charsetsentinel : defaults.charsetsentinel, comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma, decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder, delimiter: typeof opts.delimiter === 'string' || utils.isregexp(opts.delimiter) ? opts.delimiter : defaults.delimiter, // eslint-disable-next-line no-implicit-coercion, no-extra-parens depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth, ignorequeryprefix: opts.ignorequeryprefix === true, interpretnumericentities: typeof opts.interpretnumericentities === 'boolean' ? opts.interpretnumericentities : defaults.interpretnumericentities, parameterlimit: typeof opts.parameterlimit === 'number' ? opts.parameterlimit : defaults.parameterlimit, parsearrays: opts.parsearrays !== false, plainobjects: typeof opts.plainobjects === 'boolean' ? opts.plainobjects : defaults.plainobjects, strictnullhandling: typeof opts.strictnullhandling === 'boolean' ? opts.strictnullhandling : defaults.strictnullhandling }; }; module.exports = function (str, opts) { var options = normalizeparseoptions(opts); if (str === '' || str === null || typeof str === 'undefined') { return options.plainobjects ? object.create(null) : {}; } var tempobj = typeof str === 'string' ? parsevalues(str, options) : str; var obj = options.plainobjects ? object.create(null) : {}; // iterate over the keys and setup the new object var keys = object.keys(tempobj); for (var i = 0; i < keys.length; ++i) { var key = keys[i]; var newobj = parsekeys(key, tempobj[key], options, typeof str === 'string'); obj = utils.merge(obj, newobj, options); } if (options.allowsparse === true) { return obj; } return utils.compact(obj); }; /***/ }), /***/ 53: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export version */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return addsidxsegmentstoplaylist$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return generatesidxkey; }); /* unused harmony export inheritattributes */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return parse; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return parseutctiming; }); /* unused harmony export stringtompdxml */ /* unused harmony export tom3u8 */ /* unused harmony export toplaylists */ /* harmony import */ var _videojs_vhs_utils_es_resolve_url__webpack_imported_module_0__ = __webpack_require__(81); /* harmony import */ var global_window__webpack_imported_module_1__ = __webpack_require__(0); /* harmony import */ var global_window__webpack_imported_module_1___default = /*#__pure__*/__webpack_require__.n(global_window__webpack_imported_module_1__); /* harmony import */ var _videojs_vhs_utils_es_media_groups__webpack_imported_module_2__ = __webpack_require__(269); /* harmony import */ var _videojs_vhs_utils_es_decode_b64_to_uint8_array__webpack_imported_module_3__ = __webpack_require__(130); /* harmony import */ var _xmldom_xmldom__webpack_imported_module_4__ = __webpack_require__(270); /* harmony import */ var _xmldom_xmldom__webpack_imported_module_4___default = /*#__pure__*/__webpack_require__.n(_xmldom_xmldom__webpack_imported_module_4__); /*! @name mpd-parser @version 0.22.1 @license apache-2.0 */ var version = "0.22.1"; var isobject = function isobject(obj) { return !!obj && typeof obj === 'object'; }; var merge = function merge() { for (var _len = arguments.length, objects = new array(_len), _key = 0; _key < _len; _key++) { objects[_key] = arguments[_key]; } return objects.reduce(function (result, source) { if (typeof source !== 'object') { return result; } object.keys(source).foreach(function (key) { if (array.isarray(result[key]) && array.isarray(source[key])) { result[key] = result[key].concat(source[key]); } else if (isobject(result[key]) && isobject(source[key])) { result[key] = merge(result[key], source[key]); } else { result[key] = source[key]; } }); return result; }, {}); }; var values = function values(o) { return object.keys(o).map(function (k) { return o[k]; }); }; var range = function range(start, end) { var result = []; for (var i = start; i < end; i++) { result.push(i); } return result; }; var flatten = function flatten(lists) { return lists.reduce(function (x, y) { return x.concat(y); }, []); }; var from = function from(list) { if (!list.length) { return []; } var result = []; for (var i = 0; i < list.length; i++) { result.push(list[i]); } return result; }; var findindexes = function findindexes(l, key) { return l.reduce(function (a, e, i) { if (e[key]) { a.push(i); } return a; }, []); }; /** * returns the first index that satisfies the matching function, or -1 if not found. * * only necessary because of ie11 support. * * @param {array} list - the list to search through * @param {function} matchingfunction - the matching function * * @return {number} the matching index or -1 if not found */ var findindex = function findindex(list, matchingfunction) { for (var i = 0; i < list.length; i++) { if (matchingfunction(list[i])) { return i; } } return -1; }; /** * returns a union of the included lists provided each element can be identified by a key. * * @param {array} list - list of lists to get the union of * @param {function} keyfunction - the function to use as a key for each element * * @return {array} the union of the arrays */ var union = function union(lists, keyfunction) { return values(lists.reduce(function (acc, list) { list.foreach(function (el) { acc[keyfunction(el)] = el; }); return acc; }, {})); }; var errors = { invalid_number_of_period: 'invalid_number_of_period', dash_empty_manifest: 'dash_empty_manifest', dash_invalid_xml: 'dash_invalid_xml', no_base_url: 'no_base_url', missing_segment_information: 'missing_segment_information', segment_time_unspecified: 'segment_time_unspecified', unsupported_utc_timing_scheme: 'unsupported_utc_timing_scheme' }; /** * @typedef {object} singleuri * @property {string} uri - relative location of segment * @property {string} resolveduri - resolved location of segment * @property {object} byterange - object containing information on how to make byte range * requests following byte-range-spec per rfc2616. * @property {string} byterange.length - length of range request * @property {string} byterange.offset - byte offset of range request * * @see https://www.w3.org/protocols/rfc2616/rfc2616-sec14.html#sec14.35.1 */ /** * converts a urltype node (5.3.9.2.3 table 13) to a segment object * that conforms to how m3u8-parser is structured * * @see https://github.com/videojs/m3u8-parser * * @param {string} baseurl - baseurl provided by nodes * @param {string} source - source url for segment * @param {string} range - optional range used for range calls, * follows rfc 2616, clause 14.35.1 * @return {singleuri} full segment information transformed into a format similar * to m3u8-parser */ var urltypetosegment = function urltypetosegment(_ref) { var _ref$baseurl = _ref.baseurl, baseurl = _ref$baseurl === void 0 ? '' : _ref$baseurl, _ref$source = _ref.source, source = _ref$source === void 0 ? '' : _ref$source, _ref$range = _ref.range, range = _ref$range === void 0 ? '' : _ref$range, _ref$indexrange = _ref.indexrange, indexrange = _ref$indexrange === void 0 ? '' : _ref$indexrange; var segment = { uri: source, resolveduri: object(_videojs_vhs_utils_es_resolve_url__webpack_imported_module_0__[/* default */ "a"])(baseurl || '', source) }; if (range || indexrange) { var rangestr = range ? range : indexrange; var ranges = rangestr.split('-'); // default to parsing this as a bigint if possible var startrange = global_window__webpack_imported_module_1___default.a.bigint ? global_window__webpack_imported_module_1___default.a.bigint(ranges[0]) : parseint(ranges[0], 10); var endrange = global_window__webpack_imported_module_1___default.a.bigint ? global_window__webpack_imported_module_1___default.a.bigint(ranges[1]) : parseint(ranges[1], 10); // convert back to a number if less than max_safe_integer if (startrange < number.max_safe_integer && typeof startrange === 'bigint') { startrange = number(startrange); } if (endrange < number.max_safe_integer && typeof endrange === 'bigint') { endrange = number(endrange); } var length; if (typeof endrange === 'bigint' || typeof startrange === 'bigint') { length = global_window__webpack_imported_module_1___default.a.bigint(endrange) - global_window__webpack_imported_module_1___default.a.bigint(startrange) + global_window__webpack_imported_module_1___default.a.bigint(1); } else { length = endrange - startrange + 1; } if (typeof length === 'bigint' && length < number.max_safe_integer) { length = number(length); } // byterange should be inclusive according to // rfc 2616, clause 14.35.1 segment.byterange = { length: length, offset: startrange }; } return segment; }; var byterangetostring = function byterangetostring(byterange) { // `endrange` is one less than `offset + length` because the http range // header uses inclusive ranges var endrange; if (typeof byterange.offset === 'bigint' || typeof byterange.length === 'bigint') { endrange = global_window__webpack_imported_module_1___default.a.bigint(byterange.offset) + global_window__webpack_imported_module_1___default.a.bigint(byterange.length) - global_window__webpack_imported_module_1___default.a.bigint(1); } else { endrange = byterange.offset + byterange.length - 1; } return byterange.offset + "-" + endrange; }; /** * parse the end number attribue that can be a string * number, or undefined. * * @param {string|number|undefined} endnumber * the end number attribute. * * @return {number|null} * the result of parsing the end number. */ var parseendnumber = function parseendnumber(endnumber) { if (endnumber && typeof endnumber !== 'number') { endnumber = parseint(endnumber, 10); } if (isnan(endnumber)) { return null; } return endnumber; }; /** * functions for calculating the range of available segments in static and dynamic * manifests. */ var segmentrange = { /** * returns the entire range of available segments for a static mpd * * @param {object} attributes * inheritied mpd attributes * @return {{ start: number, end: number }} * the start and end numbers for available segments */ static: function _static(attributes) { var duration = attributes.duration, _attributes$timescale = attributes.timescale, timescale = _attributes$timescale === void 0 ? 1 : _attributes$timescale, sourceduration = attributes.sourceduration, periodduration = attributes.periodduration; var endnumber = parseendnumber(attributes.endnumber); var segmentduration = duration / timescale; if (typeof endnumber === 'number') { return { start: 0, end: endnumber }; } if (typeof periodduration === 'number') { return { start: 0, end: periodduration / segmentduration }; } return { start: 0, end: sourceduration / segmentduration }; }, /** * returns the current live window range of available segments for a dynamic mpd * * @param {object} attributes * inheritied mpd attributes * @return {{ start: number, end: number }} * the start and end numbers for available segments */ dynamic: function dynamic(attributes) { var now = attributes.now, clientoffset = attributes.clientoffset, availabilitystarttime = attributes.availabilitystarttime, _attributes$timescale2 = attributes.timescale, timescale = _attributes$timescale2 === void 0 ? 1 : _attributes$timescale2, duration = attributes.duration, _attributes$periodsta = attributes.periodstart, periodstart = _attributes$periodsta === void 0 ? 0 : _attributes$periodsta, _attributes$minimumup = attributes.minimumupdateperiod, minimumupdateperiod = _attributes$minimumup === void 0 ? 0 : _attributes$minimumup, _attributes$timeshift = attributes.timeshiftbufferdepth, timeshiftbufferdepth = _attributes$timeshift === void 0 ? infinity : _attributes$timeshift; var endnumber = parseendnumber(attributes.endnumber); // clientoffset is passed in at the top level of mpd-parser and is an offset calculated // after retrieving utc server time. var now = (now + clientoffset) / 1000; // wc stands for wall clock. // convert the period start time to epoch. var periodstartwc = availabilitystarttime + periodstart; // period end in epoch is manifest's retrieval time + time until next update. var periodendwc = now + minimumupdateperiod; var periodduration = periodendwc - periodstartwc; var segmentcount = math.ceil(periodduration * timescale / duration); var availablestart = math.floor((now - periodstartwc - timeshiftbufferdepth) * timescale / duration); var availableend = math.floor((now - periodstartwc) * timescale / duration); return { start: math.max(0, availablestart), end: typeof endnumber === 'number' ? endnumber : math.min(segmentcount, availableend) }; } }; /** * maps a range of numbers to objects with information needed to build the corresponding * segment list * * @name tosegmentscallback * @function * @param {number} number * number of the segment * @param {number} index * index of the number in the range list * @return {{ number: number, duration: number, timeline: number, time: number }} * object with segment timing and duration info */ /** * returns a callback for array.prototype.map for mapping a range of numbers to * information needed to build the segment list. * * @param {object} attributes * inherited mpd attributes * @return {tosegmentscallback} * callback map function */ var tosegments = function tosegments(attributes) { return function (number) { var duration = attributes.duration, _attributes$timescale3 = attributes.timescale, timescale = _attributes$timescale3 === void 0 ? 1 : _attributes$timescale3, periodstart = attributes.periodstart, _attributes$startnumb = attributes.startnumber, startnumber = _attributes$startnumb === void 0 ? 1 : _attributes$startnumb; return { number: startnumber + number, duration: duration / timescale, timeline: periodstart, time: number * duration }; }; }; /** * returns a list of objects containing segment timing and duration info used for * building the list of segments. this uses the @duration attribute specified * in the mpd manifest to derive the range of segments. * * @param {object} attributes * inherited mpd attributes * @return {{number: number, duration: number, time: number, timeline: number}[]} * list of objects with segment timing and duration info */ var parsebyduration = function parsebyduration(attributes) { var type = attributes.type, duration = attributes.duration, _attributes$timescale4 = attributes.timescale, timescale = _attributes$timescale4 === void 0 ? 1 : _attributes$timescale4, periodduration = attributes.periodduration, sourceduration = attributes.sourceduration; var _segmentrange$type = segmentrange[type](attributes), start = _segmentrange$type.start, end = _segmentrange$type.end; var segments = range(start, end).map(tosegments(attributes)); if (type === 'static') { var index = segments.length - 1; // section is either a period or the full source var sectionduration = typeof periodduration === 'number' ? periodduration : sourceduration; // final segment may be less than full segment duration segments[index].duration = sectionduration - duration / timescale * index; } return segments; }; /** * translates segmentbase into a set of segments. * (dash spec section 5.3.9.3.2) contains a set of nodes. each * node should be translated into segment. * * @param {object} attributes * object containing all inherited attributes from parent elements with attribute * names as keys * @return {object.} list of segments */ var segmentsfrombase = function segmentsfrombase(attributes) { var baseurl = attributes.baseurl, _attributes$initializ = attributes.initialization, initialization = _attributes$initializ === void 0 ? {} : _attributes$initializ, sourceduration = attributes.sourceduration, _attributes$indexrang = attributes.indexrange, indexrange = _attributes$indexrang === void 0 ? '' : _attributes$indexrang, periodstart = attributes.periodstart, presentationtime = attributes.presentationtime, _attributes$number = attributes.number, number = _attributes$number === void 0 ? 0 : _attributes$number, duration = attributes.duration; // base url is required for segmentbase to work, per spec (section 5.3.9.2.1) if (!baseurl) { throw new error(errors.no_base_url); } var initsegment = urltypetosegment({ baseurl: baseurl, source: initialization.sourceurl, range: initialization.range }); var segment = urltypetosegment({ baseurl: baseurl, source: baseurl, indexrange: indexrange }); segment.map = initsegment; // if there is a duration, use it, otherwise use the given duration of the source // (since segmentbase is only for one total segment) if (duration) { var segmenttimeinfo = parsebyduration(attributes); if (segmenttimeinfo.length) { segment.duration = segmenttimeinfo[0].duration; segment.timeline = segmenttimeinfo[0].timeline; } } else if (sourceduration) { segment.duration = sourceduration; segment.timeline = periodstart; } // if presentation time is provided, these segments are being generated by sidx // references, and should use the time provided. for the general case of segmentbase, // there should only be one segment in the period, so its presentation time is the same // as its period start. segment.presentationtime = presentationtime || periodstart; segment.number = number; return [segment]; }; /** * given a playlist, a sidx box, and a baseurl, update the segment list of the playlist * according to the sidx information given. * * playlist.sidx has metadadata about the sidx where-as the sidx param * is the parsed sidx box itself. * * @param {object} playlist the playlist to update the sidx information for * @param {object} sidx the parsed sidx box * @return {object} the playlist object with the updated sidx information */ var addsidxsegmentstoplaylist$1 = function addsidxsegmentstoplaylist(playlist, sidx, baseurl) { // retain init segment information var initsegment = playlist.sidx.map ? playlist.sidx.map : null; // retain source duration from initial main manifest parsing var sourceduration = playlist.sidx.duration; // retain source timeline var timeline = playlist.timeline || 0; var sidxbyterange = playlist.sidx.byterange; var sidxend = sidxbyterange.offset + sidxbyterange.length; // retain timescale of the parsed sidx var timescale = sidx.timescale; // referencetype 1 refers to other sidx boxes var mediareferences = sidx.references.filter(function (r) { return r.referencetype !== 1; }); var segments = []; var type = playlist.endlist ? 'static' : 'dynamic'; var periodstart = playlist.sidx.timeline; var presentationtime = periodstart; var number = playlist.mediasequence || 0; // firstoffset is the offset from the end of the sidx box var startindex; // eslint-disable-next-line if (typeof sidx.firstoffset === 'bigint') { startindex = global_window__webpack_imported_module_1___default.a.bigint(sidxend) + sidx.firstoffset; } else { startindex = sidxend + sidx.firstoffset; } for (var i = 0; i < mediareferences.length; i++) { var reference = sidx.references[i]; // size of the referenced (sub)segment var size = reference.referencedsize; // duration of the referenced (sub)segment, in the timescale // this will be converted to seconds when generating segments var duration = reference.subsegmentduration; // should be an inclusive range var endindex = void 0; // eslint-disable-next-line if (typeof startindex === 'bigint') { endindex = startindex + global_window__webpack_imported_module_1___default.a.bigint(size) - global_window__webpack_imported_module_1___default.a.bigint(1); } else { endindex = startindex + size - 1; } var indexrange = startindex + "-" + endindex; var attributes = { baseurl: baseurl, timescale: timescale, timeline: timeline, periodstart: periodstart, presentationtime: presentationtime, number: number, duration: duration, sourceduration: sourceduration, indexrange: indexrange, type: type }; var segment = segmentsfrombase(attributes)[0]; if (initsegment) { segment.map = initsegment; } segments.push(segment); if (typeof startindex === 'bigint') { startindex += global_window__webpack_imported_module_1___default.a.bigint(size); } else { startindex += size; } presentationtime += duration / timescale; number++; } playlist.segments = segments; return playlist; }; var supported_media_types = ['audio', 'subtitles']; // allow one 60fps frame as leniency (arbitrarily chosen) var time_fudge = 1 / 60; /** * given a list of timelinestarts, combines, dedupes, and sorts them. * * @param {timelinestart[]} timelinestarts - list of timeline starts * * @return {timelinestart[]} the combined and deduped timeline starts */ var getuniquetimelinestarts = function getuniquetimelinestarts(timelinestarts) { return union(timelinestarts, function (_ref) { var timeline = _ref.timeline; return timeline; }).sort(function (a, b) { return a.timeline > b.timeline ? 1 : -1; }); }; /** * finds the playlist with the matching name attribute. * * @param {array} playlists - playlists to search through * @param {string} name - the name attribute to search for * * @return {object|null} the matching playlist object, or null */ var findplaylistwithname = function findplaylistwithname(playlists, name) { for (var i = 0; i < playlists.length; i++) { if (playlists[i].attributes.name === name) { return playlists[i]; } } return null; }; /** * gets a flattened array of media group playlists. * * @param {object} manifest - the main manifest object * * @return {array} the media group playlists */ var getmediagroupplaylists = function getmediagroupplaylists(manifest) { var mediagroupplaylists = []; object(_videojs_vhs_utils_es_media_groups__webpack_imported_module_2__[/* foreachmediagroup */ "a"])(manifest, supported_media_types, function (properties, type, group, label) { mediagroupplaylists = mediagroupplaylists.concat(properties.playlists || []); }); return mediagroupplaylists; }; /** * updates the playlist's media sequence numbers. * * @param {object} config - options object * @param {object} config.playlist - the playlist to update * @param {number} config.mediasequence - the mediasequence number to start with */ var updatemediasequenceforplaylist = function updatemediasequenceforplaylist(_ref2) { var playlist = _ref2.playlist, mediasequence = _ref2.mediasequence; playlist.mediasequence = mediasequence; playlist.segments.foreach(function (segment, index) { segment.number = playlist.mediasequence + index; }); }; /** * updates the media and discontinuity sequence numbers of newplaylists given oldplaylists * and a complete list of timeline starts. * * if no matching playlist is found, only the discontinuity sequence number of the playlist * will be updated. * * since early available timelines are not supported, at least one segment must be present. * * @param {object} config - options object * @param {object[]} oldplaylists - the old playlists to use as a reference * @param {object[]} newplaylists - the new playlists to update * @param {object} timelinestarts - all timelinestarts seen in the stream to this point */ var updatesequencenumbers = function updatesequencenumbers(_ref3) { var oldplaylists = _ref3.oldplaylists, newplaylists = _ref3.newplaylists, timelinestarts = _ref3.timelinestarts; newplaylists.foreach(function (playlist) { playlist.discontinuitysequence = findindex(timelinestarts, function (_ref4) { var timeline = _ref4.timeline; return timeline === playlist.timeline; }); // playlists names come from dash representation ids, which are mandatory // (see iso_23009-1-2012 5.3.5.2). // // if the same representation existed in a prior period, it will retain the same name. var oldplaylist = findplaylistwithname(oldplaylists, playlist.attributes.name); if (!oldplaylist) { // since this is a new playlist, the media sequence values can start from 0 without // consequence. return; } // todo better support for live sidx // // as of this writing, mpd-parser does not support multiperiod sidx (in live or vod). // this is evident by a playlist only having a single sidx reference. in a multiperiod // playlist there would need to be multiple sidx references. in addition, live sidx is // not supported when the sidx properties change on refreshes. // // in the future, if support needs to be added, the merging logic here can be called // after sidx references are resolved. for now, exit early to prevent exceptions being // thrown due to undefined references. if (playlist.sidx) { return; } // since we don't yet support early available timelines, we don't need to support // playlists with no segments. var firstnewsegment = playlist.segments[0]; var oldmatchingsegmentindex = findindex(oldplaylist.segments, function (oldsegment) { return math.abs(oldsegment.presentationtime - firstnewsegment.presentationtime) < time_fudge; }); // no matching segment from the old playlist means the entire playlist was refreshed. // in this case the media sequence should account for this update, and the new segments // should be marked as discontinuous from the prior content, since the last prior // timeline was removed. if (oldmatchingsegmentindex === -1) { updatemediasequenceforplaylist({ playlist: playlist, mediasequence: oldplaylist.mediasequence + oldplaylist.segments.length }); playlist.segments[0].discontinuity = true; playlist.discontinuitystarts.unshift(0); // no matching segment does not necessarily mean there's missing content. // // if the new playlist's timeline is the same as the last seen segment's timeline, // then a discontinuity can be added to identify that there's potentially missing // content. if there's no missing content, the discontinuity should still be rather // harmless. it's possible that if segment durations are accurate enough, that the // existence of a gap can be determined using the presentation times and durations, // but if the segment timing info is off, it may introduce more problems than simply // adding the discontinuity. // // if the new playlist's timeline is different from the last seen segment's timeline, // then a discontinuity can be added to identify that this is the first seen segment // of a new timeline. however, the logic at the start of this function that // determined the disconinuity sequence by timeline index is now off by one (the // discontinuity of the newest timeline hasn't yet fallen off the manifest...since // we added it), so the disconinuity sequence must be decremented. // // a period may also have a duration of zero, so the case of no segments is handled // here even though we don't yet support early available periods. if (!oldplaylist.segments.length && playlist.timeline > oldplaylist.timeline || oldplaylist.segments.length && playlist.timeline > oldplaylist.segments[oldplaylist.segments.length - 1].timeline) { playlist.discontinuitysequence--; } return; } // if the first segment matched with a prior segment on a discontinuity (it's matching // on the first segment of a period), then the discontinuitysequence shouldn't be the // timeline's matching one, but instead should be the one prior, and the first segment // of the new manifest should be marked with a discontinuity. // // the reason for this special case is that discontinuity sequence shows how many // discontinuities have fallen off of the playlist, and discontinuities are marked on // the first segment of a new "timeline." because of this, while dash will retain that // period while the "timeline" exists, hls keeps track of it via the discontinuity // sequence, and that first segment is an indicator, but can be removed before that // timeline is gone. var oldmatchingsegment = oldplaylist.segments[oldmatchingsegmentindex]; if (oldmatchingsegment.discontinuity && !firstnewsegment.discontinuity) { firstnewsegment.discontinuity = true; playlist.discontinuitystarts.unshift(0); playlist.discontinuitysequence--; } updatemediasequenceforplaylist({ playlist: playlist, mediasequence: oldplaylist.segments[oldmatchingsegmentindex].number }); }); }; /** * given an old parsed manifest object and a new parsed manifest object, updates the * sequence and timing values within the new manifest to ensure that it lines up with the * old. * * @param {array} oldmanifest - the old main manifest object * @param {array} newmanifest - the new main manifest object * * @return {object} the updated new manifest object */ var positionmanifestontimeline = function positionmanifestontimeline(_ref5) { var oldmanifest = _ref5.oldmanifest, newmanifest = _ref5.newmanifest; // starting from v4.1.2 of the iop, section 4.4.3.3 states: // // "mpd@availabilitystarttime and period@start shall not be changed over mpd updates." // // this was added from https://github.com/dash-industry-forum/dash-if-iop/issues/160 // // because of this change, and the difficulty of supporting periods with changing start // times, periods with changing start times are not supported. this makes the logic much // simpler, since periods with the same start time can be considerred the same period // across refreshes. // // to give an example as to the difficulty of handling periods where the start time may // change, if a single period manifest is refreshed with another manifest with a single // period, and both the start and end times are increased, then the only way to determine // if it's a new period or an old one that has changed is to look through the segments of // each playlist and determine the presentation time bounds to find a match. in addition, // if the period start changed to exceed the old period end, then there would be no // match, and it would not be possible to determine whether the refreshed period is a new // one or the old one. var oldplaylists = oldmanifest.playlists.concat(getmediagroupplaylists(oldmanifest)); var newplaylists = newmanifest.playlists.concat(getmediagroupplaylists(newmanifest)); // save all seen timelinestarts to the new manifest. although this potentially means that // there's a "memory leak" in that it will never stop growing, in reality, only a couple // of properties are saved for each seen period. even long running live streams won't // generate too many periods, unless the stream is watched for decades. in the future, // this can be optimized by mapping to discontinuity sequence numbers for each timeline, // but it may not become an issue, and the additional info can be useful for debugging. newmanifest.timelinestarts = getuniquetimelinestarts([oldmanifest.timelinestarts, newmanifest.timelinestarts]); updatesequencenumbers({ oldplaylists: oldplaylists, newplaylists: newplaylists, timelinestarts: newmanifest.timelinestarts }); return newmanifest; }; var generatesidxkey = function generatesidxkey(sidx) { return sidx && sidx.uri + '-' + byterangetostring(sidx.byterange); }; var mergediscontiguousplaylists = function mergediscontiguousplaylists(playlists) { var mergedplaylists = values(playlists.reduce(function (acc, playlist) { // assuming playlist ids are the same across periods // todo: handle multiperiod where representation sets are not the same // across periods var name = playlist.attributes.id + (playlist.attributes.lang || ''); if (!acc[name]) { // first period acc[name] = playlist; acc[name].attributes.timelinestarts = []; } else { // subsequent periods if (playlist.segments) { var _acc$name$segments; // first segment of subsequent periods signal a discontinuity if (playlist.segments[0]) { playlist.segments[0].discontinuity = true; } (_acc$name$segments = acc[name].segments).push.apply(_acc$name$segments, playlist.segments); } // bubble up contentprotection, this assumes all drm content // has the same contentprotection if (playlist.attributes.contentprotection) { acc[name].attributes.contentprotection = playlist.attributes.contentprotection; } } acc[name].attributes.timelinestarts.push({ // although they represent the same number, it's important to have both to make it // compatible with hls potentially having a similar attribute. start: playlist.attributes.periodstart, timeline: playlist.attributes.periodstart }); return acc; }, {})); return mergedplaylists.map(function (playlist) { playlist.discontinuitystarts = findindexes(playlist.segments || [], 'discontinuity'); return playlist; }); }; var addsidxsegmentstoplaylist = function addsidxsegmentstoplaylist(playlist, sidxmapping) { var sidxkey = generatesidxkey(playlist.sidx); var sidxmatch = sidxkey && sidxmapping[sidxkey] && sidxmapping[sidxkey].sidx; if (sidxmatch) { addsidxsegmentstoplaylist$1(playlist, sidxmatch, playlist.sidx.resolveduri); } return playlist; }; var addsidxsegmentstoplaylists = function addsidxsegmentstoplaylists(playlists, sidxmapping) { if (sidxmapping === void 0) { sidxmapping = {}; } if (!object.keys(sidxmapping).length) { return playlists; } for (var i in playlists) { playlists[i] = addsidxsegmentstoplaylist(playlists[i], sidxmapping); } return playlists; }; var formataudioplaylist = function formataudioplaylist(_ref, isaudioonly) { var _attributes; var attributes = _ref.attributes, segments = _ref.segments, sidx = _ref.sidx, mediasequence = _ref.mediasequence, discontinuitysequence = _ref.discontinuitysequence, discontinuitystarts = _ref.discontinuitystarts; var playlist = { attributes: (_attributes = { name: attributes.id, bandwidth: attributes.bandwidth, codecs: attributes.codecs }, _attributes['program-id'] = 1, _attributes), uri: '', endlist: attributes.type === 'static', timeline: attributes.periodstart, resolveduri: '', targetduration: attributes.duration, discontinuitysequence: discontinuitysequence, discontinuitystarts: discontinuitystarts, timelinestarts: attributes.timelinestarts, mediasequence: mediasequence, segments: segments }; if (attributes.contentprotection) { playlist.contentprotection = attributes.contentprotection; } if (sidx) { playlist.sidx = sidx; } if (isaudioonly) { playlist.attributes.audio = 'audio'; playlist.attributes.subtitles = 'subs'; } return playlist; }; var formatvttplaylist = function formatvttplaylist(_ref2) { var _m3u8attributes; var attributes = _ref2.attributes, segments = _ref2.segments, mediasequence = _ref2.mediasequence, discontinuitystarts = _ref2.discontinuitystarts, discontinuitysequence = _ref2.discontinuitysequence; if (typeof segments === 'undefined') { // vtt tracks may use single file in baseurl segments = [{ uri: attributes.baseurl, timeline: attributes.periodstart, resolveduri: attributes.baseurl || '', duration: attributes.sourceduration, number: 0 }]; // targetduration should be the same duration as the only segment attributes.duration = attributes.sourceduration; } var m3u8attributes = (_m3u8attributes = { name: attributes.id, bandwidth: attributes.bandwidth }, _m3u8attributes['program-id'] = 1, _m3u8attributes); if (attributes.codecs) { m3u8attributes.codecs = attributes.codecs; } return { attributes: m3u8attributes, uri: '', endlist: attributes.type === 'static', timeline: attributes.periodstart, resolveduri: attributes.baseurl || '', targetduration: attributes.duration, timelinestarts: attributes.timelinestarts, discontinuitystarts: discontinuitystarts, discontinuitysequence: discontinuitysequence, mediasequence: mediasequence, segments: segments }; }; var organizeaudioplaylists = function organizeaudioplaylists(playlists, sidxmapping, isaudioonly) { if (sidxmapping === void 0) { sidxmapping = {}; } if (isaudioonly === void 0) { isaudioonly = false; } var mainplaylist; var formattedplaylists = playlists.reduce(function (a, playlist) { var role = playlist.attributes.role && playlist.attributes.role.value || ''; var language = playlist.attributes.lang || ''; var label = playlist.attributes.label || 'main'; if (language && !playlist.attributes.label) { var rolelabel = role ? " (" + role + ")" : ''; label = "" + playlist.attributes.lang + rolelabel; } if (!a[label]) { a[label] = { language: language, autoselect: true, default: role === 'main', playlists: [], uri: '' }; } var formatted = addsidxsegmentstoplaylist(formataudioplaylist(playlist, isaudioonly), sidxmapping); a[label].playlists.push(formatted); if (typeof mainplaylist === 'undefined' && role === 'main') { mainplaylist = playlist; mainplaylist.default = true; } return a; }, {}); // if no playlists have role "main", mark the first as main if (!mainplaylist) { var firstlabel = object.keys(formattedplaylists)[0]; formattedplaylists[firstlabel].default = true; } return formattedplaylists; }; var organizevttplaylists = function organizevttplaylists(playlists, sidxmapping) { if (sidxmapping === void 0) { sidxmapping = {}; } return playlists.reduce(function (a, playlist) { var label = playlist.attributes.lang || 'text'; if (!a[label]) { a[label] = { language: label, default: false, autoselect: false, playlists: [], uri: '' }; } a[label].playlists.push(addsidxsegmentstoplaylist(formatvttplaylist(playlist), sidxmapping)); return a; }, {}); }; var organizecaptionservices = function organizecaptionservices(captionservices) { return captionservices.reduce(function (svcobj, svc) { if (!svc) { return svcobj; } svc.foreach(function (service) { var channel = service.channel, language = service.language; svcobj[language] = { autoselect: false, default: false, instreamid: channel, language: language }; if (service.hasownproperty('aspectratio')) { svcobj[language].aspectratio = service.aspectratio; } if (service.hasownproperty('easyreader')) { svcobj[language].easyreader = service.easyreader; } if (service.hasownproperty('3d')) { svcobj[language]['3d'] = service['3d']; } }); return svcobj; }, {}); }; var formatvideoplaylist = function formatvideoplaylist(_ref3) { var _attributes2; var attributes = _ref3.attributes, segments = _ref3.segments, sidx = _ref3.sidx, discontinuitystarts = _ref3.discontinuitystarts; var playlist = { attributes: (_attributes2 = { name: attributes.id, audio: 'audio', subtitles: 'subs', resolution: { width: attributes.width, height: attributes.height }, codecs: attributes.codecs, bandwidth: attributes.bandwidth }, _attributes2['program-id'] = 1, _attributes2), uri: '', endlist: attributes.type === 'static', timeline: attributes.periodstart, resolveduri: '', targetduration: attributes.duration, discontinuitystarts: discontinuitystarts, timelinestarts: attributes.timelinestarts, segments: segments }; if (attributes.framerate) { playlist.attributes['frame-rate'] = attributes.framerate; } if (attributes.contentprotection) { playlist.contentprotection = attributes.contentprotection; } if (sidx) { playlist.sidx = sidx; } return playlist; }; var videoonly = function videoonly(_ref4) { var attributes = _ref4.attributes; return attributes.mimetype === 'video/mp4' || attributes.mimetype === 'video/webm' || attributes.contenttype === 'video'; }; var audioonly = function audioonly(_ref5) { var attributes = _ref5.attributes; return attributes.mimetype === 'audio/mp4' || attributes.mimetype === 'audio/webm' || attributes.contenttype === 'audio'; }; var vttonly = function vttonly(_ref6) { var attributes = _ref6.attributes; return attributes.mimetype === 'text/vtt' || attributes.contenttype === 'text'; }; /** * contains start and timeline properties denoting a timeline start. for dash, these will * be the same number. * * @typedef {object} timelinestart * @property {number} start - the start time of the timeline * @property {number} timeline - the timeline number */ /** * adds appropriate media and discontinuity sequence values to the segments and playlists. * * throughout mpd-parser, the `number` attribute is used in relation to `startnumber`, a * dash specific attribute used in constructing segment uri's from templates. however, from * an hls perspective, the `number` attribute on a segment would be its `mediasequence` * value, which should start at the original media sequence value (or 0) and increment by 1 * for each segment thereafter. since dash's `startnumber` values are independent per * period, it doesn't make sense to use it for `number`. instead, assume everything starts * from a 0 mediasequence value and increment from there. * * note that vhs currently doesn't use the `number` property, but it can be helpful for * debugging and making sense of the manifest. * * for live playlists, to account for values increasing in manifests when periods are * removed on refreshes, merging logic should be used to update the numbers to their * appropriate values (to ensure they're sequential and increasing). * * @param {object[]} playlists - the playlists to update * @param {timelinestart[]} timelinestarts - the timeline starts for the manifest */ var addmediasequencevalues = function addmediasequencevalues(playlists, timelinestarts) { // increment all segments sequentially playlists.foreach(function (playlist) { playlist.mediasequence = 0; playlist.discontinuitysequence = findindex(timelinestarts, function (_ref7) { var timeline = _ref7.timeline; return timeline === playlist.timeline; }); if (!playlist.segments) { return; } playlist.segments.foreach(function (segment, index) { segment.number = index; }); }); }; /** * given a media group object, flattens all playlists within the media group into a single * array. * * @param {object} mediagroupobject - the media group object * * @return {object[]} * the media group playlists */ var flattenmediagroupplaylists = function flattenmediagroupplaylists(mediagroupobject) { if (!mediagroupobject) { return []; } return object.keys(mediagroupobject).reduce(function (acc, label) { var labelcontents = mediagroupobject[label]; return acc.concat(labelcontents.playlists); }, []); }; var tom3u8 = function tom3u8(_ref8) { var _mediagroups; var dashplaylists = _ref8.dashplaylists, locations = _ref8.locations, _ref8$sidxmapping = _ref8.sidxmapping, sidxmapping = _ref8$sidxmapping === void 0 ? {} : _ref8$sidxmapping, previousmanifest = _ref8.previousmanifest; if (!dashplaylists.length) { return {}; } // grab all main manifest attributes var _dashplaylists$0$attr = dashplaylists[0].attributes, duration = _dashplaylists$0$attr.sourceduration, type = _dashplaylists$0$attr.type, suggestedpresentationdelay = _dashplaylists$0$attr.suggestedpresentationdelay, minimumupdateperiod = _dashplaylists$0$attr.minimumupdateperiod; var videoplaylists = mergediscontiguousplaylists(dashplaylists.filter(videoonly)).map(formatvideoplaylist); var audioplaylists = mergediscontiguousplaylists(dashplaylists.filter(audioonly)); var vttplaylists = mergediscontiguousplaylists(dashplaylists.filter(vttonly)); var captions = dashplaylists.map(function (playlist) { return playlist.attributes.captionservices; }).filter(boolean); var manifest = { allowcache: true, discontinuitystarts: [], segments: [], endlist: true, mediagroups: (_mediagroups = { audio: {}, video: {} }, _mediagroups['closed-captions'] = {}, _mediagroups.subtitles = {}, _mediagroups), uri: '', duration: duration, playlists: addsidxsegmentstoplaylists(videoplaylists, sidxmapping) }; if (minimumupdateperiod >= 0) { manifest.minimumupdateperiod = minimumupdateperiod * 1000; } if (locations) { manifest.locations = locations; } if (type === 'dynamic') { manifest.suggestedpresentationdelay = suggestedpresentationdelay; } var isaudioonly = manifest.playlists.length === 0; var organizedaudiogroup = audioplaylists.length ? organizeaudioplaylists(audioplaylists, sidxmapping, isaudioonly) : null; var organizedvttgroup = vttplaylists.length ? organizevttplaylists(vttplaylists, sidxmapping) : null; var formattedplaylists = videoplaylists.concat(flattenmediagroupplaylists(organizedaudiogroup), flattenmediagroupplaylists(organizedvttgroup)); var playlisttimelinestarts = formattedplaylists.map(function (_ref9) { var timelinestarts = _ref9.timelinestarts; return timelinestarts; }); manifest.timelinestarts = getuniquetimelinestarts(playlisttimelinestarts); addmediasequencevalues(formattedplaylists, manifest.timelinestarts); if (organizedaudiogroup) { manifest.mediagroups.audio.audio = organizedaudiogroup; } if (organizedvttgroup) { manifest.mediagroups.subtitles.subs = organizedvttgroup; } if (captions.length) { manifest.mediagroups['closed-captions'].cc = organizecaptionservices(captions); } if (previousmanifest) { return positionmanifestontimeline({ oldmanifest: previousmanifest, newmanifest: manifest }); } return manifest; }; /** * calculates the r (repetition) value for a live stream (for the final segment * in a manifest where the r value is negative 1) * * @param {object} attributes * object containing all inherited attributes from parent elements with attribute * names as keys * @param {number} time * current time (typically the total time up until the final segment) * @param {number} duration * duration property for the given * * @return {number} * r value to reach the end of the given period */ var getlivervalue = function getlivervalue(attributes, time, duration) { var now = attributes.now, clientoffset = attributes.clientoffset, availabilitystarttime = attributes.availabilitystarttime, _attributes$timescale = attributes.timescale, timescale = _attributes$timescale === void 0 ? 1 : _attributes$timescale, _attributes$periodsta = attributes.periodstart, periodstart = _attributes$periodsta === void 0 ? 0 : _attributes$periodsta, _attributes$minimumup = attributes.minimumupdateperiod, minimumupdateperiod = _attributes$minimumup === void 0 ? 0 : _attributes$minimumup; var now = (now + clientoffset) / 1000; var periodstartwc = availabilitystarttime + periodstart; var periodendwc = now + minimumupdateperiod; var periodduration = periodendwc - periodstartwc; return math.ceil((periodduration * timescale - time) / duration); }; /** * uses information provided by segmenttemplate.segmenttimeline to determine segment * timing and duration * * @param {object} attributes * object containing all inherited attributes from parent elements with attribute * names as keys * @param {object[]} segmenttimeline * list of objects representing the attributes of each s element contained within * * @return {{number: number, duration: number, time: number, timeline: number}[]} * list of objects with segment timing and duration info */ var parsebytimeline = function parsebytimeline(attributes, segmenttimeline) { var type = attributes.type, _attributes$minimumup2 = attributes.minimumupdateperiod, minimumupdateperiod = _attributes$minimumup2 === void 0 ? 0 : _attributes$minimumup2, _attributes$media = attributes.media, media = _attributes$media === void 0 ? '' : _attributes$media, sourceduration = attributes.sourceduration, _attributes$timescale2 = attributes.timescale, timescale = _attributes$timescale2 === void 0 ? 1 : _attributes$timescale2, _attributes$startnumb = attributes.startnumber, startnumber = _attributes$startnumb === void 0 ? 1 : _attributes$startnumb, timeline = attributes.periodstart; var segments = []; var time = -1; for (var sindex = 0; sindex < segmenttimeline.length; sindex++) { var s = segmenttimeline[sindex]; var duration = s.d; var repeat = s.r || 0; var segmenttime = s.t || 0; if (time < 0) { // first segment time = segmenttime; } if (segmenttime && segmenttime > time) { // discontinuity // todo: how to handle this type of discontinuity // timeline++ here would treat it like hls discontuity and content would // get appended without gap // e.g. // // // // // would have $time$ values of [0, 1, 2, 5] // should this be appened at time positions [0, 1, 2, 3],(#ext-x-discontinuity) // or [0, 1, 2, gap, gap, 5]? (#ext-x-gap) // does the value of sourceduration consider this when calculating arbitrary // negative @r repeat value? // e.g. same elements as above with this added at the end // // with a sourceduration of 10 // would the 2 gaps be included in the time duration calculations resulting in // 8 segments with $time$ values of [0, 1, 2, 5, 6, 7, 8, 9] or 10 segments // with $time$ values of [0, 1, 2, 5, 6, 7, 8, 9, 10, 11] ? time = segmenttime; } var count = void 0; if (repeat < 0) { var nexts = sindex + 1; if (nexts === segmenttimeline.length) { // last segment if (type === 'dynamic' && minimumupdateperiod > 0 && media.indexof('$number$') > 0) { count = getlivervalue(attributes, time, duration); } else { // todo: this may be incorrect depending on conclusion of todo above count = (sourceduration * timescale - time) / duration; } } else { count = (segmenttimeline[nexts].t - time) / duration; } } else { count = repeat + 1; } var end = startnumber + segments.length + count; var number = startnumber + segments.length; while (number < end) { segments.push({ number: number, duration: duration / timescale, time: time, timeline: timeline }); time += duration; number++; } } return segments; }; var identifierpattern = /\$([a-z]*)(?:(%0)([0-9]+)d)?\$/g; /** * replaces template identifiers with corresponding values. to be used as the callback * for string.prototype.replace * * @name replacecallback * @function * @param {string} match * entire match of identifier * @param {string} identifier * name of matched identifier * @param {string} format * format tag string. its presence indicates that padding is expected * @param {string} width * desired length of the replaced value. values less than this width shall be left * zero padded * @return {string} * replacement for the matched identifier */ /** * returns a function to be used as a callback for string.prototype.replace to replace * template identifiers * * @param {obect} values * object containing values that shall be used to replace known identifiers * @param {number} values.representationid * value of the representation@id attribute * @param {number} values.number * number of the corresponding segment * @param {number} values.bandwidth * value of the representation@bandwidth attribute. * @param {number} values.time * timestamp value of the corresponding segment * @return {replacecallback} * callback to be used with string.prototype.replace to replace identifiers */ var identifierreplacement = function identifierreplacement(values) { return function (match, identifier, format, width) { if (match === '$$') { // escape sequence return '$'; } if (typeof values[identifier] === 'undefined') { return match; } var value = '' + values[identifier]; if (identifier === 'representationid') { // format tag shall not be present with representationid return value; } if (!format) { width = 1; } else { width = parseint(width, 10); } if (value.length >= width) { return value; } return "" + new array(width - value.length + 1).join('0') + value; }; }; /** * constructs a segment url from a template string * * @param {string} url * template string to construct url from * @param {obect} values * object containing values that shall be used to replace known identifiers * @param {number} values.representationid * value of the representation@id attribute * @param {number} values.number * number of the corresponding segment * @param {number} values.bandwidth * value of the representation@bandwidth attribute. * @param {number} values.time * timestamp value of the corresponding segment * @return {string} * segment url with identifiers replaced */ var constructtemplateurl = function constructtemplateurl(url, values) { return url.replace(identifierpattern, identifierreplacement(values)); }; /** * generates a list of objects containing timing and duration information about each * segment needed to generate segment uris and the complete segment object * * @param {object} attributes * object containing all inherited attributes from parent elements with attribute * names as keys * @param {object[]|undefined} segmenttimeline * list of objects representing the attributes of each s element contained within * the segmenttimeline element * @return {{number: number, duration: number, time: number, timeline: number}[]} * list of objects with segment timing and duration info */ var parsetemplateinfo = function parsetemplateinfo(attributes, segmenttimeline) { if (!attributes.duration && !segmenttimeline) { // if neither @duration or segmenttimeline are present, then there shall be exactly // one media segment return [{ number: attributes.startnumber || 1, duration: attributes.sourceduration, time: 0, timeline: attributes.periodstart }]; } if (attributes.duration) { return parsebyduration(attributes); } return parsebytimeline(attributes, segmenttimeline); }; /** * generates a list of segments using information provided by the segmenttemplate element * * @param {object} attributes * object containing all inherited attributes from parent elements with attribute * names as keys * @param {object[]|undefined} segmenttimeline * list of objects representing the attributes of each s element contained within * the segmenttimeline element * @return {object[]} * list of segment objects */ var segmentsfromtemplate = function segmentsfromtemplate(attributes, segmenttimeline) { var templatevalues = { representationid: attributes.id, bandwidth: attributes.bandwidth || 0 }; var _attributes$initializ = attributes.initialization, initialization = _attributes$initializ === void 0 ? { sourceurl: '', range: '' } : _attributes$initializ; var mapsegment = urltypetosegment({ baseurl: attributes.baseurl, source: constructtemplateurl(initialization.sourceurl, templatevalues), range: initialization.range }); var segments = parsetemplateinfo(attributes, segmenttimeline); return segments.map(function (segment) { templatevalues.number = segment.number; templatevalues.time = segment.time; var uri = constructtemplateurl(attributes.media || '', templatevalues); // see dash spec section 5.3.9.2.2 // - if timescale isn't present on any level, default to 1. var timescale = attributes.timescale || 1; // - if presentationtimeoffset isn't present on any level, default to 0 var presentationtimeoffset = attributes.presentationtimeoffset || 0; var presentationtime = // even if the @t attribute is not specified for the segment, segment.time is // calculated in mpd-parser prior to this, so it's assumed to be available. attributes.periodstart + (segment.time - presentationtimeoffset) / timescale; var map = { uri: uri, timeline: segment.timeline, duration: segment.duration, resolveduri: object(_videojs_vhs_utils_es_resolve_url__webpack_imported_module_0__[/* default */ "a"])(attributes.baseurl || '', uri), map: mapsegment, number: segment.number, presentationtime: presentationtime }; return map; }); }; /** * converts a (of type urltype from the dash spec 5.3.9.2 table 14) * to an object that matches the output of a segment in videojs/mpd-parser * * @param {object} attributes * object containing all inherited attributes from parent elements with attribute * names as keys * @param {object} segmenturl * node to translate into a segment object * @return {object} translated segment object */ var segmenturltosegmentobject = function segmenturltosegmentobject(attributes, segmenturl) { var baseurl = attributes.baseurl, _attributes$initializ = attributes.initialization, initialization = _attributes$initializ === void 0 ? {} : _attributes$initializ; var initsegment = urltypetosegment({ baseurl: baseurl, source: initialization.sourceurl, range: initialization.range }); var segment = urltypetosegment({ baseurl: baseurl, source: segmenturl.media, range: segmenturl.mediarange }); segment.map = initsegment; return segment; }; /** * generates a list of segments using information provided by the segmentlist element * segmentlist (dash spec section 5.3.9.3.2) contains a set of nodes. each * node should be translated into segment. * * @param {object} attributes * object containing all inherited attributes from parent elements with attribute * names as keys * @param {object[]|undefined} segmenttimeline * list of objects representing the attributes of each s element contained within * the segmenttimeline element * @return {object.} list of segments */ var segmentsfromlist = function segmentsfromlist(attributes, segmenttimeline) { var duration = attributes.duration, _attributes$segmentur = attributes.segmenturls, segmenturls = _attributes$segmentur === void 0 ? [] : _attributes$segmentur, periodstart = attributes.periodstart; // per spec (5.3.9.2.1) no way to determine segment duration or // if both segmenttimeline and @duration are defined, it is outside of spec. if (!duration && !segmenttimeline || duration && segmenttimeline) { throw new error(errors.segment_time_unspecified); } var segmenturlmap = segmenturls.map(function (segmenturlobject) { return segmenturltosegmentobject(attributes, segmenturlobject); }); var segmenttimeinfo; if (duration) { segmenttimeinfo = parsebyduration(attributes); } if (segmenttimeline) { segmenttimeinfo = parsebytimeline(attributes, segmenttimeline); } var segments = segmenttimeinfo.map(function (segmenttime, index) { if (segmenturlmap[index]) { var segment = segmenturlmap[index]; // see dash spec section 5.3.9.2.2 // - if timescale isn't present on any level, default to 1. var timescale = attributes.timescale || 1; // - if presentationtimeoffset isn't present on any level, default to 0 var presentationtimeoffset = attributes.presentationtimeoffset || 0; segment.timeline = segmenttime.timeline; segment.duration = segmenttime.duration; segment.number = segmenttime.number; segment.presentationtime = periodstart + (segmenttime.time - presentationtimeoffset) / timescale; return segment; } // since we're mapping we should get rid of any blank segments (in case // the given segmenttimeline is handling for more elements than we have // segmenturls for). }).filter(function (segment) { return segment; }); return segments; }; var generatesegments = function generatesegments(_ref) { var attributes = _ref.attributes, segmentinfo = _ref.segmentinfo; var segmentattributes; var segmentsfn; if (segmentinfo.template) { segmentsfn = segmentsfromtemplate; segmentattributes = merge(attributes, segmentinfo.template); } else if (segmentinfo.base) { segmentsfn = segmentsfrombase; segmentattributes = merge(attributes, segmentinfo.base); } else if (segmentinfo.list) { segmentsfn = segmentsfromlist; segmentattributes = merge(attributes, segmentinfo.list); } var segmentsinfo = { attributes: attributes }; if (!segmentsfn) { return segmentsinfo; } var segments = segmentsfn(segmentattributes, segmentinfo.segmenttimeline); // the @duration attribute will be used to determin the playlist's targetduration which // must be in seconds. since we've generated the segment list, we no longer need // @duration to be in @timescale units, so we can convert it here. if (segmentattributes.duration) { var _segmentattributes = segmentattributes, duration = _segmentattributes.duration, _segmentattributes$ti = _segmentattributes.timescale, timescale = _segmentattributes$ti === void 0 ? 1 : _segmentattributes$ti; segmentattributes.duration = duration / timescale; } else if (segments.length) { // if there is no @duration attribute, use the largest segment duration as // as target duration segmentattributes.duration = segments.reduce(function (max, segment) { return math.max(max, math.ceil(segment.duration)); }, 0); } else { segmentattributes.duration = 0; } segmentsinfo.attributes = segmentattributes; segmentsinfo.segments = segments; // this is a sidx box without actual segment information if (segmentinfo.base && segmentattributes.indexrange) { segmentsinfo.sidx = segments[0]; segmentsinfo.segments = []; } return segmentsinfo; }; var toplaylists = function toplaylists(representations) { return representations.map(generatesegments); }; var findchildren = function findchildren(element, name) { return from(element.childnodes).filter(function (_ref) { var tagname = _ref.tagname; return tagname === name; }); }; var getcontent = function getcontent(element) { return element.textcontent.trim(); }; /** * converts the provided string that may contain a division operation to a number. * * @param {string} value - the provided string value * * @return {number} the parsed string value */ var parsedivisionvalue = function parsedivisionvalue(value) { return parsefloat(value.split('/').reduce(function (prev, current) { return prev / current; })); }; var parseduration = function parseduration(str) { var seconds_in_year = 365 * 24 * 60 * 60; var seconds_in_month = 30 * 24 * 60 * 60; var seconds_in_day = 24 * 60 * 60; var seconds_in_hour = 60 * 60; var seconds_in_min = 60; // p10y10m10dt10h10m10.1s var durationregex = /p(?:(\d*)y)?(?:(\d*)m)?(?:(\d*)d)?(?:t(?:(\d*)h)?(?:(\d*)m)?(?:([\d.]*)s)?)?/; var match = durationregex.exec(str); if (!match) { return 0; } var _match$slice = match.slice(1), year = _match$slice[0], month = _match$slice[1], day = _match$slice[2], hour = _match$slice[3], minute = _match$slice[4], second = _match$slice[5]; return parsefloat(year || 0) * seconds_in_year + parsefloat(month || 0) * seconds_in_month + parsefloat(day || 0) * seconds_in_day + parsefloat(hour || 0) * seconds_in_hour + parsefloat(minute || 0) * seconds_in_min + parsefloat(second || 0); }; var parsedate = function parsedate(str) { // date format without timezone according to iso 8601 // yyy-mm-ddthh:mm:ss.ssssss var dateregex = /^\d+-\d+-\d+t\d+:\d+:\d+(\.\d+)?$/; // if the date string does not specifiy a timezone, we must specifiy utc. this is // expressed by ending with 'z' if (dateregex.test(str)) { str += 'z'; } return date.parse(str); }; var parsers = { /** * specifies the duration of the entire media presentation. format is a duration string * as specified in iso 8601 * * @param {string} value * value of attribute as a string * @return {number} * the duration in seconds */ mediapresentationduration: function mediapresentationduration(value) { return parseduration(value); }, /** * specifies the segment availability start time for all segments referred to in this * mpd. for a dynamic manifest, it specifies the anchor for the earliest availability * time. format is a date string as specified in iso 8601 * * @param {string} value * value of attribute as a string * @return {number} * the date as seconds from unix epoch */ availabilitystarttime: function availabilitystarttime(value) { return parsedate(value) / 1000; }, /** * specifies the smallest period between potential changes to the mpd. format is a * duration string as specified in iso 8601 * * @param {string} value * value of attribute as a string * @return {number} * the duration in seconds */ minimumupdateperiod: function minimumupdateperiod(value) { return parseduration(value); }, /** * specifies the suggested presentation delay. format is a * duration string as specified in iso 8601 * * @param {string} value * value of attribute as a string * @return {number} * the duration in seconds */ suggestedpresentationdelay: function suggestedpresentationdelay(value) { return parseduration(value); }, /** * specifices the type of mpd. can be either "static" or "dynamic" * * @param {string} value * value of attribute as a string * * @return {string} * the type as a string */ type: function type(value) { return value; }, /** * specifies the duration of the smallest time shifting buffer for any representation * in the mpd. format is a duration string as specified in iso 8601 * * @param {string} value * value of attribute as a string * @return {number} * the duration in seconds */ timeshiftbufferdepth: function timeshiftbufferdepth(value) { return parseduration(value); }, /** * specifies the periodstart time of the period relative to the availabilitystarttime. * format is a duration string as specified in iso 8601 * * @param {string} value * value of attribute as a string * @return {number} * the duration in seconds */ start: function start(value) { return parseduration(value); }, /** * specifies the width of the visual presentation * * @param {string} value * value of attribute as a string * @return {number} * the parsed width */ width: function width(value) { return parseint(value, 10); }, /** * specifies the height of the visual presentation * * @param {string} value * value of attribute as a string * @return {number} * the parsed height */ height: function height(value) { return parseint(value, 10); }, /** * specifies the bitrate of the representation * * @param {string} value * value of attribute as a string * @return {number} * the parsed bandwidth */ bandwidth: function bandwidth(value) { return parseint(value, 10); }, /** * specifies the frame rate of the representation * * @param {string} value * value of attribute as a string * @return {number} * the parsed frame rate */ framerate: function framerate(value) { return parsedivisionvalue(value); }, /** * specifies the number of the first media segment in this representation in the period * * @param {string} value * value of attribute as a string * @return {number} * the parsed number */ startnumber: function startnumber(value) { return parseint(value, 10); }, /** * specifies the timescale in units per seconds * * @param {string} value * value of attribute as a string * @return {number} * the parsed timescale */ timescale: function timescale(value) { return parseint(value, 10); }, /** * specifies the presentationtimeoffset. * * @param {string} value * value of the attribute as a string * * @return {number} * the parsed presentationtimeoffset */ presentationtimeoffset: function presentationtimeoffset(value) { return parseint(value, 10); }, /** * specifies the constant approximate segment duration * note: the element also contains an @duration attribute. this duration * specifies the duration of the period. this attribute is currently not * supported by the rest of the parser, however we still check for it to prevent * errors. * * @param {string} value * value of attribute as a string * @return {number} * the parsed duration */ duration: function duration(value) { var parsedvalue = parseint(value, 10); if (isnan(parsedvalue)) { return parseduration(value); } return parsedvalue; }, /** * specifies the segment duration, in units of the value of the @timescale. * * @param {string} value * value of attribute as a string * @return {number} * the parsed duration */ d: function d(value) { return parseint(value, 10); }, /** * specifies the mpd start time, in @timescale units, the first segment in the series * starts relative to the beginning of the period * * @param {string} value * value of attribute as a string * @return {number} * the parsed time */ t: function t(value) { return parseint(value, 10); }, /** * specifies the repeat count of the number of following contiguous segments with the * same duration expressed by the value of @d * * @param {string} value * value of attribute as a string * @return {number} * the parsed number */ r: function r(value) { return parseint(value, 10); }, /** * default parser for all other attributes. acts as a no-op and just returns the value * as a string * * @param {string} value * value of attribute as a string * @return {string} * unparsed value */ default: function default(value) { return value; } }; /** * gets all the attributes and values of the provided node, parses attributes with known * types, and returns an object with attribute names mapped to values. * * @param {node} el * the node to parse attributes from * @return {object} * object with all attributes of el parsed */ var parseattributes = function parseattributes(el) { if (!(el && el.attributes)) { return {}; } return from(el.attributes).reduce(function (a, e) { var parsefn = parsers[e.name] || parsers.default; a[e.name] = parsefn(e.value); return a; }, {}); }; var keysystemsmap = { 'urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b': 'org.w3.clearkey', 'urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed': 'com.widevine.alpha', 'urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95': 'com.microsoft.playready', 'urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb': 'com.adobe.primetime' }; /** * builds a list of urls that is the product of the reference urls and baseurl values * * @param {string[]} referenceurls * list of reference urls to resolve to * @param {node[]} baseurlelements * list of baseurl nodes from the mpd * @return {string[]} * list of resolved urls */ var buildbaseurls = function buildbaseurls(referenceurls, baseurlelements) { if (!baseurlelements.length) { return referenceurls; } return flatten(referenceurls.map(function (reference) { return baseurlelements.map(function (baseurlelement) { return object(_videojs_vhs_utils_es_resolve_url__webpack_imported_module_0__[/* default */ "a"])(reference, getcontent(baseurlelement)); }); })); }; /** * contains all segment information for its containing adaptationset * * @typedef {object} segmentinformation * @property {object|undefined} template * contains the attributes for the segmenttemplate node * @property {object[]|undefined} segmenttimeline * contains a list of atrributes for each s node within the segmenttimeline node * @property {object|undefined} list * contains the attributes for the segmentlist node * @property {object|undefined} base * contains the attributes for the segmentbase node */ /** * returns all available segment information contained within the adaptationset node * * @param {node} adaptationset * the adaptationset node to get segment information from * @return {segmentinformation} * the segment information contained within the provided adaptationset */ var getsegmentinformation = function getsegmentinformation(adaptationset) { var segmenttemplate = findchildren(adaptationset, 'segmenttemplate')[0]; var segmentlist = findchildren(adaptationset, 'segmentlist')[0]; var segmenturls = segmentlist && findchildren(segmentlist, 'segmenturl').map(function (s) { return merge({ tag: 'segmenturl' }, parseattributes(s)); }); var segmentbase = findchildren(adaptationset, 'segmentbase')[0]; var segmenttimelineparentnode = segmentlist || segmenttemplate; var segmenttimeline = segmenttimelineparentnode && findchildren(segmenttimelineparentnode, 'segmenttimeline')[0]; var segmentinitializationparentnode = segmentlist || segmentbase || segmenttemplate; var segmentinitialization = segmentinitializationparentnode && findchildren(segmentinitializationparentnode, 'initialization')[0]; // segmenttemplate is handled slightly differently, since it can have both // @initialization and an node. @initialization can be templated, // while the node can have a url and range specified. if the has // both @initialization and an subelement we opt to override with // the node, as this interaction is not defined in the spec. var template = segmenttemplate && parseattributes(segmenttemplate); if (template && segmentinitialization) { template.initialization = segmentinitialization && parseattributes(segmentinitialization); } else if (template && template.initialization) { // if it is @initialization we convert it to an object since this is the format that // later functions will rely on for the initialization segment. this is only valid // for template.initialization = { sourceurl: template.initialization }; } var segmentinfo = { template: template, segmenttimeline: segmenttimeline && findchildren(segmenttimeline, 's').map(function (s) { return parseattributes(s); }), list: segmentlist && merge(parseattributes(segmentlist), { segmenturls: segmenturls, initialization: parseattributes(segmentinitialization) }), base: segmentbase && merge(parseattributes(segmentbase), { initialization: parseattributes(segmentinitialization) }) }; object.keys(segmentinfo).foreach(function (key) { if (!segmentinfo[key]) { delete segmentinfo[key]; } }); return segmentinfo; }; /** * contains segment information and attributes needed to construct a playlist object * from a representation * * @typedef {object} representationinformation * @property {segmentinformation} segmentinfo * segment information for this representation * @property {object} attributes * inherited attributes for this representation */ /** * maps a representation node to an object containing segment information and attributes * * @name inheritbaseurlscallback * @function * @param {node} representation * representation node from the mpd * @return {representationinformation} * representation information needed to construct a playlist object */ /** * returns a callback for array.prototype.map for mapping representation nodes to * segment information and attributes using inherited baseurl nodes. * * @param {object} adaptationsetattributes * contains attributes inherited by the adaptationset * @param {string[]} adaptationsetbaseurls * contains list of resolved base urls inherited by the adaptationset * @param {segmentinformation} adaptationsetsegmentinfo * contains segment information for the adaptationset * @return {inheritbaseurlscallback} * callback map function */ var inheritbaseurls = function inheritbaseurls(adaptationsetattributes, adaptationsetbaseurls, adaptationsetsegmentinfo) { return function (representation) { var repbaseurlelements = findchildren(representation, 'baseurl'); var repbaseurls = buildbaseurls(adaptationsetbaseurls, repbaseurlelements); var attributes = merge(adaptationsetattributes, parseattributes(representation)); var representationsegmentinfo = getsegmentinformation(representation); return repbaseurls.map(function (baseurl) { return { segmentinfo: merge(adaptationsetsegmentinfo, representationsegmentinfo), attributes: merge(attributes, { baseurl: baseurl }) }; }); }; }; /** * tranforms a series of content protection nodes to * an object containing pssh data by key system * * @param {node[]} contentprotectionnodes * content protection nodes * @return {object} * object containing pssh data by key system */ var generatekeysysteminformation = function generatekeysysteminformation(contentprotectionnodes) { return contentprotectionnodes.reduce(function (acc, node) { var attributes = parseattributes(node); // although it could be argued that according to the uuid rfc spec the uuid string (a-f chars) should be generated // as a lowercase string it also mentions it should be treated as case-insensitive on input. since the key system // uuids in the keysystemsmap are hardcoded as lowercase in the codebase there isn't any reason not to do // .tolowercase() on the input uuid string from the manifest (at least i could not think of one). if (attributes.schemeiduri) { attributes.schemeiduri = attributes.schemeiduri.tolowercase(); } var keysystem = keysystemsmap[attributes.schemeiduri]; if (keysystem) { acc[keysystem] = { attributes: attributes }; var psshnode = findchildren(node, 'cenc:pssh')[0]; if (psshnode) { var pssh = getcontent(psshnode); acc[keysystem].pssh = pssh && object(_videojs_vhs_utils_es_decode_b64_to_uint8_array__webpack_imported_module_3__[/* default */ "a"])(pssh); } } return acc; }, {}); }; // defined in ansi_scte 214-1 2016 var parsecaptionservicemetadata = function parsecaptionservicemetadata(service) { // 608 captions if (service.schemeiduri === 'urn:scte:dash:cc:cea-608:2015') { var values = typeof service.value !== 'string' ? [] : service.value.split(';'); return values.map(function (value) { var channel; var language; // default language to value language = value; if (/^cc\d=/.test(value)) { var _value$split = value.split('='); channel = _value$split[0]; language = _value$split[1]; } else if (/^cc\d$/.test(value)) { channel = value; } return { channel: channel, language: language }; }); } else if (service.schemeiduri === 'urn:scte:dash:cc:cea-708:2015') { var _values = typeof service.value !== 'string' ? [] : service.value.split(';'); return _values.map(function (value) { var flags = { // service or channel number 1-63 'channel': undefined, // language is a 3alpha per iso 639.2/b // field is required 'language': undefined, // bit 1/0 or ? // default value is 1, meaning 16:9 aspect ratio, 0 is 4:3, ? is unknown 'aspectratio': 1, // bit 1/0 // easy reader flag indicated the text is tailed to the needs of beginning readers // default 0, or off 'easyreader': 0, // bit 1/0 // if 3d metadata is present (cea-708.1) then 1 // default 0 '3d': 0 }; if (/=/.test(value)) { var _value$split2 = value.split('='), channel = _value$split2[0], _value$split2$ = _value$split2[1], opts = _value$split2$ === void 0 ? '' : _value$split2$; flags.channel = channel; flags.language = value; opts.split(',').foreach(function (opt) { var _opt$split = opt.split(':'), name = _opt$split[0], val = _opt$split[1]; if (name === 'lang') { flags.language = val; // er for easyreadery } else if (name === 'er') { flags.easyreader = number(val); // war for wide aspect ratio } else if (name === 'war') { flags.aspectratio = number(val); } else if (name === '3d') { flags['3d'] = number(val); } }); } else { flags.language = value; } if (flags.channel) { flags.channel = 'service' + flags.channel; } return flags; }); } }; /** * maps an adaptationset node to a list of representation information objects * * @name torepresentationscallback * @function * @param {node} adaptationset * adaptationset node from the mpd * @return {representationinformation[]} * list of objects containing representaion information */ /** * returns a callback for array.prototype.map for mapping adaptationset nodes to a list of * representation information objects * * @param {object} periodattributes * contains attributes inherited by the period * @param {string[]} periodbaseurls * contains list of resolved base urls inherited by the period * @param {string[]} periodsegmentinfo * contains segment information at the period level * @return {torepresentationscallback} * callback map function */ var torepresentations = function torepresentations(periodattributes, periodbaseurls, periodsegmentinfo) { return function (adaptationset) { var adaptationsetattributes = parseattributes(adaptationset); var adaptationsetbaseurls = buildbaseurls(periodbaseurls, findchildren(adaptationset, 'baseurl')); var role = findchildren(adaptationset, 'role')[0]; var roleattributes = { role: parseattributes(role) }; var attrs = merge(periodattributes, adaptationsetattributes, roleattributes); var accessibility = findchildren(adaptationset, 'accessibility')[0]; var captionservices = parsecaptionservicemetadata(parseattributes(accessibility)); if (captionservices) { attrs = merge(attrs, { captionservices: captionservices }); } var label = findchildren(adaptationset, 'label')[0]; if (label && label.childnodes.length) { var labelval = label.childnodes[0].nodevalue.trim(); attrs = merge(attrs, { label: labelval }); } var contentprotection = generatekeysysteminformation(findchildren(adaptationset, 'contentprotection')); if (object.keys(contentprotection).length) { attrs = merge(attrs, { contentprotection: contentprotection }); } var segmentinfo = getsegmentinformation(adaptationset); var representations = findchildren(adaptationset, 'representation'); var adaptationsetsegmentinfo = merge(periodsegmentinfo, segmentinfo); return flatten(representations.map(inheritbaseurls(attrs, adaptationsetbaseurls, adaptationsetsegmentinfo))); }; }; /** * contains all period information for mapping nodes onto adaptation sets. * * @typedef {object} periodinformation * @property {node} period.node * period node from the mpd * @property {object} period.attributes * parsed period attributes from node plus any added */ /** * maps a periodinformation object to a list of representation information objects for all * adaptationset nodes contained within the period. * * @name toadaptationsetscallback * @function * @param {periodinformation} period * period object containing necessary period information * @param {number} periodstart * start time of the period within the mpd * @return {representationinformation[]} * list of objects containing representaion information */ /** * returns a callback for array.prototype.map for mapping period nodes to a list of * representation information objects * * @param {object} mpdattributes * contains attributes inherited by the mpd * @param {string[]} mpdbaseurls * contains list of resolved base urls inherited by the mpd * @return {toadaptationsetscallback} * callback map function */ var toadaptationsets = function toadaptationsets(mpdattributes, mpdbaseurls) { return function (period, index) { var periodbaseurls = buildbaseurls(mpdbaseurls, findchildren(period.node, 'baseurl')); var periodattributes = merge(mpdattributes, { periodstart: period.attributes.start }); if (typeof period.attributes.duration === 'number') { periodattributes.periodduration = period.attributes.duration; } var adaptationsets = findchildren(period.node, 'adaptationset'); var periodsegmentinfo = getsegmentinformation(period.node); return flatten(adaptationsets.map(torepresentations(periodattributes, periodbaseurls, periodsegmentinfo))); }; }; /** * gets period@start property for a given period. * * @param {object} options * options object * @param {object} options.attributes * period attributes * @param {object} [options.priorperiodattributes] * prior period attributes (if prior period is available) * @param {string} options.mpdtype * the mpd@type these periods came from * @return {number|null} * the period start, or null if it's an early available period or error */ var getperiodstart = function getperiodstart(_ref) { var attributes = _ref.attributes, priorperiodattributes = _ref.priorperiodattributes, mpdtype = _ref.mpdtype; // summary of period start time calculation from dash spec section 5.3.2.1 // // a period's start is the first period's start + time elapsed after playing all // prior periods to this one. periods continue one after the other in time (without // gaps) until the end of the presentation. // // the value of period@start should be: // 1. if period@start is present: value of period@start // 2. if previous period exists and it has @duration: previous period@start + // previous period@duration // 3. if this is first period and mpd@type is 'static': 0 // 4. in all other cases, consider the period an "early available period" (note: not // currently supported) // (1) if (typeof attributes.start === 'number') { return attributes.start; } // (2) if (priorperiodattributes && typeof priorperiodattributes.start === 'number' && typeof priorperiodattributes.duration === 'number') { return priorperiodattributes.start + priorperiodattributes.duration; } // (3) if (!priorperiodattributes && mpdtype === 'static') { return 0; } // (4) // there is currently no logic for calculating the period@start value if there is // no period@start or prior period@start and period@duration available. this is not made // explicit by the dash interop guidelines or the dash spec, however, since there's // nothing about any other resolution strategies, it's implied. thus, this case should // be considered an early available period, or error, and null should suffice for both // of those cases. return null; }; /** * traverses the mpd xml tree to generate a list of representation information objects * that have inherited attributes from parent nodes * * @param {node} mpd * the root node of the mpd * @param {object} options * available options for inheritattributes * @param {string} options.manifesturi * the uri source of the mpd * @param {number} options.now * current time per dash iop. default is current time in ms since epoch * @param {number} options.clientoffset * client time difference from now (in milliseconds) * @return {representationinformation[]} * list of objects containing representation information */ var inheritattributes = function inheritattributes(mpd, options) { if (options === void 0) { options = {}; } var _options = options, _options$manifesturi = _options.manifesturi, manifesturi = _options$manifesturi === void 0 ? '' : _options$manifesturi, _options$now = _options.now, now = _options$now === void 0 ? date.now() : _options$now, _options$clientoffset = _options.clientoffset, clientoffset = _options$clientoffset === void 0 ? 0 : _options$clientoffset; var periodnodes = findchildren(mpd, 'period'); if (!periodnodes.length) { throw new error(errors.invalid_number_of_period); } var locations = findchildren(mpd, 'location'); var mpdattributes = parseattributes(mpd); var mpdbaseurls = buildbaseurls([manifesturi], findchildren(mpd, 'baseurl')); // see dash spec section 5.3.1.2, semantics of mpd element. default type to 'static'. mpdattributes.type = mpdattributes.type || 'static'; mpdattributes.sourceduration = mpdattributes.mediapresentationduration || 0; mpdattributes.now = now; mpdattributes.clientoffset = clientoffset; if (locations.length) { mpdattributes.locations = locations.map(getcontent); } var periods = []; // since toadaptationsets acts on individual periods right now, the simplest approach to // adding properties that require looking at prior periods is to parse attributes and add // missing ones before toadaptationsets is called. if more such properties are added, it // may be better to refactor toadaptationsets. periodnodes.foreach(function (node, index) { var attributes = parseattributes(node); // use the last modified prior period, as it may contain added information necessary // for this period. var priorperiod = periods[index - 1]; attributes.start = getperiodstart({ attributes: attributes, priorperiodattributes: priorperiod ? priorperiod.attributes : null, mpdtype: mpdattributes.type }); periods.push({ node: node, attributes: attributes }); }); return { locations: mpdattributes.locations, representationinfo: flatten(periods.map(toadaptationsets(mpdattributes, mpdbaseurls))) }; }; var stringtompdxml = function stringtompdxml(manifeststring) { if (manifeststring === '') { throw new error(errors.dash_empty_manifest); } var parser = new _xmldom_xmldom__webpack_imported_module_4__["domparser"](); var xml; var mpd; try { xml = parser.parsefromstring(manifeststring, 'application/xml'); mpd = xml && xml.documentelement.tagname === 'mpd' ? xml.documentelement : null; } catch (e) {// ie 11 throwsw on invalid xml } if (!mpd || mpd && mpd.getelementsbytagname('parsererror').length > 0) { throw new error(errors.dash_invalid_xml); } return mpd; }; /** * parses the manifest for a utctiming node, returning the nodes attributes if found * * @param {string} mpd * xml string of the mpd manifest * @return {object|null} * attributes of utctiming node specified in the manifest. null if none found */ var parseutctimingscheme = function parseutctimingscheme(mpd) { var utctimingnode = findchildren(mpd, 'utctiming')[0]; if (!utctimingnode) { return null; } var attributes = parseattributes(utctimingnode); switch (attributes.schemeiduri) { case 'urn:mpeg:dash:utc:http-head:2014': case 'urn:mpeg:dash:utc:http-head:2012': attributes.method = 'head'; break; case 'urn:mpeg:dash:utc:http-xsdate:2014': case 'urn:mpeg:dash:utc:http-iso:2014': case 'urn:mpeg:dash:utc:http-xsdate:2012': case 'urn:mpeg:dash:utc:http-iso:2012': attributes.method = 'get'; break; case 'urn:mpeg:dash:utc:direct:2014': case 'urn:mpeg:dash:utc:direct:2012': attributes.method = 'direct'; attributes.value = date.parse(attributes.value); break; case 'urn:mpeg:dash:utc:http-ntp:2014': case 'urn:mpeg:dash:utc:ntp:2014': case 'urn:mpeg:dash:utc:sntp:2014': default: throw new error(errors.unsupported_utc_timing_scheme); } return attributes; }; var version = version; /* * given a dash manifest string and options, parses the dash manifest into an object in the * form outputed by m3u8-parser and accepted by videojs/http-streaming. * * for live dash manifests, if `previousmanifest` is provided in options, then the newly * parsed dash manifest will have its media sequence and discontinuity sequence values * updated to reflect its position relative to the prior manifest. * * @param {string} manifeststring - the dash manifest as a string * @param {options} [options] - any options * * @return {object} the manifest object */ var parse = function parse(manifeststring, options) { if (options === void 0) { options = {}; } var parsedmanifestinfo = inheritattributes(stringtompdxml(manifeststring), options); var playlists = toplaylists(parsedmanifestinfo.representationinfo); return tom3u8({ dashplaylists: playlists, locations: parsedmanifestinfo.locations, sidxmapping: options.sidxmapping, previousmanifest: options.previousmanifest }); }; /** * parses the manifest for a utctiming node, returning the nodes attributes if found * * @param {string} manifeststring * xml string of the mpd manifest * @return {object|null} * attributes of utctiming node specified in the manifest. null if none found */ var parseutctiming = function parseutctiming(manifeststring) { return parseutctimingscheme(stringtompdxml(manifeststring)); }; /***/ }), /***/ 7: /***/ (function(module, exports) { // source: http://jsfiddle.net/vwx8v/ // http://stackoverflow.com/questions/5603195/full-list-of-javascript-keycodes /** * conenience method returns corresponding value for given keyname or keycode. * * @param {mixed} keycode {number} or keyname {string} * @return {mixed} * @api public */ function keycode(searchinput) { // keyboard events if (searchinput && 'object' === typeof searchinput) { var haskeycode = searchinput.which || searchinput.keycode || searchinput.charcode if (haskeycode) searchinput = haskeycode } // numbers if ('number' === typeof searchinput) return names[searchinput] // everything else (cast to string) var search = string(searchinput) // check codes var foundnamedkey = codes[search.tolowercase()] if (foundnamedkey) return foundnamedkey // check aliases var foundnamedkey = aliases[search.tolowercase()] if (foundnamedkey) return foundnamedkey // weird character? if (search.length === 1) return search.charcodeat(0) return undefined } /** * compares a keyboard event with a given keycode or keyname. * * @param {event} event keyboard event that should be tested * @param {mixed} keycode {number} or keyname {string} * @return {boolean} * @api public */ keycode.iseventkey = function iseventkey(event, nameorcode) { if (event && 'object' === typeof event) { var keycode = event.which || event.keycode || event.charcode if (keycode === null || keycode === undefined) { return false; } if (typeof nameorcode === 'string') { // check codes var foundnamedkey = codes[nameorcode.tolowercase()] if (foundnamedkey) { return foundnamedkey === keycode; } // check aliases var foundnamedkey = aliases[nameorcode.tolowercase()] if (foundnamedkey) { return foundnamedkey === keycode; } } else if (typeof nameorcode === 'number') { return nameorcode === keycode; } return false; } } exports = module.exports = keycode; /** * get by name * * exports.code['enter'] // => 13 */ var codes = exports.code = exports.codes = { 'backspace': 8, 'tab': 9, 'enter': 13, 'shift': 16, 'ctrl': 17, 'alt': 18, 'pause/break': 19, 'caps lock': 20, 'esc': 27, 'space': 32, 'page up': 33, 'page down': 34, 'end': 35, 'home': 36, 'left': 37, 'up': 38, 'right': 39, 'down': 40, 'insert': 45, 'delete': 46, 'command': 91, 'left command': 91, 'right command': 93, 'numpad *': 106, 'numpad +': 107, 'numpad -': 109, 'numpad .': 110, 'numpad /': 111, 'num lock': 144, 'scroll lock': 145, 'my computer': 182, 'my calculator': 183, ';': 186, '=': 187, ',': 188, '-': 189, '.': 190, '/': 191, '`': 192, '[': 219, '\\': 220, ']': 221, "'": 222 } // helper aliases var aliases = exports.aliases = { 'windows': 91, '⇧': 16, '⌥': 18, '⌃': 17, '⌘': 91, 'ctl': 17, 'control': 17, 'option': 18, 'pause': 19, 'break': 19, 'caps': 20, 'return': 13, 'escape': 27, 'spc': 32, 'spacebar': 32, 'pgup': 33, 'pgdn': 34, 'ins': 45, 'del': 46, 'cmd': 91 } /*! * programatically add the following */ // lower case chars for (i = 97; i < 123; i++) codes[string.fromcharcode(i)] = i - 32 // numbers for (var i = 48; i < 58; i++) codes[i - 48] = i // function keys for (i = 1; i < 13; i++) codes['f'+i] = i + 111 // numpad keys for (i = 0; i < 10; i++) codes['numpad '+i] = i + 96 /** * get by code * * exports.name[13] // => 'enter' */ var names = exports.names = exports.title = {} // title for backward compat // create reverse mapping for (i in codes) names[codes[i]] = i // add aliases for (var alias in aliases) { codes[alias] = aliases[alias] } /***/ }) }]);