import { __commonJS, __toESM } from "./chunk-QWN5BXRD.js"; // node_modules/global/window.js var require_window = __commonJS({ "node_modules/global/window.js"(exports, module) { var win; if (typeof window !== "undefined") { win = window; } else if (typeof global !== "undefined") { win = global; } else if (typeof self !== "undefined") { win = self; } else { win = {}; } module.exports = win; } }); // browser-external:min-document var require_min_document = __commonJS({ "browser-external:min-document"(exports, module) { module.exports = Object.create(new Proxy({}, { get(_, key) { if (key !== "__esModule" && key !== "__proto__" && key !== "constructor" && key !== "splice") { console.warn(`Module "min-document" has been externalized for browser compatibility. Cannot access "min-document.${key}" in client code. See https://vitejs.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`); } } })); } }); // node_modules/global/document.js var require_document = __commonJS({ "node_modules/global/document.js"(exports, module) { var topLevel = typeof global !== "undefined" ? global : typeof window !== "undefined" ? window : {}; var minDoc = require_min_document(); var doccy; if (typeof document !== "undefined") { doccy = document; } else { doccy = topLevel["__GLOBAL_DOCUMENT_CACHE@4"]; if (!doccy) { doccy = topLevel["__GLOBAL_DOCUMENT_CACHE@4"] = minDoc; } } module.exports = doccy; } }); // node_modules/@babel/runtime/helpers/extends.js var require_extends = __commonJS({ "node_modules/@babel/runtime/helpers/extends.js"(exports, module) { function _extends2() { module.exports = _extends2 = Object.assign ? Object.assign.bind() : function(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }, module.exports.__esModule = true, module.exports["default"] = module.exports; return _extends2.apply(this, arguments); } module.exports = _extends2, module.exports.__esModule = true, module.exports["default"] = module.exports; } }); // node_modules/is-function/index.js var require_is_function = __commonJS({ "node_modules/is-function/index.js"(exports, module) { module.exports = isFunction; var toString2 = Object.prototype.toString; function isFunction(fn) { if (!fn) { return false; } var string = toString2.call(fn); return string === "[object Function]" || typeof fn === "function" && string !== "[object RegExp]" || typeof window !== "undefined" && // IE8 and below (fn === window.setTimeout || fn === window.alert || fn === window.confirm || fn === window.prompt); } } }); // node_modules/@videojs/xhr/lib/interceptors.js var require_interceptors = __commonJS({ "node_modules/@videojs/xhr/lib/interceptors.js"(exports, module) { "use strict"; function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } var InterceptorsStorage = function() { function InterceptorsStorage2() { this.typeToInterceptorsMap_ = /* @__PURE__ */ new Map(); this.enabled_ = false; } var _proto = InterceptorsStorage2.prototype; _proto.getIsEnabled = function getIsEnabled() { return this.enabled_; }; _proto.enable = function enable() { this.enabled_ = true; }; _proto.disable = function disable() { this.enabled_ = false; }; _proto.reset = function reset2() { this.typeToInterceptorsMap_ = /* @__PURE__ */ new Map(); this.enabled_ = false; }; _proto.addInterceptor = function addInterceptor(type, interceptor) { if (!this.typeToInterceptorsMap_.has(type)) { this.typeToInterceptorsMap_.set(type, /* @__PURE__ */ new Set()); } var interceptorsSet = this.typeToInterceptorsMap_.get(type); if (interceptorsSet.has(interceptor)) { return false; } interceptorsSet.add(interceptor); return true; }; _proto.removeInterceptor = function removeInterceptor(type, interceptor) { var interceptorsSet = this.typeToInterceptorsMap_.get(type); if (interceptorsSet && interceptorsSet.has(interceptor)) { interceptorsSet.delete(interceptor); return true; } return false; }; _proto.clearInterceptorsByType = function clearInterceptorsByType(type) { var interceptorsSet = this.typeToInterceptorsMap_.get(type); if (!interceptorsSet) { return false; } this.typeToInterceptorsMap_.delete(type); this.typeToInterceptorsMap_.set(type, /* @__PURE__ */ new Set()); return true; }; _proto.clear = function clear() { if (!this.typeToInterceptorsMap_.size) { return false; } this.typeToInterceptorsMap_ = /* @__PURE__ */ new Map(); return true; }; _proto.getForType = function getForType(type) { return this.typeToInterceptorsMap_.get(type) || /* @__PURE__ */ new Set(); }; _proto.execute = function execute(type, payload) { var interceptors = this.getForType(type); for (var _iterator = _createForOfIteratorHelperLoose(interceptors), _step; !(_step = _iterator()).done; ) { var interceptor = _step.value; try { payload = interceptor(payload); } catch (e) { } } return payload; }; return InterceptorsStorage2; }(); module.exports = InterceptorsStorage; } }); // node_modules/@videojs/xhr/lib/retry.js var require_retry = __commonJS({ "node_modules/@videojs/xhr/lib/retry.js"(exports, module) { "use strict"; var RetryManager = function() { function RetryManager2() { this.maxAttempts_ = 1; this.delayFactor_ = 0.1; this.fuzzFactor_ = 0.1; this.initialDelay_ = 1e3; this.enabled_ = false; } var _proto = RetryManager2.prototype; _proto.getIsEnabled = function getIsEnabled() { return this.enabled_; }; _proto.enable = function enable() { this.enabled_ = true; }; _proto.disable = function disable() { this.enabled_ = false; }; _proto.reset = function reset2() { this.maxAttempts_ = 1; this.delayFactor_ = 0.1; this.fuzzFactor_ = 0.1; this.initialDelay_ = 1e3; this.enabled_ = false; }; _proto.getMaxAttempts = function getMaxAttempts() { return this.maxAttempts_; }; _proto.setMaxAttempts = function setMaxAttempts(maxAttempts) { this.maxAttempts_ = maxAttempts; }; _proto.getDelayFactor = function getDelayFactor() { return this.delayFactor_; }; _proto.setDelayFactor = function setDelayFactor(delayFactor) { this.delayFactor_ = delayFactor; }; _proto.getFuzzFactor = function getFuzzFactor() { return this.fuzzFactor_; }; _proto.setFuzzFactor = function setFuzzFactor(fuzzFactor) { this.fuzzFactor_ = fuzzFactor; }; _proto.getInitialDelay = function getInitialDelay() { return this.initialDelay_; }; _proto.setInitialDelay = function setInitialDelay(initialDelay) { this.initialDelay_ = initialDelay; }; _proto.createRetry = function createRetry(_temp) { var _ref = _temp === void 0 ? {} : _temp, maxAttempts = _ref.maxAttempts, delayFactor = _ref.delayFactor, fuzzFactor = _ref.fuzzFactor, initialDelay = _ref.initialDelay; return new Retry({ maxAttempts: maxAttempts || this.maxAttempts_, delayFactor: delayFactor || this.delayFactor_, fuzzFactor: fuzzFactor || this.fuzzFactor_, initialDelay: initialDelay || this.initialDelay_ }); }; return RetryManager2; }(); var Retry = function() { function Retry2(options) { this.maxAttempts_ = options.maxAttempts; this.delayFactor_ = options.delayFactor; this.fuzzFactor_ = options.fuzzFactor; this.currentDelay_ = options.initialDelay; this.currentAttempt_ = 1; } var _proto2 = Retry2.prototype; _proto2.moveToNextAttempt = function moveToNextAttempt() { this.currentAttempt_++; var delayDelta = this.currentDelay_ * this.delayFactor_; this.currentDelay_ = this.currentDelay_ + delayDelta; }; _proto2.shouldRetry = function shouldRetry() { return this.currentAttempt_ < this.maxAttempts_; }; _proto2.getCurrentDelay = function getCurrentDelay() { return this.currentDelay_; }; _proto2.getCurrentMinPossibleDelay = function getCurrentMinPossibleDelay() { return (1 - this.fuzzFactor_) * this.currentDelay_; }; _proto2.getCurrentMaxPossibleDelay = function getCurrentMaxPossibleDelay() { return (1 + this.fuzzFactor_) * this.currentDelay_; }; _proto2.getCurrentFuzzedDelay = function getCurrentFuzzedDelay() { var lowValue = this.getCurrentMinPossibleDelay(); var highValue = this.getCurrentMaxPossibleDelay(); return lowValue + Math.random() * (highValue - lowValue); }; return Retry2; }(); module.exports = RetryManager; } }); // node_modules/@videojs/xhr/lib/http-handler.js var require_http_handler = __commonJS({ "node_modules/@videojs/xhr/lib/http-handler.js"(exports, module) { "use strict"; var window7 = require_window(); var httpResponseHandler = function httpResponseHandler2(callback, decodeResponseBody) { if (decodeResponseBody === void 0) { decodeResponseBody = false; } return function(err, response, responseBody) { if (err) { callback(err); return; } if (response.statusCode >= 400 && response.statusCode <= 599) { var cause = responseBody; if (decodeResponseBody) { if (window7.TextDecoder) { var charset = getCharset(response.headers && response.headers["content-type"]); try { cause = new TextDecoder(charset).decode(responseBody); } catch (e) { } } else { cause = String.fromCharCode.apply(null, new Uint8Array(responseBody)); } } callback({ cause }); return; } callback(null, responseBody); }; }; function getCharset(contentTypeHeader) { if (contentTypeHeader === void 0) { contentTypeHeader = ""; } return contentTypeHeader.toLowerCase().split(";").reduce(function(charset, contentType) { var _contentType$split = contentType.split("="), type = _contentType$split[0], value = _contentType$split[1]; if (type.trim() === "charset") { return value.trim(); } return charset; }, "utf-8"); } module.exports = httpResponseHandler; } }); // node_modules/@videojs/xhr/lib/index.js var require_lib = __commonJS({ "node_modules/@videojs/xhr/lib/index.js"(exports, module) { "use strict"; var window7 = require_window(); var _extends2 = require_extends(); var isFunction = require_is_function(); var InterceptorsStorage = require_interceptors(); var RetryManager = require_retry(); createXHR.httpHandler = require_http_handler(); createXHR.requestInterceptorsStorage = new InterceptorsStorage(); createXHR.responseInterceptorsStorage = new InterceptorsStorage(); createXHR.retryManager = new RetryManager(); var parseHeaders = function parseHeaders2(headers) { var result = {}; if (!headers) { return result; } headers.trim().split("\n").forEach(function(row) { var index = row.indexOf(":"); var key = row.slice(0, index).trim().toLowerCase(); var value = row.slice(index + 1).trim(); if (typeof result[key] === "undefined") { result[key] = value; } else if (Array.isArray(result[key])) { result[key].push(value); } else { result[key] = [result[key], value]; } }); return result; }; module.exports = createXHR; module.exports.default = createXHR; createXHR.XMLHttpRequest = window7.XMLHttpRequest || noop2; createXHR.XDomainRequest = "withCredentials" in new createXHR.XMLHttpRequest() ? createXHR.XMLHttpRequest : window7.XDomainRequest; forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) { createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) { options = initParams(uri, options, callback); options.method = method.toUpperCase(); return _createXHR(options); }; }); function forEachArray(array, iterator) { for (var i = 0; i < array.length; i++) { iterator(array[i]); } } function isEmpty(obj) { for (var i in obj) { if (obj.hasOwnProperty(i)) return false; } return true; } function initParams(uri, options, callback) { var params = uri; if (isFunction(options)) { callback = options; if (typeof uri === "string") { params = { uri }; } } else { params = _extends2({}, options, { uri }); } params.callback = callback; return params; } function createXHR(uri, options, callback) { options = initParams(uri, options, callback); return _createXHR(options); } function _createXHR(options) { if (typeof options.callback === "undefined") { throw new Error("callback argument missing"); } if (options.requestType && createXHR.requestInterceptorsStorage.getIsEnabled()) { var requestInterceptorPayload = { uri: options.uri || options.url, headers: options.headers || {}, body: options.body, metadata: options.metadata || {}, retry: options.retry, timeout: options.timeout }; var updatedPayload = createXHR.requestInterceptorsStorage.execute(options.requestType, requestInterceptorPayload); options.uri = updatedPayload.uri; options.headers = updatedPayload.headers; options.body = updatedPayload.body; options.metadata = updatedPayload.metadata; options.retry = updatedPayload.retry; options.timeout = updatedPayload.timeout; } var called = false; var callback = function cbOnce(err, response, body2) { if (!called) { called = true; options.callback(err, response, body2); } }; function readystatechange() { if (xhr.readyState === 4 && !createXHR.responseInterceptorsStorage.getIsEnabled()) { setTimeout(loadFunc, 0); } } function getBody() { var body2 = void 0; if (xhr.response) { body2 = xhr.response; } else { body2 = xhr.responseText || getXml(xhr); } if (isJson) { try { body2 = JSON.parse(body2); } catch (e) { } } return body2; } function errorFunc(evt) { clearTimeout(timeoutTimer); clearTimeout(options.retryTimeout); if (!(evt instanceof Error)) { evt = new Error("" + (evt || "Unknown XMLHttpRequest Error")); } evt.statusCode = 0; if (!aborted && createXHR.retryManager.getIsEnabled() && options.retry && options.retry.shouldRetry()) { options.retryTimeout = setTimeout(function() { options.retry.moveToNextAttempt(); options.xhr = xhr; _createXHR(options); }, options.retry.getCurrentFuzzedDelay()); return; } if (options.requestType && createXHR.responseInterceptorsStorage.getIsEnabled()) { var responseInterceptorPayload = { headers: failureResponse.headers || {}, body: failureResponse.body, responseUrl: xhr.responseURL, responseType: xhr.responseType }; var _updatedPayload = createXHR.responseInterceptorsStorage.execute(options.requestType, responseInterceptorPayload); failureResponse.body = _updatedPayload.body; failureResponse.headers = _updatedPayload.headers; } return callback(evt, failureResponse); } function loadFunc() { if (aborted) return; var status; clearTimeout(timeoutTimer); clearTimeout(options.retryTimeout); if (options.useXDR && xhr.status === void 0) { status = 200; } else { status = xhr.status === 1223 ? 204 : xhr.status; } var response = failureResponse; var err = null; if (status !== 0) { response = { body: getBody(), statusCode: status, method, headers: {}, url: uri, rawRequest: xhr }; if (xhr.getAllResponseHeaders) { response.headers = parseHeaders(xhr.getAllResponseHeaders()); } } else { err = new Error("Internal XMLHttpRequest Error"); } if (options.requestType && createXHR.responseInterceptorsStorage.getIsEnabled()) { var responseInterceptorPayload = { headers: response.headers || {}, body: response.body, responseUrl: xhr.responseURL, responseType: xhr.responseType }; var _updatedPayload2 = createXHR.responseInterceptorsStorage.execute(options.requestType, responseInterceptorPayload); response.body = _updatedPayload2.body; response.headers = _updatedPayload2.headers; } return callback(err, response, response.body); } var xhr = options.xhr || null; if (!xhr) { if (options.cors || options.useXDR) { xhr = new createXHR.XDomainRequest(); } else { xhr = new createXHR.XMLHttpRequest(); } } var key; var aborted; var uri = xhr.url = options.uri || options.url; var method = xhr.method = options.method || "GET"; var body = options.body || options.data; var headers = xhr.headers = options.headers || {}; var sync = !!options.sync; var isJson = false; var timeoutTimer; var failureResponse = { body: void 0, headers: {}, statusCode: 0, method, url: uri, rawRequest: xhr }; if ("json" in options && options.json !== false) { isJson = true; headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json"); if (method !== "GET" && method !== "HEAD") { headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json"); body = JSON.stringify(options.json === true ? body : options.json); } } xhr.onreadystatechange = readystatechange; xhr.onload = loadFunc; xhr.onerror = errorFunc; xhr.onprogress = function() { }; xhr.onabort = function() { aborted = true; clearTimeout(options.retryTimeout); }; xhr.ontimeout = errorFunc; xhr.open(method, uri, !sync, options.username, options.password); if (!sync) { xhr.withCredentials = !!options.withCredentials; } if (!sync && options.timeout > 0) { timeoutTimer = setTimeout(function() { if (aborted) return; aborted = true; xhr.abort("timeout"); var e = new Error("XMLHttpRequest timeout"); e.code = "ETIMEDOUT"; errorFunc(e); }, options.timeout); } if (xhr.setRequestHeader) { for (key in headers) { if (headers.hasOwnProperty(key)) { xhr.setRequestHeader(key, headers[key]); } } } else if (options.headers && !isEmpty(options.headers)) { throw new Error("Headers cannot be set on an XDomainRequest object"); } if ("responseType" in options) { xhr.responseType = options.responseType; } if ("beforeSend" in options && typeof options.beforeSend === "function") { options.beforeSend(xhr); } xhr.send(body || null); return xhr; } function getXml(xhr) { try { if (xhr.responseType === "document") { return xhr.responseXML; } var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror"; if (xhr.responseType === "" && !firefoxBugTakenEffect) { return xhr.responseXML; } } catch (e) { } return null; } function noop2() { } } }); // node_modules/videojs-vtt.js/lib/vtt.js var require_vtt = __commonJS({ "node_modules/videojs-vtt.js/lib/vtt.js"(exports, module) { var document2 = require_document(); var _objCreate = Object.create || /* @__PURE__ */ function() { function F() { } return function(o) { if (arguments.length !== 1) { throw new Error("Object.create shim only accepts one parameter."); } F.prototype = o; return new F(); }; }(); function ParsingError(errorData, message) { this.name = "ParsingError"; this.code = errorData.code; this.message = message || errorData.message; } ParsingError.prototype = _objCreate(Error.prototype); ParsingError.prototype.constructor = ParsingError; ParsingError.Errors = { BadSignature: { code: 0, message: "Malformed WebVTT signature." }, BadTimeStamp: { code: 1, message: "Malformed time stamp." } }; function parseTimeStamp(input) { function computeSeconds(h, m2, s, f) { return (h | 0) * 3600 + (m2 | 0) * 60 + (s | 0) + (f | 0) / 1e3; } var m = input.match(/^(\d+):(\d{1,2})(:\d{1,2})?\.(\d{3})/); if (!m) { return null; } if (m[3]) { return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]); } else if (m[1] > 59) { return computeSeconds(m[1], m[2], 0, m[4]); } else { return computeSeconds(0, m[1], m[2], m[4]); } } function Settings() { this.values = _objCreate(null); } Settings.prototype = { // Only accept the first assignment to any key. set: function(k, v) { if (!this.get(k) && v !== "") { this.values[k] = v; } }, // Return the value for a key, or a default value. // If 'defaultKey' is passed then 'dflt' is assumed to be an object with // a number of possible default values as properties where 'defaultKey' is // the key of the property that will be chosen; otherwise it's assumed to be // a single value. get: function(k, dflt, defaultKey) { if (defaultKey) { return this.has(k) ? this.values[k] : dflt[defaultKey]; } return this.has(k) ? this.values[k] : dflt; }, // Check whether we have a value for a key. has: function(k) { return k in this.values; }, // Accept a setting if its one of the given alternatives. alt: function(k, v, a) { for (var n = 0; n < a.length; ++n) { if (v === a[n]) { this.set(k, v); break; } } }, // Accept a setting if its a valid (signed) integer. integer: function(k, v) { if (/^-?\d+$/.test(v)) { this.set(k, parseInt(v, 10)); } }, // Accept a setting if its a valid percentage. percent: function(k, v) { var m; if (m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/)) { v = parseFloat(v); if (v >= 0 && v <= 100) { this.set(k, v); return true; } } return false; } }; function parseOptions(input, callback, keyValueDelim, groupDelim) { var groups = groupDelim ? input.split(groupDelim) : [input]; for (var i in groups) { if (typeof groups[i] !== "string") { continue; } var kv = groups[i].split(keyValueDelim); if (kv.length !== 2) { continue; } var k = kv[0].trim(); var v = kv[1].trim(); callback(k, v); } } function parseCue(input, cue, regionList) { var oInput = input; function consumeTimeStamp() { var ts2 = parseTimeStamp(input); if (ts2 === null) { throw new ParsingError( ParsingError.Errors.BadTimeStamp, "Malformed timestamp: " + oInput ); } input = input.replace(/^[^\sa-zA-Z-]+/, ""); return ts2; } function consumeCueSettings(input2, cue2) { var settings = new Settings(); parseOptions(input2, function(k, v) { switch (k) { case "region": for (var i = regionList.length - 1; i >= 0; i--) { if (regionList[i].id === v) { settings.set(k, regionList[i].region); break; } } break; case "vertical": settings.alt(k, v, ["rl", "lr"]); break; case "line": var vals = v.split(","), vals0 = vals[0]; settings.integer(k, vals0); settings.percent(k, vals0) ? settings.set("snapToLines", false) : null; settings.alt(k, vals0, ["auto"]); if (vals.length === 2) { settings.alt("lineAlign", vals[1], ["start", "center", "end"]); } break; case "position": vals = v.split(","); settings.percent(k, vals[0]); if (vals.length === 2) { settings.alt("positionAlign", vals[1], ["start", "center", "end"]); } break; case "size": settings.percent(k, v); break; case "align": settings.alt(k, v, ["start", "center", "end", "left", "right"]); break; } }, /:/, /\s/); cue2.region = settings.get("region", null); cue2.vertical = settings.get("vertical", ""); try { cue2.line = settings.get("line", "auto"); } catch (e) { } cue2.lineAlign = settings.get("lineAlign", "start"); cue2.snapToLines = settings.get("snapToLines", true); cue2.size = settings.get("size", 100); try { cue2.align = settings.get("align", "center"); } catch (e) { cue2.align = settings.get("align", "middle"); } try { cue2.position = settings.get("position", "auto"); } catch (e) { cue2.position = settings.get("position", { start: 0, left: 0, center: 50, middle: 50, end: 100, right: 100 }, cue2.align); } cue2.positionAlign = settings.get("positionAlign", { start: "start", left: "start", center: "center", middle: "center", end: "end", right: "end" }, cue2.align); } function skipWhitespace() { input = input.replace(/^\s+/, ""); } skipWhitespace(); cue.startTime = consumeTimeStamp(); skipWhitespace(); if (input.substr(0, 3) !== "-->") { throw new ParsingError( ParsingError.Errors.BadTimeStamp, "Malformed time stamp (time stamps must be separated by '-->'): " + oInput ); } input = input.substr(3); skipWhitespace(); cue.endTime = consumeTimeStamp(); skipWhitespace(); consumeCueSettings(input, cue); } var TEXTAREA_ELEMENT = document2.createElement && document2.createElement("textarea"); var TAG_NAME = { c: "span", i: "i", b: "b", u: "u", ruby: "ruby", rt: "rt", v: "span", lang: "span" }; var DEFAULT_COLOR_CLASS = { white: "rgba(255,255,255,1)", lime: "rgba(0,255,0,1)", cyan: "rgba(0,255,255,1)", red: "rgba(255,0,0,1)", yellow: "rgba(255,255,0,1)", magenta: "rgba(255,0,255,1)", blue: "rgba(0,0,255,1)", black: "rgba(0,0,0,1)" }; var TAG_ANNOTATION = { v: "title", lang: "lang" }; var NEEDS_PARENT = { rt: "ruby" }; function parseContent(window7, input) { function nextToken() { if (!input) { return null; } function consume(result) { input = input.substr(result.length); return result; } var m2 = input.match(/^([^<]*)(<[^>]*>?)?/); return consume(m2[1] ? m2[1] : m2[2]); } function unescape2(s) { TEXTAREA_ELEMENT.innerHTML = s; s = TEXTAREA_ELEMENT.textContent; TEXTAREA_ELEMENT.textContent = ""; return s; } function shouldAdd(current2, element) { return !NEEDS_PARENT[element.localName] || NEEDS_PARENT[element.localName] === current2.localName; } function createElement(type, annotation) { var tagName = TAG_NAME[type]; if (!tagName) { return null; } var element = window7.document.createElement(tagName); var name = TAG_ANNOTATION[type]; if (name && annotation) { element[name] = annotation.trim(); } return element; } var rootDiv = window7.document.createElement("div"), current = rootDiv, t, tagStack = []; while ((t = nextToken()) !== null) { if (t[0] === "<") { if (t[1] === "/") { if (tagStack.length && tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) { tagStack.pop(); current = current.parentNode; } continue; } var ts2 = parseTimeStamp(t.substr(1, t.length - 2)); var node; if (ts2) { node = window7.document.createProcessingInstruction("timestamp", ts2); current.appendChild(node); continue; } var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/); if (!m) { continue; } node = createElement(m[1], m[3]); if (!node) { continue; } if (!shouldAdd(current, node)) { continue; } if (m[2]) { var classes = m[2].split("."); classes.forEach(function(cl) { var bgColor = /^bg_/.test(cl); var colorName = bgColor ? cl.slice(3) : cl; if (DEFAULT_COLOR_CLASS.hasOwnProperty(colorName)) { var propName = bgColor ? "background-color" : "color"; var propValue = DEFAULT_COLOR_CLASS[colorName]; node.style[propName] = propValue; } }); node.className = classes.join(" "); } tagStack.push(m[1]); current.appendChild(node); current = node; continue; } current.appendChild(window7.document.createTextNode(unescape2(t))); } return rootDiv; } var strongRTLRanges = [ [1470, 1470], [1472, 1472], [1475, 1475], [1478, 1478], [1488, 1514], [1520, 1524], [1544, 1544], [1547, 1547], [1549, 1549], [1563, 1563], [1566, 1610], [1645, 1647], [1649, 1749], [1765, 1766], [1774, 1775], [1786, 1805], [1807, 1808], [1810, 1839], [1869, 1957], [1969, 1969], [1984, 2026], [2036, 2037], [2042, 2042], [2048, 2069], [2074, 2074], [2084, 2084], [2088, 2088], [2096, 2110], [2112, 2136], [2142, 2142], [2208, 2208], [2210, 2220], [8207, 8207], [64285, 64285], [64287, 64296], [64298, 64310], [64312, 64316], [64318, 64318], [64320, 64321], [64323, 64324], [64326, 64449], [64467, 64829], [64848, 64911], [64914, 64967], [65008, 65020], [65136, 65140], [65142, 65276], [67584, 67589], [67592, 67592], [67594, 67637], [67639, 67640], [67644, 67644], [67647, 67669], [67671, 67679], [67840, 67867], [67872, 67897], [67903, 67903], [67968, 68023], [68030, 68031], [68096, 68096], [68112, 68115], [68117, 68119], [68121, 68147], [68160, 68167], [68176, 68184], [68192, 68223], [68352, 68405], [68416, 68437], [68440, 68466], [68472, 68479], [68608, 68680], [126464, 126467], [126469, 126495], [126497, 126498], [126500, 126500], [126503, 126503], [126505, 126514], [126516, 126519], [126521, 126521], [126523, 126523], [126530, 126530], [126535, 126535], [126537, 126537], [126539, 126539], [126541, 126543], [126545, 126546], [126548, 126548], [126551, 126551], [126553, 126553], [126555, 126555], [126557, 126557], [126559, 126559], [126561, 126562], [126564, 126564], [126567, 126570], [126572, 126578], [126580, 126583], [126585, 126588], [126590, 126590], [126592, 126601], [126603, 126619], [126625, 126627], [126629, 126633], [126635, 126651], [1114109, 1114109] ]; function isStrongRTLChar(charCode) { for (var i = 0; i < strongRTLRanges.length; i++) { var currentRange = strongRTLRanges[i]; if (charCode >= currentRange[0] && charCode <= currentRange[1]) { return true; } } return false; } function determineBidi(cueDiv) { var nodeStack = [], text = "", charCode; if (!cueDiv || !cueDiv.childNodes) { return "ltr"; } function pushNodes(nodeStack2, node) { for (var i2 = node.childNodes.length - 1; i2 >= 0; i2--) { nodeStack2.push(node.childNodes[i2]); } } function nextTextNode(nodeStack2) { if (!nodeStack2 || !nodeStack2.length) { return null; } var node = nodeStack2.pop(), text2 = node.textContent || node.innerText; if (text2) { var m = text2.match(/^.*(\n|\r)/); if (m) { nodeStack2.length = 0; return m[0]; } return text2; } if (node.tagName === "ruby") { return nextTextNode(nodeStack2); } if (node.childNodes) { pushNodes(nodeStack2, node); return nextTextNode(nodeStack2); } } pushNodes(nodeStack, cueDiv); while (text = nextTextNode(nodeStack)) { for (var i = 0; i < text.length; i++) { charCode = text.charCodeAt(i); if (isStrongRTLChar(charCode)) { return "rtl"; } } } return "ltr"; } function computeLinePos(cue) { if (typeof cue.line === "number" && (cue.snapToLines || cue.line >= 0 && cue.line <= 100)) { return cue.line; } if (!cue.track || !cue.track.textTrackList || !cue.track.textTrackList.mediaElement) { return -1; } var track = cue.track, trackList = track.textTrackList, count = 0; for (var i = 0; i < trackList.length && trackList[i] !== track; i++) { if (trackList[i].mode === "showing") { count++; } } return ++count * -1; } function StyleBox() { } StyleBox.prototype.applyStyles = function(styles, div) { div = div || this.div; for (var prop in styles) { if (styles.hasOwnProperty(prop)) { div.style[prop] = styles[prop]; } } }; StyleBox.prototype.formatStyle = function(val, unit) { return val === 0 ? 0 : val + unit; }; function CueStyleBox(window7, cue, styleOptions) { StyleBox.call(this); this.cue = cue; this.cueDiv = parseContent(window7, cue.text); var styles = { color: "rgba(255, 255, 255, 1)", backgroundColor: "rgba(0, 0, 0, 0.8)", position: "relative", left: 0, right: 0, top: 0, bottom: 0, display: "inline", writingMode: cue.vertical === "" ? "horizontal-tb" : cue.vertical === "lr" ? "vertical-lr" : "vertical-rl", unicodeBidi: "plaintext" }; this.applyStyles(styles, this.cueDiv); this.div = window7.document.createElement("div"); styles = { direction: determineBidi(this.cueDiv), writingMode: cue.vertical === "" ? "horizontal-tb" : cue.vertical === "lr" ? "vertical-lr" : "vertical-rl", unicodeBidi: "plaintext", textAlign: cue.align === "middle" ? "center" : cue.align, font: styleOptions.font, whiteSpace: "pre-line", position: "absolute" }; this.applyStyles(styles); this.div.appendChild(this.cueDiv); var textPos = 0; switch (cue.positionAlign) { case "start": case "line-left": textPos = cue.position; break; case "center": textPos = cue.position - cue.size / 2; break; case "end": case "line-right": textPos = cue.position - cue.size; break; } if (cue.vertical === "") { this.applyStyles({ left: this.formatStyle(textPos, "%"), width: this.formatStyle(cue.size, "%") }); } else { this.applyStyles({ top: this.formatStyle(textPos, "%"), height: this.formatStyle(cue.size, "%") }); } this.move = function(box) { this.applyStyles({ top: this.formatStyle(box.top, "px"), bottom: this.formatStyle(box.bottom, "px"), left: this.formatStyle(box.left, "px"), right: this.formatStyle(box.right, "px"), height: this.formatStyle(box.height, "px"), width: this.formatStyle(box.width, "px") }); }; } CueStyleBox.prototype = _objCreate(StyleBox.prototype); CueStyleBox.prototype.constructor = CueStyleBox; function BoxPosition(obj) { var lh, height, width, top; if (obj.div) { height = obj.div.offsetHeight; width = obj.div.offsetWidth; top = obj.div.offsetTop; var rects = (rects = obj.div.childNodes) && (rects = rects[0]) && rects.getClientRects && rects.getClientRects(); obj = obj.div.getBoundingClientRect(); lh = rects ? Math.max(rects[0] && rects[0].height || 0, obj.height / rects.length) : 0; } this.left = obj.left; this.right = obj.right; this.top = obj.top || top; this.height = obj.height || height; this.bottom = obj.bottom || top + (obj.height || height); this.width = obj.width || width; this.lineHeight = lh !== void 0 ? lh : obj.lineHeight; } BoxPosition.prototype.move = function(axis, toMove) { toMove = toMove !== void 0 ? toMove : this.lineHeight; switch (axis) { case "+x": this.left += toMove; this.right += toMove; break; case "-x": this.left -= toMove; this.right -= toMove; break; case "+y": this.top += toMove; this.bottom += toMove; break; case "-y": this.top -= toMove; this.bottom -= toMove; break; } }; BoxPosition.prototype.overlaps = function(b2) { return this.left < b2.right && this.right > b2.left && this.top < b2.bottom && this.bottom > b2.top; }; BoxPosition.prototype.overlapsAny = function(boxes) { for (var i = 0; i < boxes.length; i++) { if (this.overlaps(boxes[i])) { return true; } } return false; }; BoxPosition.prototype.within = function(container) { return this.top >= container.top && this.bottom <= container.bottom && this.left >= container.left && this.right <= container.right; }; BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) { switch (axis) { case "+x": return this.left < container.left; case "-x": return this.right > container.right; case "+y": return this.top < container.top; case "-y": return this.bottom > container.bottom; } }; BoxPosition.prototype.intersectPercentage = function(b2) { var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)), y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)), intersectArea = x * y; return intersectArea / (this.height * this.width); }; BoxPosition.prototype.toCSSCompatValues = function(reference) { return { top: this.top - reference.top, bottom: reference.bottom - this.bottom, left: this.left - reference.left, right: reference.right - this.right, height: this.height, width: this.width }; }; BoxPosition.getSimpleBoxPosition = function(obj) { var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0; var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0; var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0; obj = obj.div ? obj.div.getBoundingClientRect() : obj.tagName ? obj.getBoundingClientRect() : obj; var ret = { left: obj.left, right: obj.right, top: obj.top || top, height: obj.height || height, bottom: obj.bottom || top + (obj.height || height), width: obj.width || width }; return ret; }; function moveBoxToLinePosition(window7, styleBox, containerBox, boxPositions) { function findBestPosition(b, axis2) { var bestPosition2, specifiedPosition = new BoxPosition(b), percentage = 1; for (var i = 0; i < axis2.length; i++) { while (b.overlapsOppositeAxis(containerBox, axis2[i]) || b.within(containerBox) && b.overlapsAny(boxPositions)) { b.move(axis2[i]); } if (b.within(containerBox)) { return b; } var p = b.intersectPercentage(containerBox); if (percentage > p) { bestPosition2 = new BoxPosition(b); percentage = p; } b = new BoxPosition(specifiedPosition); } return bestPosition2 || specifiedPosition; } var boxPosition = new BoxPosition(styleBox), cue = styleBox.cue, linePos = computeLinePos(cue), axis = []; if (cue.snapToLines) { var size; switch (cue.vertical) { case "": axis = ["+y", "-y"]; size = "height"; break; case "rl": axis = ["+x", "-x"]; size = "width"; break; case "lr": axis = ["-x", "+x"]; size = "width"; break; } var step = boxPosition.lineHeight, position = step * Math.round(linePos), maxPosition = containerBox[size] + step, initialAxis = axis[0]; if (Math.abs(position) > maxPosition) { position = position < 0 ? -1 : 1; position *= Math.ceil(maxPosition / step) * step; } if (linePos < 0) { position += cue.vertical === "" ? containerBox.height : containerBox.width; axis = axis.reverse(); } boxPosition.move(initialAxis, position); } else { var calculatedPercentage = boxPosition.lineHeight / containerBox.height * 100; switch (cue.lineAlign) { case "center": linePos -= calculatedPercentage / 2; break; case "end": linePos -= calculatedPercentage; break; } switch (cue.vertical) { case "": styleBox.applyStyles({ top: styleBox.formatStyle(linePos, "%") }); break; case "rl": styleBox.applyStyles({ left: styleBox.formatStyle(linePos, "%") }); break; case "lr": styleBox.applyStyles({ right: styleBox.formatStyle(linePos, "%") }); break; } axis = ["+y", "-x", "+x", "-y"]; boxPosition = new BoxPosition(styleBox); } var bestPosition = findBestPosition(boxPosition, axis); styleBox.move(bestPosition.toCSSCompatValues(containerBox)); } function WebVTT2() { } WebVTT2.StringDecoder = function() { return { decode: function(data) { if (!data) { return ""; } if (typeof data !== "string") { throw new Error("Error - expected string data."); } return decodeURIComponent(encodeURIComponent(data)); } }; }; WebVTT2.convertCueToDOMTree = function(window7, cuetext) { if (!window7 || !cuetext) { return null; } return parseContent(window7, cuetext); }; var FONT_SIZE_PERCENT = 0.05; var FONT_STYLE = "sans-serif"; var CUE_BACKGROUND_PADDING = "1.5%"; WebVTT2.processCues = function(window7, cues, overlay) { if (!window7 || !cues || !overlay) { return null; } while (overlay.firstChild) { overlay.removeChild(overlay.firstChild); } var paddedOverlay = window7.document.createElement("div"); paddedOverlay.style.position = "absolute"; paddedOverlay.style.left = "0"; paddedOverlay.style.right = "0"; paddedOverlay.style.top = "0"; paddedOverlay.style.bottom = "0"; paddedOverlay.style.margin = CUE_BACKGROUND_PADDING; overlay.appendChild(paddedOverlay); function shouldCompute(cues2) { for (var i2 = 0; i2 < cues2.length; i2++) { if (cues2[i2].hasBeenReset || !cues2[i2].displayState) { return true; } } return false; } if (!shouldCompute(cues)) { for (var i = 0; i < cues.length; i++) { paddedOverlay.appendChild(cues[i].displayState); } return; } var boxPositions = [], containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay), fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100; var styleOptions = { font: fontSize + "px " + FONT_STYLE }; (function() { var styleBox, cue; for (var i2 = 0; i2 < cues.length; i2++) { cue = cues[i2]; styleBox = new CueStyleBox(window7, cue, styleOptions); paddedOverlay.appendChild(styleBox.div); moveBoxToLinePosition(window7, styleBox, containerBox, boxPositions); cue.displayState = styleBox.div; boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox)); } })(); }; WebVTT2.Parser = function(window7, vttjs, decoder) { if (!decoder) { decoder = vttjs; vttjs = {}; } if (!vttjs) { vttjs = {}; } this.window = window7; this.vttjs = vttjs; this.state = "INITIAL"; this.buffer = ""; this.decoder = decoder || new TextDecoder("utf8"); this.regionList = []; }; WebVTT2.Parser.prototype = { // If the error is a ParsingError then report it to the consumer if // possible. If it's not a ParsingError then throw it like normal. reportOrThrowError: function(e) { if (e instanceof ParsingError) { this.onparsingerror && this.onparsingerror(e); } else { throw e; } }, parse: function(data) { var self2 = this; if (data) { self2.buffer += self2.decoder.decode(data, { stream: true }); } function collectNextLine() { var buffer = self2.buffer; var pos = 0; while (pos < buffer.length && buffer[pos] !== "\r" && buffer[pos] !== "\n") { ++pos; } var line2 = buffer.substr(0, pos); if (buffer[pos] === "\r") { ++pos; } if (buffer[pos] === "\n") { ++pos; } self2.buffer = buffer.substr(pos); return line2; } function parseRegion(input) { var settings = new Settings(); parseOptions(input, function(k, v) { switch (k) { case "id": settings.set(k, v); break; case "width": settings.percent(k, v); break; case "lines": settings.integer(k, v); break; case "regionanchor": case "viewportanchor": var xy = v.split(","); if (xy.length !== 2) { break; } var anchor = new Settings(); anchor.percent("x", xy[0]); anchor.percent("y", xy[1]); if (!anchor.has("x") || !anchor.has("y")) { break; } settings.set(k + "X", anchor.get("x")); settings.set(k + "Y", anchor.get("y")); break; case "scroll": settings.alt(k, v, ["up"]); break; } }, /=/, /\s/); if (settings.has("id")) { var region = new (self2.vttjs.VTTRegion || self2.window.VTTRegion)(); region.width = settings.get("width", 100); region.lines = settings.get("lines", 3); region.regionAnchorX = settings.get("regionanchorX", 0); region.regionAnchorY = settings.get("regionanchorY", 100); region.viewportAnchorX = settings.get("viewportanchorX", 0); region.viewportAnchorY = settings.get("viewportanchorY", 100); region.scroll = settings.get("scroll", ""); self2.onregion && self2.onregion(region); self2.regionList.push({ id: settings.get("id"), region }); } } function parseTimestampMap(input) { var settings = new Settings(); parseOptions(input, function(k, v) { switch (k) { case "MPEGT": settings.integer(k + "S", v); break; case "LOCA": settings.set(k + "L", parseTimeStamp(v)); break; } }, /[^\d]:/, /,/); self2.ontimestampmap && self2.ontimestampmap({ "MPEGTS": settings.get("MPEGTS"), "LOCAL": settings.get("LOCAL") }); } function parseHeader(input) { if (input.match(/X-TIMESTAMP-MAP/)) { parseOptions(input, function(k, v) { switch (k) { case "X-TIMESTAMP-MAP": parseTimestampMap(v); break; } }, /=/); } else { parseOptions(input, function(k, v) { switch (k) { case "Region": parseRegion(v); break; } }, /:/); } } try { var line; if (self2.state === "INITIAL") { if (!/\r\n|\n/.test(self2.buffer)) { return this; } line = collectNextLine(); var m = line.match(/^WEBVTT([ \t].*)?$/); if (!m || !m[0]) { throw new ParsingError(ParsingError.Errors.BadSignature); } self2.state = "HEADER"; } var alreadyCollectedLine = false; while (self2.buffer) { if (!/\r\n|\n/.test(self2.buffer)) { return this; } if (!alreadyCollectedLine) { line = collectNextLine(); } else { alreadyCollectedLine = false; } switch (self2.state) { case "HEADER": if (/:/.test(line)) { parseHeader(line); } else if (!line) { self2.state = "ID"; } continue; case "NOTE": if (!line) { self2.state = "ID"; } continue; case "ID": if (/^NOTE($|[ \t])/.test(line)) { self2.state = "NOTE"; break; } if (!line) { continue; } self2.cue = new (self2.vttjs.VTTCue || self2.window.VTTCue)(0, 0, ""); try { self2.cue.align = "center"; } catch (e) { self2.cue.align = "middle"; } self2.state = "CUE"; if (line.indexOf("-->") === -1) { self2.cue.id = line; continue; } case "CUE": try { parseCue(line, self2.cue, self2.regionList); } catch (e) { self2.reportOrThrowError(e); self2.cue = null; self2.state = "BADCUE"; continue; } self2.state = "CUETEXT"; continue; case "CUETEXT": var hasSubstring = line.indexOf("-->") !== -1; if (!line || hasSubstring && (alreadyCollectedLine = true)) { self2.oncue && self2.oncue(self2.cue); self2.cue = null; self2.state = "ID"; continue; } if (self2.cue.text) { self2.cue.text += "\n"; } self2.cue.text += line.replace(/\u2028/g, "\n").replace(/u2029/g, "\n"); continue; case "BADCUE": if (!line) { self2.state = "ID"; } continue; } } } catch (e) { self2.reportOrThrowError(e); if (self2.state === "CUETEXT" && self2.cue && self2.oncue) { self2.oncue(self2.cue); } self2.cue = null; self2.state = self2.state === "INITIAL" ? "BADWEBVTT" : "BADCUE"; } return this; }, flush: function() { var self2 = this; try { self2.buffer += self2.decoder.decode(); if (self2.cue || self2.state === "HEADER") { self2.buffer += "\n\n"; self2.parse(); } if (self2.state === "INITIAL") { throw new ParsingError(ParsingError.Errors.BadSignature); } } catch (e) { self2.reportOrThrowError(e); } self2.onflush && self2.onflush(); return this; } }; module.exports = WebVTT2; } }); // node_modules/videojs-vtt.js/lib/vttcue.js var require_vttcue = __commonJS({ "node_modules/videojs-vtt.js/lib/vttcue.js"(exports, module) { var autoKeyword = "auto"; var directionSetting = { "": 1, "lr": 1, "rl": 1 }; var alignSetting = { "start": 1, "center": 1, "end": 1, "left": 1, "right": 1, "auto": 1, "line-left": 1, "line-right": 1 }; function findDirectionSetting(value) { if (typeof value !== "string") { return false; } var dir = directionSetting[value.toLowerCase()]; return dir ? value.toLowerCase() : false; } function findAlignSetting(value) { if (typeof value !== "string") { return false; } var align = alignSetting[value.toLowerCase()]; return align ? value.toLowerCase() : false; } function VTTCue(startTime, endTime, text) { this.hasBeenReset = false; var _id = ""; var _pauseOnExit = false; var _startTime = startTime; var _endTime = endTime; var _text = text; var _region = null; var _vertical = ""; var _snapToLines = true; var _line = "auto"; var _lineAlign = "start"; var _position = "auto"; var _positionAlign = "auto"; var _size = 100; var _align = "center"; Object.defineProperties(this, { "id": { enumerable: true, get: function() { return _id; }, set: function(value) { _id = "" + value; } }, "pauseOnExit": { enumerable: true, get: function() { return _pauseOnExit; }, set: function(value) { _pauseOnExit = !!value; } }, "startTime": { enumerable: true, get: function() { return _startTime; }, set: function(value) { if (typeof value !== "number") { throw new TypeError("Start time must be set to a number."); } _startTime = value; this.hasBeenReset = true; } }, "endTime": { enumerable: true, get: function() { return _endTime; }, set: function(value) { if (typeof value !== "number") { throw new TypeError("End time must be set to a number."); } _endTime = value; this.hasBeenReset = true; } }, "text": { enumerable: true, get: function() { return _text; }, set: function(value) { _text = "" + value; this.hasBeenReset = true; } }, "region": { enumerable: true, get: function() { return _region; }, set: function(value) { _region = value; this.hasBeenReset = true; } }, "vertical": { enumerable: true, get: function() { return _vertical; }, set: function(value) { var setting = findDirectionSetting(value); if (setting === false) { throw new SyntaxError("Vertical: an invalid or illegal direction string was specified."); } _vertical = setting; this.hasBeenReset = true; } }, "snapToLines": { enumerable: true, get: function() { return _snapToLines; }, set: function(value) { _snapToLines = !!value; this.hasBeenReset = true; } }, "line": { enumerable: true, get: function() { return _line; }, set: function(value) { if (typeof value !== "number" && value !== autoKeyword) { throw new SyntaxError("Line: an invalid number or illegal string was specified."); } _line = value; this.hasBeenReset = true; } }, "lineAlign": { enumerable: true, get: function() { return _lineAlign; }, set: function(value) { var setting = findAlignSetting(value); if (!setting) { console.warn("lineAlign: an invalid or illegal string was specified."); } else { _lineAlign = setting; this.hasBeenReset = true; } } }, "position": { enumerable: true, get: function() { return _position; }, set: function(value) { if (value < 0 || value > 100) { throw new Error("Position must be between 0 and 100."); } _position = value; this.hasBeenReset = true; } }, "positionAlign": { enumerable: true, get: function() { return _positionAlign; }, set: function(value) { var setting = findAlignSetting(value); if (!setting) { console.warn("positionAlign: an invalid or illegal string was specified."); } else { _positionAlign = setting; this.hasBeenReset = true; } } }, "size": { enumerable: true, get: function() { return _size; }, set: function(value) { if (value < 0 || value > 100) { throw new Error("Size must be between 0 and 100."); } _size = value; this.hasBeenReset = true; } }, "align": { enumerable: true, get: function() { return _align; }, set: function(value) { var setting = findAlignSetting(value); if (!setting) { throw new SyntaxError("align: an invalid or illegal alignment string was specified."); } _align = setting; this.hasBeenReset = true; } } }); this.displayState = void 0; } VTTCue.prototype.getCueAsHTML = function() { return WebVTT.convertCueToDOMTree(window, this.text); }; module.exports = VTTCue; } }); // node_modules/videojs-vtt.js/lib/vttregion.js var require_vttregion = __commonJS({ "node_modules/videojs-vtt.js/lib/vttregion.js"(exports, module) { var scrollSetting = { "": true, "up": true }; function findScrollSetting(value) { if (typeof value !== "string") { return false; } var scroll = scrollSetting[value.toLowerCase()]; return scroll ? value.toLowerCase() : false; } function isValidPercentValue(value) { return typeof value === "number" && (value >= 0 && value <= 100); } function VTTRegion() { var _width = 100; var _lines = 3; var _regionAnchorX = 0; var _regionAnchorY = 100; var _viewportAnchorX = 0; var _viewportAnchorY = 100; var _scroll = ""; Object.defineProperties(this, { "width": { enumerable: true, get: function() { return _width; }, set: function(value) { if (!isValidPercentValue(value)) { throw new Error("Width must be between 0 and 100."); } _width = value; } }, "lines": { enumerable: true, get: function() { return _lines; }, set: function(value) { if (typeof value !== "number") { throw new TypeError("Lines must be set to a number."); } _lines = value; } }, "regionAnchorY": { enumerable: true, get: function() { return _regionAnchorY; }, set: function(value) { if (!isValidPercentValue(value)) { throw new Error("RegionAnchorX must be between 0 and 100."); } _regionAnchorY = value; } }, "regionAnchorX": { enumerable: true, get: function() { return _regionAnchorX; }, set: function(value) { if (!isValidPercentValue(value)) { throw new Error("RegionAnchorY must be between 0 and 100."); } _regionAnchorX = value; } }, "viewportAnchorY": { enumerable: true, get: function() { return _viewportAnchorY; }, set: function(value) { if (!isValidPercentValue(value)) { throw new Error("ViewportAnchorY must be between 0 and 100."); } _viewportAnchorY = value; } }, "viewportAnchorX": { enumerable: true, get: function() { return _viewportAnchorX; }, set: function(value) { if (!isValidPercentValue(value)) { throw new Error("ViewportAnchorX must be between 0 and 100."); } _viewportAnchorX = value; } }, "scroll": { enumerable: true, get: function() { return _scroll; }, set: function(value) { var setting = findScrollSetting(value); if (setting === false) { console.warn("Scroll: an invalid or illegal string was specified."); } else { _scroll = setting; } } } }); } module.exports = VTTRegion; } }); // node_modules/videojs-vtt.js/lib/browser-index.js var require_browser_index = __commonJS({ "node_modules/videojs-vtt.js/lib/browser-index.js"(exports, module) { var window7 = require_window(); var vttjs = module.exports = { WebVTT: require_vtt(), VTTCue: require_vttcue(), VTTRegion: require_vttregion() }; window7.vttjs = vttjs; window7.WebVTT = vttjs.WebVTT; var cueShim = vttjs.VTTCue; var regionShim = vttjs.VTTRegion; var nativeVTTCue = window7.VTTCue; var nativeVTTRegion = window7.VTTRegion; vttjs.shim = function() { window7.VTTCue = cueShim; window7.VTTRegion = regionShim; }; vttjs.restore = function() { window7.VTTCue = nativeVTTCue; window7.VTTRegion = nativeVTTRegion; }; if (!window7.VTTCue) { vttjs.shim(); } } }); // node_modules/@xmldom/xmldom/lib/conventions.js var require_conventions = __commonJS({ "node_modules/@xmldom/xmldom/lib/conventions.js"(exports) { "use strict"; function find(list, predicate, ac) { if (ac === void 0) { ac = Array.prototype; } if (list && typeof ac.find === "function") { return ac.find.call(list, predicate); } for (var i = 0; i < list.length; i++) { if (Object.prototype.hasOwnProperty.call(list, i)) { var item = list[i]; if (predicate.call(void 0, item, i, list)) { return item; } } } } function freeze(object, oc) { if (oc === void 0) { oc = Object; } return oc && typeof oc.freeze === "function" ? oc.freeze(object) : object; } function assign(target, source) { if (target === null || typeof target !== "object") { throw new TypeError("target is not an object"); } for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } return target; } var MIME_TYPE = freeze({ /** * `text/html`, the only mime type that triggers treating an XML document as HTML. * * @see DOMParser.SupportedType.isHTML * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration * @see https://en.wikipedia.org/wiki/HTML Wikipedia * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring WHATWG HTML Spec */ HTML: "text/html", /** * Helper method to check a mime type if it indicates an HTML document * * @param {string} [value] * @returns {boolean} * * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration * @see https://en.wikipedia.org/wiki/HTML Wikipedia * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring */ isHTML: function(value) { return value === MIME_TYPE.HTML; }, /** * `application/xml`, the standard mime type for XML documents. * * @see https://www.iana.org/assignments/media-types/application/xml IANA MimeType registration * @see https://tools.ietf.org/html/rfc7303#section-9.1 RFC 7303 * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia */ XML_APPLICATION: "application/xml", /** * `text/html`, an alias for `application/xml`. * * @see https://tools.ietf.org/html/rfc7303#section-9.2 RFC 7303 * @see https://www.iana.org/assignments/media-types/text/xml IANA MimeType registration * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia */ XML_TEXT: "text/xml", /** * `application/xhtml+xml`, indicates an XML document that has the default HTML namespace, * but is parsed as an XML document. * * @see https://www.iana.org/assignments/media-types/application/xhtml+xml IANA MimeType registration * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument WHATWG DOM Spec * @see https://en.wikipedia.org/wiki/XHTML Wikipedia */ XML_XHTML_APPLICATION: "application/xhtml+xml", /** * `image/svg+xml`, * * @see https://www.iana.org/assignments/media-types/image/svg+xml IANA MimeType registration * @see https://www.w3.org/TR/SVG11/ W3C SVG 1.1 * @see https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Wikipedia */ XML_SVG_IMAGE: "image/svg+xml" }); var NAMESPACE = freeze({ /** * The XHTML namespace. * * @see http://www.w3.org/1999/xhtml */ HTML: "http://www.w3.org/1999/xhtml", /** * Checks if `uri` equals `NAMESPACE.HTML`. * * @param {string} [uri] * * @see NAMESPACE.HTML */ isHTML: function(uri) { return uri === NAMESPACE.HTML; }, /** * The SVG namespace. * * @see http://www.w3.org/2000/svg */ SVG: "http://www.w3.org/2000/svg", /** * The `xml:` namespace. * * @see http://www.w3.org/XML/1998/namespace */ XML: "http://www.w3.org/XML/1998/namespace", /** * The `xmlns:` namespace * * @see https://www.w3.org/2000/xmlns/ */ XMLNS: "http://www.w3.org/2000/xmlns/" }); exports.assign = assign; exports.find = find; exports.freeze = freeze; exports.MIME_TYPE = MIME_TYPE; exports.NAMESPACE = NAMESPACE; } }); // node_modules/@xmldom/xmldom/lib/dom.js var require_dom = __commonJS({ "node_modules/@xmldom/xmldom/lib/dom.js"(exports) { var conventions = require_conventions(); var find = conventions.find; var NAMESPACE = conventions.NAMESPACE; function notEmptyString(input) { return input !== ""; } function splitOnASCIIWhitespace(input) { return input ? input.split(/[\t\n\f\r ]+/).filter(notEmptyString) : []; } function orderedSetReducer(current, element) { if (!current.hasOwnProperty(element)) { current[element] = true; } return current; } function toOrderedSet(input) { if (!input) return []; var list = splitOnASCIIWhitespace(input); return Object.keys(list.reduce(orderedSetReducer, {})); } function arrayIncludes(list) { return function(element) { return list && list.indexOf(element) !== -1; }; } function copy(src, dest) { for (var p in src) { if (Object.prototype.hasOwnProperty.call(src, p)) { dest[p] = src[p]; } } } function _extends2(Class, Super) { var pt = Class.prototype; if (!(pt instanceof Super)) { let t2 = function() { }; var t = t2; ; t2.prototype = Super.prototype; t2 = new t2(); copy(pt, t2); Class.prototype = pt = t2; } if (pt.constructor != Class) { if (typeof Class != "function") { console.error("unknown Class:" + Class); } pt.constructor = Class; } } var NodeType = {}; var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1; var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2; var TEXT_NODE = NodeType.TEXT_NODE = 3; var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4; var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5; var ENTITY_NODE = NodeType.ENTITY_NODE = 6; var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7; var COMMENT_NODE = NodeType.COMMENT_NODE = 8; var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9; var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10; var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11; var NOTATION_NODE = NodeType.NOTATION_NODE = 12; var ExceptionCode = {}; var ExceptionMessage = {}; var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = (ExceptionMessage[1] = "Index size error", 1); var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = (ExceptionMessage[2] = "DOMString size error", 2); var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = (ExceptionMessage[3] = "Hierarchy request error", 3); var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = (ExceptionMessage[4] = "Wrong document", 4); var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = (ExceptionMessage[5] = "Invalid character", 5); var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = (ExceptionMessage[6] = "No data allowed", 6); var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = (ExceptionMessage[7] = "No modification allowed", 7); var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = (ExceptionMessage[8] = "Not found", 8); var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = (ExceptionMessage[9] = "Not supported", 9); var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = (ExceptionMessage[10] = "Attribute in use", 10); var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = (ExceptionMessage[11] = "Invalid state", 11); var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = (ExceptionMessage[12] = "Syntax error", 12); var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = (ExceptionMessage[13] = "Invalid modification", 13); var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = (ExceptionMessage[14] = "Invalid namespace", 14); var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = (ExceptionMessage[15] = "Invalid access", 15); function DOMException(code, message) { if (message instanceof Error) { var error = message; } else { error = this; Error.call(this, ExceptionMessage[code]); this.message = ExceptionMessage[code]; if (Error.captureStackTrace) Error.captureStackTrace(this, DOMException); } error.code = code; if (message) this.message = this.message + ": " + message; return error; } DOMException.prototype = Error.prototype; copy(ExceptionCode, DOMException); function NodeList() { } NodeList.prototype = { /** * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive. * @standard level1 */ length: 0, /** * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null. * @standard level1 * @param index unsigned long * Index into the collection. * @return Node * The node at the indexth position in the NodeList, or null if that is not a valid index. */ item: function(index) { return index >= 0 && index < this.length ? this[index] : null; }, toString: function(isHTML, nodeFilter) { for (var buf = [], i = 0; i < this.length; i++) { serializeToString(this[i], buf, isHTML, nodeFilter); } return buf.join(""); }, /** * @private * @param {function (Node):boolean} predicate * @returns {Node[]} */ filter: function(predicate) { return Array.prototype.filter.call(this, predicate); }, /** * @private * @param {Node} item * @returns {number} */ indexOf: function(item) { return Array.prototype.indexOf.call(this, item); } }; function LiveNodeList(node, refresh) { this._node = node; this._refresh = refresh; _updateLiveList(this); } function _updateLiveList(list) { var inc = list._node._inc || list._node.ownerDocument._inc; if (list._inc !== inc) { var ls = list._refresh(list._node); __set__(list, "length", ls.length); if (!list.$$length || ls.length < list.$$length) { for (var i = ls.length; i in list; i++) { if (Object.prototype.hasOwnProperty.call(list, i)) { delete list[i]; } } } copy(ls, list); list._inc = inc; } } LiveNodeList.prototype.item = function(i) { _updateLiveList(this); return this[i] || null; }; _extends2(LiveNodeList, NodeList); function NamedNodeMap() { } function _findNodeIndex(list, node) { var i = list.length; while (i--) { if (list[i] === node) { return i; } } } function _addNamedNode(el, list, newAttr, oldAttr) { if (oldAttr) { list[_findNodeIndex(list, oldAttr)] = newAttr; } else { list[list.length++] = newAttr; } if (el) { newAttr.ownerElement = el; var doc = el.ownerDocument; if (doc) { oldAttr && _onRemoveAttribute(doc, el, oldAttr); _onAddAttribute(doc, el, newAttr); } } } function _removeNamedNode(el, list, attr) { var i = _findNodeIndex(list, attr); if (i >= 0) { var lastIndex = list.length - 1; while (i < lastIndex) { list[i] = list[++i]; } list.length = lastIndex; if (el) { var doc = el.ownerDocument; if (doc) { _onRemoveAttribute(doc, el, attr); attr.ownerElement = null; } } } else { throw new DOMException(NOT_FOUND_ERR, new Error(el.tagName + "@" + attr)); } } NamedNodeMap.prototype = { length: 0, item: NodeList.prototype.item, getNamedItem: function(key) { var i = this.length; while (i--) { var attr = this[i]; if (attr.nodeName == key) { return attr; } } }, setNamedItem: function(attr) { var el = attr.ownerElement; if (el && el != this._ownerElement) { throw new DOMException(INUSE_ATTRIBUTE_ERR); } var oldAttr = this.getNamedItem(attr.nodeName); _addNamedNode(this._ownerElement, this, attr, oldAttr); return oldAttr; }, /* returns Node */ setNamedItemNS: function(attr) { var el = attr.ownerElement, oldAttr; if (el && el != this._ownerElement) { throw new DOMException(INUSE_ATTRIBUTE_ERR); } oldAttr = this.getNamedItemNS(attr.namespaceURI, attr.localName); _addNamedNode(this._ownerElement, this, attr, oldAttr); return oldAttr; }, /* returns Node */ removeNamedItem: function(key) { var attr = this.getNamedItem(key); _removeNamedNode(this._ownerElement, this, attr); return attr; }, // raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR //for level2 removeNamedItemNS: function(namespaceURI, localName) { var attr = this.getNamedItemNS(namespaceURI, localName); _removeNamedNode(this._ownerElement, this, attr); return attr; }, getNamedItemNS: function(namespaceURI, localName) { var i = this.length; while (i--) { var node = this[i]; if (node.localName == localName && node.namespaceURI == namespaceURI) { return node; } } return null; } }; function DOMImplementation() { } DOMImplementation.prototype = { /** * The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given feature is supported. * The different implementations fairly diverged in what kind of features were reported. * The latest version of the spec settled to force this method to always return true, where the functionality was accurate and in use. * * @deprecated It is deprecated and modern browsers return true in all cases. * * @param {string} feature * @param {string} [version] * @returns {boolean} always true * * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 Core * @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard */ hasFeature: function(feature, version2) { return true; }, /** * Creates an XML Document object of the specified type with its document element. * * __It behaves slightly different from the description in the living standard__: * - There is no interface/class `XMLDocument`, it returns a `Document` instance. * - `contentType`, `encoding`, `mode`, `origin`, `url` fields are currently not declared. * - this implementation is not validating names or qualified names * (when parsing XML strings, the SAX parser takes care of that) * * @param {string|null} namespaceURI * @param {string} qualifiedName * @param {DocumentType=null} doctype * @returns {Document} * * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM Level 2 Core (initial) * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Level 2 Core * * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names */ createDocument: function(namespaceURI, qualifiedName, doctype) { var doc = new Document(); doc.implementation = this; doc.childNodes = new NodeList(); doc.doctype = doctype || null; if (doctype) { doc.appendChild(doctype); } if (qualifiedName) { var root = doc.createElementNS(namespaceURI, qualifiedName); doc.appendChild(root); } return doc; }, /** * Returns a doctype, with the given `qualifiedName`, `publicId`, and `systemId`. * * __This behavior is slightly different from the in the specs__: * - this implementation is not validating names or qualified names * (when parsing XML strings, the SAX parser takes care of that) * * @param {string} qualifiedName * @param {string} [publicId] * @param {string} [systemId] * @returns {DocumentType} which can either be used with `DOMImplementation.createDocument` upon document creation * or can be put into the document via methods like `Node.insertBefore()` or `Node.replaceChild()` * * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType MDN * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM Level 2 Core * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living Standard * * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names */ createDocumentType: function(qualifiedName, publicId, systemId) { var node = new DocumentType(); node.name = qualifiedName; node.nodeName = qualifiedName; node.publicId = publicId || ""; node.systemId = systemId || ""; return node; } }; function Node() { } Node.prototype = { firstChild: null, lastChild: null, previousSibling: null, nextSibling: null, attributes: null, parentNode: null, childNodes: null, ownerDocument: null, nodeValue: null, namespaceURI: null, prefix: null, localName: null, // Modified in DOM Level 2: insertBefore: function(newChild, refChild) { return _insertBefore(this, newChild, refChild); }, replaceChild: function(newChild, oldChild) { _insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument); if (oldChild) { this.removeChild(oldChild); } }, removeChild: function(oldChild) { return _removeChild(this, oldChild); }, appendChild: function(newChild) { return this.insertBefore(newChild, null); }, hasChildNodes: function() { return this.firstChild != null; }, cloneNode: function(deep) { return cloneNode(this.ownerDocument || this, this, deep); }, // Modified in DOM Level 2: normalize: function() { var child = this.firstChild; while (child) { var next = child.nextSibling; if (next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE) { this.removeChild(next); child.appendData(next.data); } else { child.normalize(); child = next; } } }, // Introduced in DOM Level 2: isSupported: function(feature, version2) { return this.ownerDocument.implementation.hasFeature(feature, version2); }, // Introduced in DOM Level 2: hasAttributes: function() { return this.attributes.length > 0; }, /** * Look up the prefix associated to the given namespace URI, starting from this node. * **The default namespace declarations are ignored by this method.** * See Namespace Prefix Lookup for details on the algorithm used by this method. * * _Note: The implementation seems to be incomplete when compared to the algorithm described in the specs._ * * @param {string | null} namespaceURI * @returns {string | null} * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespacePrefix * @see https://www.w3.org/TR/DOM-Level-3-Core/namespaces-algorithms.html#lookupNamespacePrefixAlgo * @see https://dom.spec.whatwg.org/#dom-node-lookupprefix * @see https://github.com/xmldom/xmldom/issues/322 */ lookupPrefix: function(namespaceURI) { var el = this; while (el) { var map = el._nsMap; if (map) { for (var n in map) { if (Object.prototype.hasOwnProperty.call(map, n) && map[n] === namespaceURI) { return n; } } } el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode; } return null; }, // Introduced in DOM Level 3: lookupNamespaceURI: function(prefix) { var el = this; while (el) { var map = el._nsMap; if (map) { if (Object.prototype.hasOwnProperty.call(map, prefix)) { return map[prefix]; } } el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode; } return null; }, // Introduced in DOM Level 3: isDefaultNamespace: function(namespaceURI) { var prefix = this.lookupPrefix(namespaceURI); return prefix == null; } }; function _xmlEncoder(c) { return c == "<" && "<" || c == ">" && ">" || c == "&" && "&" || c == '"' && """ || "&#" + c.charCodeAt() + ";"; } copy(NodeType, Node); copy(NodeType, Node.prototype); function _visitNode(node, callback) { if (callback(node)) { return true; } if (node = node.firstChild) { do { if (_visitNode(node, callback)) { return true; } } while (node = node.nextSibling); } } function Document() { this.ownerDocument = this; } function _onAddAttribute(doc, el, newAttr) { doc && doc._inc++; var ns = newAttr.namespaceURI; if (ns === NAMESPACE.XMLNS) { el._nsMap[newAttr.prefix ? newAttr.localName : ""] = newAttr.value; } } function _onRemoveAttribute(doc, el, newAttr, remove) { doc && doc._inc++; var ns = newAttr.namespaceURI; if (ns === NAMESPACE.XMLNS) { delete el._nsMap[newAttr.prefix ? newAttr.localName : ""]; } } function _onUpdateChild(doc, el, newChild) { if (doc && doc._inc) { doc._inc++; var cs = el.childNodes; if (newChild) { cs[cs.length++] = newChild; } else { var child = el.firstChild; var i = 0; while (child) { cs[i++] = child; child = child.nextSibling; } cs.length = i; delete cs[cs.length]; } } } function _removeChild(parentNode, child) { var previous = child.previousSibling; var next = child.nextSibling; if (previous) { previous.nextSibling = next; } else { parentNode.firstChild = next; } if (next) { next.previousSibling = previous; } else { parentNode.lastChild = previous; } child.parentNode = null; child.previousSibling = null; child.nextSibling = null; _onUpdateChild(parentNode.ownerDocument, parentNode); return child; } function hasValidParentNodeType(node) { return node && (node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.ELEMENT_NODE); } function hasInsertableNodeType(node) { return node && (isElementNode(node) || isTextNode2(node) || isDocTypeNode(node) || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.COMMENT_NODE || node.nodeType === Node.PROCESSING_INSTRUCTION_NODE); } function isDocTypeNode(node) { return node && node.nodeType === Node.DOCUMENT_TYPE_NODE; } function isElementNode(node) { return node && node.nodeType === Node.ELEMENT_NODE; } function isTextNode2(node) { return node && node.nodeType === Node.TEXT_NODE; } function isElementInsertionPossible(doc, child) { var parentChildNodes = doc.childNodes || []; if (find(parentChildNodes, isElementNode) || isDocTypeNode(child)) { return false; } var docTypeNode = find(parentChildNodes, isDocTypeNode); return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child)); } function isElementReplacementPossible(doc, child) { var parentChildNodes = doc.childNodes || []; function hasElementChildThatIsNotChild(node) { return isElementNode(node) && node !== child; } if (find(parentChildNodes, hasElementChildThatIsNotChild)) { return false; } var docTypeNode = find(parentChildNodes, isDocTypeNode); return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child)); } function assertPreInsertionValidity1to5(parent, node, child) { if (!hasValidParentNodeType(parent)) { throw new DOMException(HIERARCHY_REQUEST_ERR, "Unexpected parent node type " + parent.nodeType); } if (child && child.parentNode !== parent) { throw new DOMException(NOT_FOUND_ERR, "child not in parent"); } if ( // 4. If `node` is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException. !hasInsertableNodeType(node) || // 5. If either `node` is a Text node and `parent` is a document, // the sax parser currently adds top level text nodes, this will be fixed in 0.9.0 // || (node.nodeType === Node.TEXT_NODE && parent.nodeType === Node.DOCUMENT_NODE) // or `node` is a doctype and `parent` is not a document, then throw a "HierarchyRequestError" DOMException. isDocTypeNode(node) && parent.nodeType !== Node.DOCUMENT_NODE ) { throw new DOMException( HIERARCHY_REQUEST_ERR, "Unexpected node type " + node.nodeType + " for parent node type " + parent.nodeType ); } } function assertPreInsertionValidityInDocument(parent, node, child) { var parentChildNodes = parent.childNodes || []; var nodeChildNodes = node.childNodes || []; if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { var nodeChildElements = nodeChildNodes.filter(isElementNode); if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode2)) { throw new DOMException(HIERARCHY_REQUEST_ERR, "More than one element or text in fragment"); } if (nodeChildElements.length === 1 && !isElementInsertionPossible(parent, child)) { throw new DOMException(HIERARCHY_REQUEST_ERR, "Element in fragment can not be inserted before doctype"); } } if (isElementNode(node)) { if (!isElementInsertionPossible(parent, child)) { throw new DOMException(HIERARCHY_REQUEST_ERR, "Only one element can be added and only after doctype"); } } if (isDocTypeNode(node)) { if (find(parentChildNodes, isDocTypeNode)) { throw new DOMException(HIERARCHY_REQUEST_ERR, "Only one doctype is allowed"); } var parentElementChild = find(parentChildNodes, isElementNode); if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) { throw new DOMException(HIERARCHY_REQUEST_ERR, "Doctype can only be inserted before an element"); } if (!child && parentElementChild) { throw new DOMException(HIERARCHY_REQUEST_ERR, "Doctype can not be appended since element is present"); } } } function assertPreReplacementValidityInDocument(parent, node, child) { var parentChildNodes = parent.childNodes || []; var nodeChildNodes = node.childNodes || []; if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { var nodeChildElements = nodeChildNodes.filter(isElementNode); if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode2)) { throw new DOMException(HIERARCHY_REQUEST_ERR, "More than one element or text in fragment"); } if (nodeChildElements.length === 1 && !isElementReplacementPossible(parent, child)) { throw new DOMException(HIERARCHY_REQUEST_ERR, "Element in fragment can not be inserted before doctype"); } } if (isElementNode(node)) { if (!isElementReplacementPossible(parent, child)) { throw new DOMException(HIERARCHY_REQUEST_ERR, "Only one element can be added and only after doctype"); } } if (isDocTypeNode(node)) { let hasDoctypeChildThatIsNotChild2 = function(node2) { return isDocTypeNode(node2) && node2 !== child; }; var hasDoctypeChildThatIsNotChild = hasDoctypeChildThatIsNotChild2; if (find(parentChildNodes, hasDoctypeChildThatIsNotChild2)) { throw new DOMException(HIERARCHY_REQUEST_ERR, "Only one doctype is allowed"); } var parentElementChild = find(parentChildNodes, isElementNode); if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) { throw new DOMException(HIERARCHY_REQUEST_ERR, "Doctype can only be inserted before an element"); } } } function _insertBefore(parent, node, child, _inDocumentAssertion) { assertPreInsertionValidity1to5(parent, node, child); if (parent.nodeType === Node.DOCUMENT_NODE) { (_inDocumentAssertion || assertPreInsertionValidityInDocument)(parent, node, child); } var cp = node.parentNode; if (cp) { cp.removeChild(node); } if (node.nodeType === DOCUMENT_FRAGMENT_NODE) { var newFirst = node.firstChild; if (newFirst == null) { return node; } var newLast = node.lastChild; } else { newFirst = newLast = node; } var pre = child ? child.previousSibling : parent.lastChild; newFirst.previousSibling = pre; newLast.nextSibling = child; if (pre) { pre.nextSibling = newFirst; } else { parent.firstChild = newFirst; } if (child == null) { parent.lastChild = newLast; } else { child.previousSibling = newLast; } do { newFirst.parentNode = parent; } while (newFirst !== newLast && (newFirst = newFirst.nextSibling)); _onUpdateChild(parent.ownerDocument || parent, parent); if (node.nodeType == DOCUMENT_FRAGMENT_NODE) { node.firstChild = node.lastChild = null; } return node; } function _appendSingleChild(parentNode, newChild) { if (newChild.parentNode) { newChild.parentNode.removeChild(newChild); } newChild.parentNode = parentNode; newChild.previousSibling = parentNode.lastChild; newChild.nextSibling = null; if (newChild.previousSibling) { newChild.previousSibling.nextSibling = newChild; } else { parentNode.firstChild = newChild; } parentNode.lastChild = newChild; _onUpdateChild(parentNode.ownerDocument, parentNode, newChild); return newChild; } Document.prototype = { //implementation : null, nodeName: "#document", nodeType: DOCUMENT_NODE, /** * The DocumentType node of the document. * * @readonly * @type DocumentType */ doctype: null, documentElement: null, _inc: 1, insertBefore: function(newChild, refChild) { if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) { var child = newChild.firstChild; while (child) { var next = child.nextSibling; this.insertBefore(child, refChild); child = next; } return newChild; } _insertBefore(this, newChild, refChild); newChild.ownerDocument = this; if (this.documentElement === null && newChild.nodeType === ELEMENT_NODE) { this.documentElement = newChild; } return newChild; }, removeChild: function(oldChild) { if (this.documentElement == oldChild) { this.documentElement = null; } return _removeChild(this, oldChild); }, replaceChild: function(newChild, oldChild) { _insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument); newChild.ownerDocument = this; if (oldChild) { this.removeChild(oldChild); } if (isElementNode(newChild)) { this.documentElement = newChild; } }, // Introduced in DOM Level 2: importNode: function(importedNode, deep) { return importNode(this, importedNode, deep); }, // Introduced in DOM Level 2: getElementById: function(id) { var rtv = null; _visitNode(this.documentElement, function(node) { if (node.nodeType == ELEMENT_NODE) { if (node.getAttribute("id") == id) { rtv = node; return true; } } }); return rtv; }, /** * The `getElementsByClassName` method of `Document` interface returns an array-like object * of all child elements which have **all** of the given class name(s). * * Returns an empty list if `classeNames` is an empty string or only contains HTML white space characters. * * * Warning: This is a live LiveNodeList. * Changes in the DOM will reflect in the array as the changes occur. * If an element selected by this array no longer qualifies for the selector, * it will automatically be removed. Be aware of this for iteration purposes. * * @param {string} classNames is a string representing the class name(s) to match; multiple class names are separated by (ASCII-)whitespace * * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname */ getElementsByClassName: function(classNames) { var classNamesSet = toOrderedSet(classNames); return new LiveNodeList(this, function(base) { var ls = []; if (classNamesSet.length > 0) { _visitNode(base.documentElement, function(node) { if (node !== base && node.nodeType === ELEMENT_NODE) { var nodeClassNames = node.getAttribute("class"); if (nodeClassNames) { var matches = classNames === nodeClassNames; if (!matches) { var nodeClassNamesSet = toOrderedSet(nodeClassNames); matches = classNamesSet.every(arrayIncludes(nodeClassNamesSet)); } if (matches) { ls.push(node); } } } }); } return ls; }); }, //document factory method: createElement: function(tagName) { var node = new Element(); node.ownerDocument = this; node.nodeName = tagName; node.tagName = tagName; node.localName = tagName; node.childNodes = new NodeList(); var attrs = node.attributes = new NamedNodeMap(); attrs._ownerElement = node; return node; }, createDocumentFragment: function() { var node = new DocumentFragment(); node.ownerDocument = this; node.childNodes = new NodeList(); return node; }, createTextNode: function(data) { var node = new Text(); node.ownerDocument = this; node.appendData(data); return node; }, createComment: function(data) { var node = new Comment(); node.ownerDocument = this; node.appendData(data); return node; }, createCDATASection: function(data) { var node = new CDATASection(); node.ownerDocument = this; node.appendData(data); return node; }, createProcessingInstruction: function(target, data) { var node = new ProcessingInstruction(); node.ownerDocument = this; node.tagName = node.nodeName = node.target = target; node.nodeValue = node.data = data; return node; }, createAttribute: function(name) { var node = new Attr(); node.ownerDocument = this; node.name = name; node.nodeName = name; node.localName = name; node.specified = true; return node; }, createEntityReference: function(name) { var node = new EntityReference(); node.ownerDocument = this; node.nodeName = name; return node; }, // Introduced in DOM Level 2: createElementNS: function(namespaceURI, qualifiedName) { var node = new Element(); var pl = qualifiedName.split(":"); var attrs = node.attributes = new NamedNodeMap(); node.childNodes = new NodeList(); node.ownerDocument = this; node.nodeName = qualifiedName; node.tagName = qualifiedName; node.namespaceURI = namespaceURI; if (pl.length == 2) { node.prefix = pl[0]; node.localName = pl[1]; } else { node.localName = qualifiedName; } attrs._ownerElement = node; return node; }, // Introduced in DOM Level 2: createAttributeNS: function(namespaceURI, qualifiedName) { var node = new Attr(); var pl = qualifiedName.split(":"); node.ownerDocument = this; node.nodeName = qualifiedName; node.name = qualifiedName; node.namespaceURI = namespaceURI; node.specified = true; if (pl.length == 2) { node.prefix = pl[0]; node.localName = pl[1]; } else { node.localName = qualifiedName; } return node; } }; _extends2(Document, Node); function Element() { this._nsMap = {}; } Element.prototype = { nodeType: ELEMENT_NODE, hasAttribute: function(name) { return this.getAttributeNode(name) != null; }, getAttribute: function(name) { var attr = this.getAttributeNode(name); return attr && attr.value || ""; }, getAttributeNode: function(name) { return this.attributes.getNamedItem(name); }, setAttribute: function(name, value) { var attr = this.ownerDocument.createAttribute(name); attr.value = attr.nodeValue = "" + value; this.setAttributeNode(attr); }, removeAttribute: function(name) { var attr = this.getAttributeNode(name); attr && this.removeAttributeNode(attr); }, //four real opeartion method appendChild: function(newChild) { if (newChild.nodeType === DOCUMENT_FRAGMENT_NODE) { return this.insertBefore(newChild, null); } else { return _appendSingleChild(this, newChild); } }, setAttributeNode: function(newAttr) { return this.attributes.setNamedItem(newAttr); }, setAttributeNodeNS: function(newAttr) { return this.attributes.setNamedItemNS(newAttr); }, removeAttributeNode: function(oldAttr) { return this.attributes.removeNamedItem(oldAttr.nodeName); }, //get real attribute name,and remove it by removeAttributeNode removeAttributeNS: function(namespaceURI, localName) { var old = this.getAttributeNodeNS(namespaceURI, localName); old && this.removeAttributeNode(old); }, hasAttributeNS: function(namespaceURI, localName) { return this.getAttributeNodeNS(namespaceURI, localName) != null; }, getAttributeNS: function(namespaceURI, localName) { var attr = this.getAttributeNodeNS(namespaceURI, localName); return attr && attr.value || ""; }, setAttributeNS: function(namespaceURI, qualifiedName, value) { var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName); attr.value = attr.nodeValue = "" + value; this.setAttributeNode(attr); }, getAttributeNodeNS: function(namespaceURI, localName) { return this.attributes.getNamedItemNS(namespaceURI, localName); }, getElementsByTagName: function(tagName) { return new LiveNodeList(this, function(base) { var ls = []; _visitNode(base, function(node) { if (node !== base && node.nodeType == ELEMENT_NODE && (tagName === "*" || node.tagName == tagName)) { ls.push(node); } }); return ls; }); }, getElementsByTagNameNS: function(namespaceURI, localName) { return new LiveNodeList(this, function(base) { var ls = []; _visitNode(base, function(node) { if (node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === "*" || node.namespaceURI === namespaceURI) && (localName === "*" || node.localName == localName)) { ls.push(node); } }); return ls; }); } }; Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName; Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS; _extends2(Element, Node); function Attr() { } Attr.prototype.nodeType = ATTRIBUTE_NODE; _extends2(Attr, Node); function CharacterData() { } CharacterData.prototype = { data: "", substringData: function(offset, count) { return this.data.substring(offset, offset + count); }, appendData: function(text) { text = this.data + text; this.nodeValue = this.data = text; this.length = text.length; }, insertData: function(offset, text) { this.replaceData(offset, 0, text); }, appendChild: function(newChild) { throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR]); }, deleteData: function(offset, count) { this.replaceData(offset, count, ""); }, replaceData: function(offset, count, text) { var start = this.data.substring(0, offset); var end = this.data.substring(offset + count); text = start + text + end; this.nodeValue = this.data = text; this.length = text.length; } }; _extends2(CharacterData, Node); function Text() { } Text.prototype = { nodeName: "#text", nodeType: TEXT_NODE, splitText: function(offset) { var text = this.data; var newText = text.substring(offset); text = text.substring(0, offset); this.data = this.nodeValue = text; this.length = text.length; var newNode = this.ownerDocument.createTextNode(newText); if (this.parentNode) { this.parentNode.insertBefore(newNode, this.nextSibling); } return newNode; } }; _extends2(Text, CharacterData); function Comment() { } Comment.prototype = { nodeName: "#comment", nodeType: COMMENT_NODE }; _extends2(Comment, CharacterData); function CDATASection() { } CDATASection.prototype = { nodeName: "#cdata-section", nodeType: CDATA_SECTION_NODE }; _extends2(CDATASection, CharacterData); function DocumentType() { } DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE; _extends2(DocumentType, Node); function Notation() { } Notation.prototype.nodeType = NOTATION_NODE; _extends2(Notation, Node); function Entity() { } Entity.prototype.nodeType = ENTITY_NODE; _extends2(Entity, Node); function EntityReference() { } EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE; _extends2(EntityReference, Node); function DocumentFragment() { } DocumentFragment.prototype.nodeName = "#document-fragment"; DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE; _extends2(DocumentFragment, Node); function ProcessingInstruction() { } ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE; _extends2(ProcessingInstruction, Node); function XMLSerializer() { } XMLSerializer.prototype.serializeToString = function(node, isHtml, nodeFilter) { return nodeSerializeToString.call(node, isHtml, nodeFilter); }; Node.prototype.toString = nodeSerializeToString; function nodeSerializeToString(isHtml, nodeFilter) { var buf = []; var refNode = this.nodeType == 9 && this.documentElement || this; var prefix = refNode.prefix; var uri = refNode.namespaceURI; if (uri && prefix == null) { var prefix = refNode.lookupPrefix(uri); if (prefix == null) { var visibleNamespaces = [ { namespace: uri, prefix: null } //{namespace:uri,prefix:''} ]; } } serializeToString(this, buf, isHtml, nodeFilter, visibleNamespaces); return buf.join(""); } function needNamespaceDefine(node, isHTML, visibleNamespaces) { var prefix = node.prefix || ""; var uri = node.namespaceURI; if (!uri) { return false; } if (prefix === "xml" && uri === NAMESPACE.XML || uri === NAMESPACE.XMLNS) { return false; } var i = visibleNamespaces.length; while (i--) { var ns = visibleNamespaces[i]; if (ns.prefix === prefix) { return ns.namespace !== uri; } } return true; } function addSerializedAttribute(buf, qualifiedName, value) { buf.push(" ", qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"'); } function serializeToString(node, buf, isHTML, nodeFilter, visibleNamespaces) { if (!visibleNamespaces) { visibleNamespaces = []; } if (nodeFilter) { node = nodeFilter(node); if (node) { if (typeof node == "string") { buf.push(node); return; } } else { return; } } switch (node.nodeType) { case ELEMENT_NODE: var attrs = node.attributes; var len = attrs.length; var child = node.firstChild; var nodeName = node.tagName; isHTML = NAMESPACE.isHTML(node.namespaceURI) || isHTML; var prefixedNodeName = nodeName; if (!isHTML && !node.prefix && node.namespaceURI) { var defaultNS; for (var ai = 0; ai < attrs.length; ai++) { if (attrs.item(ai).name === "xmlns") { defaultNS = attrs.item(ai).value; break; } } if (!defaultNS) { for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) { var namespace = visibleNamespaces[nsi]; if (namespace.prefix === "" && namespace.namespace === node.namespaceURI) { defaultNS = namespace.namespace; break; } } } if (defaultNS !== node.namespaceURI) { for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) { var namespace = visibleNamespaces[nsi]; if (namespace.namespace === node.namespaceURI) { if (namespace.prefix) { prefixedNodeName = namespace.prefix + ":" + nodeName; } break; } } } } buf.push("<", prefixedNodeName); for (var i = 0; i < len; i++) { var attr = attrs.item(i); if (attr.prefix == "xmlns") { visibleNamespaces.push({ prefix: attr.localName, namespace: attr.value }); } else if (attr.nodeName == "xmlns") { visibleNamespaces.push({ prefix: "", namespace: attr.value }); } } for (var i = 0; i < len; i++) { var attr = attrs.item(i); if (needNamespaceDefine(attr, isHTML, visibleNamespaces)) { var prefix = attr.prefix || ""; var uri = attr.namespaceURI; addSerializedAttribute(buf, prefix ? "xmlns:" + prefix : "xmlns", uri); visibleNamespaces.push({ prefix, namespace: uri }); } serializeToString(attr, buf, isHTML, nodeFilter, visibleNamespaces); } if (nodeName === prefixedNodeName && needNamespaceDefine(node, isHTML, visibleNamespaces)) { var prefix = node.prefix || ""; var uri = node.namespaceURI; addSerializedAttribute(buf, prefix ? "xmlns:" + prefix : "xmlns", uri); visibleNamespaces.push({ prefix, namespace: uri }); } if (child || isHTML && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)) { buf.push(">"); if (isHTML && /^script$/i.test(nodeName)) { while (child) { if (child.data) { buf.push(child.data); } else { serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); } child = child.nextSibling; } } else { while (child) { serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); child = child.nextSibling; } } buf.push(""); } else { buf.push("/>"); } return; case DOCUMENT_NODE: case DOCUMENT_FRAGMENT_NODE: var child = node.firstChild; while (child) { serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); child = child.nextSibling; } return; case ATTRIBUTE_NODE: return addSerializedAttribute(buf, node.name, node.value); case TEXT_NODE: return buf.push( node.data.replace(/[<&>]/g, _xmlEncoder) ); case CDATA_SECTION_NODE: return buf.push(""); case COMMENT_NODE: return buf.push(""); case DOCUMENT_TYPE_NODE: var pubid = node.publicId; var sysid = node.systemId; buf.push(""); } else if (sysid && sysid != ".") { buf.push(" SYSTEM ", sysid, ">"); } else { var sub = node.internalSubset; if (sub) { buf.push(" [", sub, "]"); } buf.push(">"); } return; case PROCESSING_INSTRUCTION_NODE: return buf.push(""); case ENTITY_REFERENCE_NODE: return buf.push("&", node.nodeName, ";"); default: buf.push("??", node.nodeName); } } function importNode(doc, node, deep) { var node2; switch (node.nodeType) { case ELEMENT_NODE: node2 = node.cloneNode(false); node2.ownerDocument = doc; case DOCUMENT_FRAGMENT_NODE: break; case ATTRIBUTE_NODE: deep = true; break; } if (!node2) { node2 = node.cloneNode(false); } node2.ownerDocument = doc; node2.parentNode = null; if (deep) { var child = node.firstChild; while (child) { node2.appendChild(importNode(doc, child, deep)); child = child.nextSibling; } } return node2; } function cloneNode(doc, node, deep) { var node2 = new node.constructor(); for (var n in node) { if (Object.prototype.hasOwnProperty.call(node, n)) { var v = node[n]; if (typeof v != "object") { if (v != node2[n]) { node2[n] = v; } } } } if (node.childNodes) { node2.childNodes = new NodeList(); } node2.ownerDocument = doc; switch (node2.nodeType) { case ELEMENT_NODE: var attrs = node.attributes; var attrs2 = node2.attributes = new NamedNodeMap(); var len = attrs.length; attrs2._ownerElement = node2; for (var i = 0; i < len; i++) { node2.setAttributeNode(cloneNode(doc, attrs.item(i), true)); } break; ; case ATTRIBUTE_NODE: deep = true; } if (deep) { var child = node.firstChild; while (child) { node2.appendChild(cloneNode(doc, child, deep)); child = child.nextSibling; } } return node2; } function __set__(object, key, value) { object[key] = value; } try { if (Object.defineProperty) { let getTextContent2 = function(node) { switch (node.nodeType) { case ELEMENT_NODE: case DOCUMENT_FRAGMENT_NODE: var buf = []; node = node.firstChild; while (node) { if (node.nodeType !== 7 && node.nodeType !== 8) { buf.push(getTextContent2(node)); } node = node.nextSibling; } return buf.join(""); default: return node.nodeValue; } }; getTextContent = getTextContent2; Object.defineProperty(LiveNodeList.prototype, "length", { get: function() { _updateLiveList(this); return this.$$length; } }); Object.defineProperty(Node.prototype, "textContent", { get: function() { return getTextContent2(this); }, set: function(data) { switch (this.nodeType) { case ELEMENT_NODE: case DOCUMENT_FRAGMENT_NODE: while (this.firstChild) { this.removeChild(this.firstChild); } if (data || String(data)) { this.appendChild(this.ownerDocument.createTextNode(data)); } break; default: this.data = data; this.value = data; this.nodeValue = data; } } }); __set__ = function(object, key, value) { object["$$" + key] = value; }; } } catch (e) { } var getTextContent; exports.DocumentType = DocumentType; exports.DOMException = DOMException; exports.DOMImplementation = DOMImplementation; exports.Element = Element; exports.Node = Node; exports.NodeList = NodeList; exports.XMLSerializer = XMLSerializer; } }); // node_modules/@xmldom/xmldom/lib/entities.js var require_entities = __commonJS({ "node_modules/@xmldom/xmldom/lib/entities.js"(exports) { "use strict"; var freeze = require_conventions().freeze; exports.XML_ENTITIES = freeze({ amp: "&", apos: "'", gt: ">", lt: "<", quot: '"' }); exports.HTML_ENTITIES = freeze({ Aacute: "Á", aacute: "á", Abreve: "Ă", abreve: "ă", ac: "∾", acd: "∿", acE: "∾̳", Acirc: "Â", acirc: "â", acute: "´", Acy: "А", acy: "а", AElig: "Æ", aelig: "æ", af: "⁡", Afr: "𝔄", afr: "𝔞", Agrave: "À", agrave: "à", alefsym: "ℵ", aleph: "ℵ", Alpha: "Α", alpha: "α", Amacr: "Ā", amacr: "ā", amalg: "⨿", AMP: "&", amp: "&", And: "⩓", and: "∧", andand: "⩕", andd: "⩜", andslope: "⩘", andv: "⩚", ang: "∠", ange: "⦤", angle: "∠", angmsd: "∡", angmsdaa: "⦨", angmsdab: "⦩", angmsdac: "⦪", angmsdad: "⦫", angmsdae: "⦬", angmsdaf: "⦭", angmsdag: "⦮", angmsdah: "⦯", angrt: "∟", angrtvb: "⊾", angrtvbd: "⦝", angsph: "∢", angst: "Å", angzarr: "⍼", Aogon: "Ą", aogon: "ą", Aopf: "𝔸", aopf: "𝕒", ap: "≈", apacir: "⩯", apE: "⩰", ape: "≊", apid: "≋", apos: "'", ApplyFunction: "⁡", approx: "≈", approxeq: "≊", Aring: "Å", aring: "å", Ascr: "𝒜", ascr: "𝒶", Assign: "≔", ast: "*", asymp: "≈", asympeq: "≍", Atilde: "Ã", atilde: "ã", Auml: "Ä", auml: "ä", awconint: "∳", awint: "⨑", backcong: "≌", backepsilon: "϶", backprime: "‵", backsim: "∽", backsimeq: "⋍", Backslash: "∖", Barv: "⫧", barvee: "⊽", Barwed: "⌆", barwed: "⌅", barwedge: "⌅", bbrk: "⎵", bbrktbrk: "⎶", bcong: "≌", Bcy: "Б", bcy: "б", bdquo: "„", becaus: "∵", Because: "∵", because: "∵", bemptyv: "⦰", bepsi: "϶", bernou: "ℬ", Bernoullis: "ℬ", Beta: "Β", beta: "β", beth: "ℶ", between: "≬", Bfr: "𝔅", bfr: "𝔟", bigcap: "⋂", bigcirc: "◯", bigcup: "⋃", bigodot: "⨀", bigoplus: "⨁", bigotimes: "⨂", bigsqcup: "⨆", bigstar: "★", bigtriangledown: "▽", bigtriangleup: "△", biguplus: "⨄", bigvee: "⋁", bigwedge: "⋀", bkarow: "⤍", blacklozenge: "⧫", blacksquare: "▪", blacktriangle: "▴", blacktriangledown: "▾", blacktriangleleft: "◂", blacktriangleright: "▸", blank: "␣", blk12: "▒", blk14: "░", blk34: "▓", block: "█", bne: "=⃥", bnequiv: "≡⃥", bNot: "⫭", bnot: "⌐", Bopf: "𝔹", bopf: "𝕓", bot: "⊥", bottom: "⊥", bowtie: "⋈", boxbox: "⧉", boxDL: "╗", boxDl: "╖", boxdL: "╕", boxdl: "┐", boxDR: "╔", boxDr: "╓", boxdR: "╒", boxdr: "┌", boxH: "═", boxh: "─", boxHD: "╦", boxHd: "╤", boxhD: "╥", boxhd: "┬", boxHU: "╩", boxHu: "╧", boxhU: "╨", boxhu: "┴", boxminus: "⊟", boxplus: "⊞", boxtimes: "⊠", boxUL: "╝", boxUl: "╜", boxuL: "╛", boxul: "┘", boxUR: "╚", boxUr: "╙", boxuR: "╘", boxur: "└", boxV: "║", boxv: "│", boxVH: "╬", boxVh: "╫", boxvH: "╪", boxvh: "┼", boxVL: "╣", boxVl: "╢", boxvL: "╡", boxvl: "┤", boxVR: "╠", boxVr: "╟", boxvR: "╞", boxvr: "├", bprime: "‵", Breve: "˘", breve: "˘", brvbar: "¦", Bscr: "ℬ", bscr: "𝒷", bsemi: "⁏", bsim: "∽", bsime: "⋍", bsol: "\\", bsolb: "⧅", bsolhsub: "⟈", bull: "•", bullet: "•", bump: "≎", bumpE: "⪮", bumpe: "≏", Bumpeq: "≎", bumpeq: "≏", Cacute: "Ć", cacute: "ć", Cap: "⋒", cap: "∩", capand: "⩄", capbrcup: "⩉", capcap: "⩋", capcup: "⩇", capdot: "⩀", CapitalDifferentialD: "ⅅ", caps: "∩︀", caret: "⁁", caron: "ˇ", Cayleys: "ℭ", ccaps: "⩍", Ccaron: "Č", ccaron: "č", Ccedil: "Ç", ccedil: "ç", Ccirc: "Ĉ", ccirc: "ĉ", Cconint: "∰", ccups: "⩌", ccupssm: "⩐", Cdot: "Ċ", cdot: "ċ", cedil: "¸", Cedilla: "¸", cemptyv: "⦲", cent: "¢", CenterDot: "·", centerdot: "·", Cfr: "ℭ", cfr: "𝔠", CHcy: "Ч", chcy: "ч", check: "✓", checkmark: "✓", Chi: "Χ", chi: "χ", cir: "○", circ: "ˆ", circeq: "≗", circlearrowleft: "↺", circlearrowright: "↻", circledast: "⊛", circledcirc: "⊚", circleddash: "⊝", CircleDot: "⊙", circledR: "®", circledS: "Ⓢ", CircleMinus: "⊖", CirclePlus: "⊕", CircleTimes: "⊗", cirE: "⧃", cire: "≗", cirfnint: "⨐", cirmid: "⫯", cirscir: "⧂", ClockwiseContourIntegral: "∲", CloseCurlyDoubleQuote: "”", CloseCurlyQuote: "’", clubs: "♣", clubsuit: "♣", Colon: "∷", colon: ":", Colone: "⩴", colone: "≔", coloneq: "≔", comma: ",", commat: "@", comp: "∁", compfn: "∘", complement: "∁", complexes: "ℂ", cong: "≅", congdot: "⩭", Congruent: "≡", Conint: "∯", conint: "∮", ContourIntegral: "∮", Copf: "ℂ", copf: "𝕔", coprod: "∐", Coproduct: "∐", COPY: "©", copy: "©", copysr: "℗", CounterClockwiseContourIntegral: "∳", crarr: "↵", Cross: "⨯", cross: "✗", Cscr: "𝒞", cscr: "𝒸", csub: "⫏", csube: "⫑", csup: "⫐", csupe: "⫒", ctdot: "⋯", cudarrl: "⤸", cudarrr: "⤵", cuepr: "⋞", cuesc: "⋟", cularr: "↶", cularrp: "⤽", Cup: "⋓", cup: "∪", cupbrcap: "⩈", CupCap: "≍", cupcap: "⩆", cupcup: "⩊", cupdot: "⊍", cupor: "⩅", cups: "∪︀", curarr: "↷", curarrm: "⤼", curlyeqprec: "⋞", curlyeqsucc: "⋟", curlyvee: "⋎", curlywedge: "⋏", curren: "¤", curvearrowleft: "↶", curvearrowright: "↷", cuvee: "⋎", cuwed: "⋏", cwconint: "∲", cwint: "∱", cylcty: "⌭", Dagger: "‡", dagger: "†", daleth: "ℸ", Darr: "↡", dArr: "⇓", darr: "↓", dash: "‐", Dashv: "⫤", dashv: "⊣", dbkarow: "⤏", dblac: "˝", Dcaron: "Ď", dcaron: "ď", Dcy: "Д", dcy: "д", DD: "ⅅ", dd: "ⅆ", ddagger: "‡", ddarr: "⇊", DDotrahd: "⤑", ddotseq: "⩷", deg: "°", Del: "∇", Delta: "Δ", delta: "δ", demptyv: "⦱", dfisht: "⥿", Dfr: "𝔇", dfr: "𝔡", dHar: "⥥", dharl: "⇃", dharr: "⇂", DiacriticalAcute: "´", DiacriticalDot: "˙", DiacriticalDoubleAcute: "˝", DiacriticalGrave: "`", DiacriticalTilde: "˜", diam: "⋄", Diamond: "⋄", diamond: "⋄", diamondsuit: "♦", diams: "♦", die: "¨", DifferentialD: "ⅆ", digamma: "ϝ", disin: "⋲", div: "÷", divide: "÷", divideontimes: "⋇", divonx: "⋇", DJcy: "Ђ", djcy: "ђ", dlcorn: "⌞", dlcrop: "⌍", dollar: "$", Dopf: "𝔻", dopf: "𝕕", Dot: "¨", dot: "˙", DotDot: "⃜", doteq: "≐", doteqdot: "≑", DotEqual: "≐", dotminus: "∸", dotplus: "∔", dotsquare: "⊡", doublebarwedge: "⌆", DoubleContourIntegral: "∯", DoubleDot: "¨", DoubleDownArrow: "⇓", DoubleLeftArrow: "⇐", DoubleLeftRightArrow: "⇔", DoubleLeftTee: "⫤", DoubleLongLeftArrow: "⟸", DoubleLongLeftRightArrow: "⟺", DoubleLongRightArrow: "⟹", DoubleRightArrow: "⇒", DoubleRightTee: "⊨", DoubleUpArrow: "⇑", DoubleUpDownArrow: "⇕", DoubleVerticalBar: "∥", DownArrow: "↓", Downarrow: "⇓", downarrow: "↓", DownArrowBar: "⤓", DownArrowUpArrow: "⇵", DownBreve: "̑", downdownarrows: "⇊", downharpoonleft: "⇃", downharpoonright: "⇂", DownLeftRightVector: "⥐", DownLeftTeeVector: "⥞", DownLeftVector: "↽", DownLeftVectorBar: "⥖", DownRightTeeVector: "⥟", DownRightVector: "⇁", DownRightVectorBar: "⥗", DownTee: "⊤", DownTeeArrow: "↧", drbkarow: "⤐", drcorn: "⌟", drcrop: "⌌", Dscr: "𝒟", dscr: "𝒹", DScy: "Ѕ", dscy: "ѕ", dsol: "⧶", Dstrok: "Đ", dstrok: "đ", dtdot: "⋱", dtri: "▿", dtrif: "▾", duarr: "⇵", duhar: "⥯", dwangle: "⦦", DZcy: "Џ", dzcy: "џ", dzigrarr: "⟿", Eacute: "É", eacute: "é", easter: "⩮", Ecaron: "Ě", ecaron: "ě", ecir: "≖", Ecirc: "Ê", ecirc: "ê", ecolon: "≕", Ecy: "Э", ecy: "э", eDDot: "⩷", Edot: "Ė", eDot: "≑", edot: "ė", ee: "ⅇ", efDot: "≒", Efr: "𝔈", efr: "𝔢", eg: "⪚", Egrave: "È", egrave: "è", egs: "⪖", egsdot: "⪘", el: "⪙", Element: "∈", elinters: "⏧", ell: "ℓ", els: "⪕", elsdot: "⪗", Emacr: "Ē", emacr: "ē", empty: "∅", emptyset: "∅", EmptySmallSquare: "◻", emptyv: "∅", EmptyVerySmallSquare: "▫", emsp: " ", emsp13: " ", emsp14: " ", ENG: "Ŋ", eng: "ŋ", ensp: " ", Eogon: "Ę", eogon: "ę", Eopf: "𝔼", eopf: "𝕖", epar: "⋕", eparsl: "⧣", eplus: "⩱", epsi: "ε", Epsilon: "Ε", epsilon: "ε", epsiv: "ϵ", eqcirc: "≖", eqcolon: "≕", eqsim: "≂", eqslantgtr: "⪖", eqslantless: "⪕", Equal: "⩵", equals: "=", EqualTilde: "≂", equest: "≟", Equilibrium: "⇌", equiv: "≡", equivDD: "⩸", eqvparsl: "⧥", erarr: "⥱", erDot: "≓", Escr: "ℰ", escr: "ℯ", esdot: "≐", Esim: "⩳", esim: "≂", Eta: "Η", eta: "η", ETH: "Ð", eth: "ð", Euml: "Ë", euml: "ë", euro: "€", excl: "!", exist: "∃", Exists: "∃", expectation: "ℰ", ExponentialE: "ⅇ", exponentiale: "ⅇ", fallingdotseq: "≒", Fcy: "Ф", fcy: "ф", female: "♀", ffilig: "ffi", fflig: "ff", ffllig: "ffl", Ffr: "𝔉", ffr: "𝔣", filig: "fi", FilledSmallSquare: "◼", FilledVerySmallSquare: "▪", fjlig: "fj", flat: "♭", fllig: "fl", fltns: "▱", fnof: "ƒ", Fopf: "𝔽", fopf: "𝕗", ForAll: "∀", forall: "∀", fork: "⋔", forkv: "⫙", Fouriertrf: "ℱ", fpartint: "⨍", frac12: "½", frac13: "⅓", frac14: "¼", frac15: "⅕", frac16: "⅙", frac18: "⅛", frac23: "⅔", frac25: "⅖", frac34: "¾", frac35: "⅗", frac38: "⅜", frac45: "⅘", frac56: "⅚", frac58: "⅝", frac78: "⅞", frasl: "⁄", frown: "⌢", Fscr: "ℱ", fscr: "𝒻", gacute: "ǵ", Gamma: "Γ", gamma: "γ", Gammad: "Ϝ", gammad: "ϝ", gap: "⪆", Gbreve: "Ğ", gbreve: "ğ", Gcedil: "Ģ", Gcirc: "Ĝ", gcirc: "ĝ", Gcy: "Г", gcy: "г", Gdot: "Ġ", gdot: "ġ", gE: "≧", ge: "≥", gEl: "⪌", gel: "⋛", geq: "≥", geqq: "≧", geqslant: "⩾", ges: "⩾", gescc: "⪩", gesdot: "⪀", gesdoto: "⪂", gesdotol: "⪄", gesl: "⋛︀", gesles: "⪔", Gfr: "𝔊", gfr: "𝔤", Gg: "⋙", gg: "≫", ggg: "⋙", gimel: "ℷ", GJcy: "Ѓ", gjcy: "ѓ", gl: "≷", gla: "⪥", glE: "⪒", glj: "⪤", gnap: "⪊", gnapprox: "⪊", gnE: "≩", gne: "⪈", gneq: "⪈", gneqq: "≩", gnsim: "⋧", Gopf: "𝔾", gopf: "𝕘", grave: "`", GreaterEqual: "≥", GreaterEqualLess: "⋛", GreaterFullEqual: "≧", GreaterGreater: "⪢", GreaterLess: "≷", GreaterSlantEqual: "⩾", GreaterTilde: "≳", Gscr: "𝒢", gscr: "ℊ", gsim: "≳", gsime: "⪎", gsiml: "⪐", Gt: "≫", GT: ">", gt: ">", gtcc: "⪧", gtcir: "⩺", gtdot: "⋗", gtlPar: "⦕", gtquest: "⩼", gtrapprox: "⪆", gtrarr: "⥸", gtrdot: "⋗", gtreqless: "⋛", gtreqqless: "⪌", gtrless: "≷", gtrsim: "≳", gvertneqq: "≩︀", gvnE: "≩︀", Hacek: "ˇ", hairsp: " ", half: "½", hamilt: "ℋ", HARDcy: "Ъ", hardcy: "ъ", hArr: "⇔", harr: "↔", harrcir: "⥈", harrw: "↭", Hat: "^", hbar: "ℏ", Hcirc: "Ĥ", hcirc: "ĥ", hearts: "♥", heartsuit: "♥", hellip: "…", hercon: "⊹", Hfr: "ℌ", hfr: "𝔥", HilbertSpace: "ℋ", hksearow: "⤥", hkswarow: "⤦", hoarr: "⇿", homtht: "∻", hookleftarrow: "↩", hookrightarrow: "↪", Hopf: "ℍ", hopf: "𝕙", horbar: "―", HorizontalLine: "─", Hscr: "ℋ", hscr: "𝒽", hslash: "ℏ", Hstrok: "Ħ", hstrok: "ħ", HumpDownHump: "≎", HumpEqual: "≏", hybull: "⁃", hyphen: "‐", Iacute: "Í", iacute: "í", ic: "⁣", Icirc: "Î", icirc: "î", Icy: "И", icy: "и", Idot: "İ", IEcy: "Е", iecy: "е", iexcl: "¡", iff: "⇔", Ifr: "ℑ", ifr: "𝔦", Igrave: "Ì", igrave: "ì", ii: "ⅈ", iiiint: "⨌", iiint: "∭", iinfin: "⧜", iiota: "℩", IJlig: "IJ", ijlig: "ij", Im: "ℑ", Imacr: "Ī", imacr: "ī", image: "ℑ", ImaginaryI: "ⅈ", imagline: "ℐ", imagpart: "ℑ", imath: "ı", imof: "⊷", imped: "Ƶ", Implies: "⇒", in: "∈", incare: "℅", infin: "∞", infintie: "⧝", inodot: "ı", Int: "∬", int: "∫", intcal: "⊺", integers: "ℤ", Integral: "∫", intercal: "⊺", Intersection: "⋂", intlarhk: "⨗", intprod: "⨼", InvisibleComma: "⁣", InvisibleTimes: "⁢", IOcy: "Ё", iocy: "ё", Iogon: "Į", iogon: "į", Iopf: "𝕀", iopf: "𝕚", Iota: "Ι", iota: "ι", iprod: "⨼", iquest: "¿", Iscr: "ℐ", iscr: "𝒾", isin: "∈", isindot: "⋵", isinE: "⋹", isins: "⋴", isinsv: "⋳", isinv: "∈", it: "⁢", Itilde: "Ĩ", itilde: "ĩ", Iukcy: "І", iukcy: "і", Iuml: "Ï", iuml: "ï", Jcirc: "Ĵ", jcirc: "ĵ", Jcy: "Й", jcy: "й", Jfr: "𝔍", jfr: "𝔧", jmath: "ȷ", Jopf: "𝕁", jopf: "𝕛", Jscr: "𝒥", jscr: "𝒿", Jsercy: "Ј", jsercy: "ј", Jukcy: "Є", jukcy: "є", Kappa: "Κ", kappa: "κ", kappav: "ϰ", Kcedil: "Ķ", kcedil: "ķ", Kcy: "К", kcy: "к", Kfr: "𝔎", kfr: "𝔨", kgreen: "ĸ", KHcy: "Х", khcy: "х", KJcy: "Ќ", kjcy: "ќ", Kopf: "𝕂", kopf: "𝕜", Kscr: "𝒦", kscr: "𝓀", lAarr: "⇚", Lacute: "Ĺ", lacute: "ĺ", laemptyv: "⦴", lagran: "ℒ", Lambda: "Λ", lambda: "λ", Lang: "⟪", lang: "⟨", langd: "⦑", langle: "⟨", lap: "⪅", Laplacetrf: "ℒ", laquo: "«", Larr: "↞", lArr: "⇐", larr: "←", larrb: "⇤", larrbfs: "⤟", larrfs: "⤝", larrhk: "↩", larrlp: "↫", larrpl: "⤹", larrsim: "⥳", larrtl: "↢", lat: "⪫", lAtail: "⤛", latail: "⤙", late: "⪭", lates: "⪭︀", lBarr: "⤎", lbarr: "⤌", lbbrk: "❲", lbrace: "{", lbrack: "[", lbrke: "⦋", lbrksld: "⦏", lbrkslu: "⦍", Lcaron: "Ľ", lcaron: "ľ", Lcedil: "Ļ", lcedil: "ļ", lceil: "⌈", lcub: "{", Lcy: "Л", lcy: "л", ldca: "⤶", ldquo: "“", ldquor: "„", ldrdhar: "⥧", ldrushar: "⥋", ldsh: "↲", lE: "≦", le: "≤", LeftAngleBracket: "⟨", LeftArrow: "←", Leftarrow: "⇐", leftarrow: "←", LeftArrowBar: "⇤", LeftArrowRightArrow: "⇆", leftarrowtail: "↢", LeftCeiling: "⌈", LeftDoubleBracket: "⟦", LeftDownTeeVector: "⥡", LeftDownVector: "⇃", LeftDownVectorBar: "⥙", LeftFloor: "⌊", leftharpoondown: "↽", leftharpoonup: "↼", leftleftarrows: "⇇", LeftRightArrow: "↔", Leftrightarrow: "⇔", leftrightarrow: "↔", leftrightarrows: "⇆", leftrightharpoons: "⇋", leftrightsquigarrow: "↭", LeftRightVector: "⥎", LeftTee: "⊣", LeftTeeArrow: "↤", LeftTeeVector: "⥚", leftthreetimes: "⋋", LeftTriangle: "⊲", LeftTriangleBar: "⧏", LeftTriangleEqual: "⊴", LeftUpDownVector: "⥑", LeftUpTeeVector: "⥠", LeftUpVector: "↿", LeftUpVectorBar: "⥘", LeftVector: "↼", LeftVectorBar: "⥒", lEg: "⪋", leg: "⋚", leq: "≤", leqq: "≦", leqslant: "⩽", les: "⩽", lescc: "⪨", lesdot: "⩿", lesdoto: "⪁", lesdotor: "⪃", lesg: "⋚︀", lesges: "⪓", lessapprox: "⪅", lessdot: "⋖", lesseqgtr: "⋚", lesseqqgtr: "⪋", LessEqualGreater: "⋚", LessFullEqual: "≦", LessGreater: "≶", lessgtr: "≶", LessLess: "⪡", lesssim: "≲", LessSlantEqual: "⩽", LessTilde: "≲", lfisht: "⥼", lfloor: "⌊", Lfr: "𝔏", lfr: "𝔩", lg: "≶", lgE: "⪑", lHar: "⥢", lhard: "↽", lharu: "↼", lharul: "⥪", lhblk: "▄", LJcy: "Љ", ljcy: "љ", Ll: "⋘", ll: "≪", llarr: "⇇", llcorner: "⌞", Lleftarrow: "⇚", llhard: "⥫", lltri: "◺", Lmidot: "Ŀ", lmidot: "ŀ", lmoust: "⎰", lmoustache: "⎰", lnap: "⪉", lnapprox: "⪉", lnE: "≨", lne: "⪇", lneq: "⪇", lneqq: "≨", lnsim: "⋦", loang: "⟬", loarr: "⇽", lobrk: "⟦", LongLeftArrow: "⟵", Longleftarrow: "⟸", longleftarrow: "⟵", LongLeftRightArrow: "⟷", Longleftrightarrow: "⟺", longleftrightarrow: "⟷", longmapsto: "⟼", LongRightArrow: "⟶", Longrightarrow: "⟹", longrightarrow: "⟶", looparrowleft: "↫", looparrowright: "↬", lopar: "⦅", Lopf: "𝕃", lopf: "𝕝", loplus: "⨭", lotimes: "⨴", lowast: "∗", lowbar: "_", LowerLeftArrow: "↙", LowerRightArrow: "↘", loz: "◊", lozenge: "◊", lozf: "⧫", lpar: "(", lparlt: "⦓", lrarr: "⇆", lrcorner: "⌟", lrhar: "⇋", lrhard: "⥭", lrm: "‎", lrtri: "⊿", lsaquo: "‹", Lscr: "ℒ", lscr: "𝓁", Lsh: "↰", lsh: "↰", lsim: "≲", lsime: "⪍", lsimg: "⪏", lsqb: "[", lsquo: "‘", lsquor: "‚", Lstrok: "Ł", lstrok: "ł", Lt: "≪", LT: "<", lt: "<", ltcc: "⪦", ltcir: "⩹", ltdot: "⋖", lthree: "⋋", ltimes: "⋉", ltlarr: "⥶", ltquest: "⩻", ltri: "◃", ltrie: "⊴", ltrif: "◂", ltrPar: "⦖", lurdshar: "⥊", luruhar: "⥦", lvertneqq: "≨︀", lvnE: "≨︀", macr: "¯", male: "♂", malt: "✠", maltese: "✠", Map: "⤅", map: "↦", mapsto: "↦", mapstodown: "↧", mapstoleft: "↤", mapstoup: "↥", marker: "▮", mcomma: "⨩", Mcy: "М", mcy: "м", mdash: "—", mDDot: "∺", measuredangle: "∡", MediumSpace: " ", Mellintrf: "ℳ", Mfr: "𝔐", mfr: "𝔪", mho: "℧", micro: "µ", mid: "∣", midast: "*", midcir: "⫰", middot: "·", minus: "−", minusb: "⊟", minusd: "∸", minusdu: "⨪", MinusPlus: "∓", mlcp: "⫛", mldr: "…", mnplus: "∓", models: "⊧", Mopf: "𝕄", mopf: "𝕞", mp: "∓", Mscr: "ℳ", mscr: "𝓂", mstpos: "∾", Mu: "Μ", mu: "μ", multimap: "⊸", mumap: "⊸", nabla: "∇", Nacute: "Ń", nacute: "ń", nang: "∠⃒", nap: "≉", napE: "⩰̸", napid: "≋̸", napos: "ʼn", napprox: "≉", natur: "♮", natural: "♮", naturals: "ℕ", nbsp: " ", nbump: "≎̸", nbumpe: "≏̸", ncap: "⩃", Ncaron: "Ň", ncaron: "ň", Ncedil: "Ņ", ncedil: "ņ", ncong: "≇", ncongdot: "⩭̸", ncup: "⩂", Ncy: "Н", ncy: "н", ndash: "–", ne: "≠", nearhk: "⤤", neArr: "⇗", nearr: "↗", nearrow: "↗", nedot: "≐̸", NegativeMediumSpace: "​", NegativeThickSpace: "​", NegativeThinSpace: "​", NegativeVeryThinSpace: "​", nequiv: "≢", nesear: "⤨", nesim: "≂̸", NestedGreaterGreater: "≫", NestedLessLess: "≪", NewLine: "\n", nexist: "∄", nexists: "∄", Nfr: "𝔑", nfr: "𝔫", ngE: "≧̸", nge: "≱", ngeq: "≱", ngeqq: "≧̸", ngeqslant: "⩾̸", nges: "⩾̸", nGg: "⋙̸", ngsim: "≵", nGt: "≫⃒", ngt: "≯", ngtr: "≯", nGtv: "≫̸", nhArr: "⇎", nharr: "↮", nhpar: "⫲", ni: "∋", nis: "⋼", nisd: "⋺", niv: "∋", NJcy: "Њ", njcy: "њ", nlArr: "⇍", nlarr: "↚", nldr: "‥", nlE: "≦̸", nle: "≰", nLeftarrow: "⇍", nleftarrow: "↚", nLeftrightarrow: "⇎", nleftrightarrow: "↮", nleq: "≰", nleqq: "≦̸", nleqslant: "⩽̸", nles: "⩽̸", nless: "≮", nLl: "⋘̸", nlsim: "≴", nLt: "≪⃒", nlt: "≮", nltri: "⋪", nltrie: "⋬", nLtv: "≪̸", nmid: "∤", NoBreak: "⁠", NonBreakingSpace: " ", Nopf: "ℕ", nopf: "𝕟", Not: "⫬", not: "¬", NotCongruent: "≢", NotCupCap: "≭", NotDoubleVerticalBar: "∦", NotElement: "∉", NotEqual: "≠", NotEqualTilde: "≂̸", NotExists: "∄", NotGreater: "≯", NotGreaterEqual: "≱", NotGreaterFullEqual: "≧̸", NotGreaterGreater: "≫̸", NotGreaterLess: "≹", NotGreaterSlantEqual: "⩾̸", NotGreaterTilde: "≵", NotHumpDownHump: "≎̸", NotHumpEqual: "≏̸", notin: "∉", notindot: "⋵̸", notinE: "⋹̸", notinva: "∉", notinvb: "⋷", notinvc: "⋶", NotLeftTriangle: "⋪", NotLeftTriangleBar: "⧏̸", NotLeftTriangleEqual: "⋬", NotLess: "≮", NotLessEqual: "≰", NotLessGreater: "≸", NotLessLess: "≪̸", NotLessSlantEqual: "⩽̸", NotLessTilde: "≴", NotNestedGreaterGreater: "⪢̸", NotNestedLessLess: "⪡̸", notni: "∌", notniva: "∌", notnivb: "⋾", notnivc: "⋽", NotPrecedes: "⊀", NotPrecedesEqual: "⪯̸", NotPrecedesSlantEqual: "⋠", NotReverseElement: "∌", NotRightTriangle: "⋫", NotRightTriangleBar: "⧐̸", NotRightTriangleEqual: "⋭", NotSquareSubset: "⊏̸", NotSquareSubsetEqual: "⋢", NotSquareSuperset: "⊐̸", NotSquareSupersetEqual: "⋣", NotSubset: "⊂⃒", NotSubsetEqual: "⊈", NotSucceeds: "⊁", NotSucceedsEqual: "⪰̸", NotSucceedsSlantEqual: "⋡", NotSucceedsTilde: "≿̸", NotSuperset: "⊃⃒", NotSupersetEqual: "⊉", NotTilde: "≁", NotTildeEqual: "≄", NotTildeFullEqual: "≇", NotTildeTilde: "≉", NotVerticalBar: "∤", npar: "∦", nparallel: "∦", nparsl: "⫽⃥", npart: "∂̸", npolint: "⨔", npr: "⊀", nprcue: "⋠", npre: "⪯̸", nprec: "⊀", npreceq: "⪯̸", nrArr: "⇏", nrarr: "↛", nrarrc: "⤳̸", nrarrw: "↝̸", nRightarrow: "⇏", nrightarrow: "↛", nrtri: "⋫", nrtrie: "⋭", nsc: "⊁", nsccue: "⋡", nsce: "⪰̸", Nscr: "𝒩", nscr: "𝓃", nshortmid: "∤", nshortparallel: "∦", nsim: "≁", nsime: "≄", nsimeq: "≄", nsmid: "∤", nspar: "∦", nsqsube: "⋢", nsqsupe: "⋣", nsub: "⊄", nsubE: "⫅̸", nsube: "⊈", nsubset: "⊂⃒", nsubseteq: "⊈", nsubseteqq: "⫅̸", nsucc: "⊁", nsucceq: "⪰̸", nsup: "⊅", nsupE: "⫆̸", nsupe: "⊉", nsupset: "⊃⃒", nsupseteq: "⊉", nsupseteqq: "⫆̸", ntgl: "≹", Ntilde: "Ñ", ntilde: "ñ", ntlg: "≸", ntriangleleft: "⋪", ntrianglelefteq: "⋬", ntriangleright: "⋫", ntrianglerighteq: "⋭", Nu: "Ν", nu: "ν", num: "#", numero: "№", numsp: " ", nvap: "≍⃒", nVDash: "⊯", nVdash: "⊮", nvDash: "⊭", nvdash: "⊬", nvge: "≥⃒", nvgt: ">⃒", nvHarr: "⤄", nvinfin: "⧞", nvlArr: "⤂", nvle: "≤⃒", nvlt: "<⃒", nvltrie: "⊴⃒", nvrArr: "⤃", nvrtrie: "⊵⃒", nvsim: "∼⃒", nwarhk: "⤣", nwArr: "⇖", nwarr: "↖", nwarrow: "↖", nwnear: "⤧", Oacute: "Ó", oacute: "ó", oast: "⊛", ocir: "⊚", Ocirc: "Ô", ocirc: "ô", Ocy: "О", ocy: "о", odash: "⊝", Odblac: "Ő", odblac: "ő", odiv: "⨸", odot: "⊙", odsold: "⦼", OElig: "Œ", oelig: "œ", ofcir: "⦿", Ofr: "𝔒", ofr: "𝔬", ogon: "˛", Ograve: "Ò", ograve: "ò", ogt: "⧁", ohbar: "⦵", ohm: "Ω", oint: "∮", olarr: "↺", olcir: "⦾", olcross: "⦻", oline: "‾", olt: "⧀", Omacr: "Ō", omacr: "ō", Omega: "Ω", omega: "ω", Omicron: "Ο", omicron: "ο", omid: "⦶", ominus: "⊖", Oopf: "𝕆", oopf: "𝕠", opar: "⦷", OpenCurlyDoubleQuote: "“", OpenCurlyQuote: "‘", operp: "⦹", oplus: "⊕", Or: "⩔", or: "∨", orarr: "↻", ord: "⩝", order: "ℴ", orderof: "ℴ", ordf: "ª", ordm: "º", origof: "⊶", oror: "⩖", orslope: "⩗", orv: "⩛", oS: "Ⓢ", Oscr: "𝒪", oscr: "ℴ", Oslash: "Ø", oslash: "ø", osol: "⊘", Otilde: "Õ", otilde: "õ", Otimes: "⨷", otimes: "⊗", otimesas: "⨶", Ouml: "Ö", ouml: "ö", ovbar: "⌽", OverBar: "‾", OverBrace: "⏞", OverBracket: "⎴", OverParenthesis: "⏜", par: "∥", para: "¶", parallel: "∥", parsim: "⫳", parsl: "⫽", part: "∂", PartialD: "∂", Pcy: "П", pcy: "п", percnt: "%", period: ".", permil: "‰", perp: "⊥", pertenk: "‱", Pfr: "𝔓", pfr: "𝔭", Phi: "Φ", phi: "φ", phiv: "ϕ", phmmat: "ℳ", phone: "☎", Pi: "Π", pi: "π", pitchfork: "⋔", piv: "ϖ", planck: "ℏ", planckh: "ℎ", plankv: "ℏ", plus: "+", plusacir: "⨣", plusb: "⊞", pluscir: "⨢", plusdo: "∔", plusdu: "⨥", pluse: "⩲", PlusMinus: "±", plusmn: "±", plussim: "⨦", plustwo: "⨧", pm: "±", Poincareplane: "ℌ", pointint: "⨕", Popf: "ℙ", popf: "𝕡", pound: "£", Pr: "⪻", pr: "≺", prap: "⪷", prcue: "≼", prE: "⪳", pre: "⪯", prec: "≺", precapprox: "⪷", preccurlyeq: "≼", Precedes: "≺", PrecedesEqual: "⪯", PrecedesSlantEqual: "≼", PrecedesTilde: "≾", preceq: "⪯", precnapprox: "⪹", precneqq: "⪵", precnsim: "⋨", precsim: "≾", Prime: "″", prime: "′", primes: "ℙ", prnap: "⪹", prnE: "⪵", prnsim: "⋨", prod: "∏", Product: "∏", profalar: "⌮", profline: "⌒", profsurf: "⌓", prop: "∝", Proportion: "∷", Proportional: "∝", propto: "∝", prsim: "≾", prurel: "⊰", Pscr: "𝒫", pscr: "𝓅", Psi: "Ψ", psi: "ψ", puncsp: " ", Qfr: "𝔔", qfr: "𝔮", qint: "⨌", Qopf: "ℚ", qopf: "𝕢", qprime: "⁗", Qscr: "𝒬", qscr: "𝓆", quaternions: "ℍ", quatint: "⨖", quest: "?", questeq: "≟", QUOT: '"', quot: '"', rAarr: "⇛", race: "∽̱", Racute: "Ŕ", racute: "ŕ", radic: "√", raemptyv: "⦳", Rang: "⟫", rang: "⟩", rangd: "⦒", range: "⦥", rangle: "⟩", raquo: "»", Rarr: "↠", rArr: "⇒", rarr: "→", rarrap: "⥵", rarrb: "⇥", rarrbfs: "⤠", rarrc: "⤳", rarrfs: "⤞", rarrhk: "↪", rarrlp: "↬", rarrpl: "⥅", rarrsim: "⥴", Rarrtl: "⤖", rarrtl: "↣", rarrw: "↝", rAtail: "⤜", ratail: "⤚", ratio: "∶", rationals: "ℚ", RBarr: "⤐", rBarr: "⤏", rbarr: "⤍", rbbrk: "❳", rbrace: "}", rbrack: "]", rbrke: "⦌", rbrksld: "⦎", rbrkslu: "⦐", Rcaron: "Ř", rcaron: "ř", Rcedil: "Ŗ", rcedil: "ŗ", rceil: "⌉", rcub: "}", Rcy: "Р", rcy: "р", rdca: "⤷", rdldhar: "⥩", rdquo: "”", rdquor: "”", rdsh: "↳", Re: "ℜ", real: "ℜ", realine: "ℛ", realpart: "ℜ", reals: "ℝ", rect: "▭", REG: "®", reg: "®", ReverseElement: "∋", ReverseEquilibrium: "⇋", ReverseUpEquilibrium: "⥯", rfisht: "⥽", rfloor: "⌋", Rfr: "ℜ", rfr: "𝔯", rHar: "⥤", rhard: "⇁", rharu: "⇀", rharul: "⥬", Rho: "Ρ", rho: "ρ", rhov: "ϱ", RightAngleBracket: "⟩", RightArrow: "→", Rightarrow: "⇒", rightarrow: "→", RightArrowBar: "⇥", RightArrowLeftArrow: "⇄", rightarrowtail: "↣", RightCeiling: "⌉", RightDoubleBracket: "⟧", RightDownTeeVector: "⥝", RightDownVector: "⇂", RightDownVectorBar: "⥕", RightFloor: "⌋", rightharpoondown: "⇁", rightharpoonup: "⇀", rightleftarrows: "⇄", rightleftharpoons: "⇌", rightrightarrows: "⇉", rightsquigarrow: "↝", RightTee: "⊢", RightTeeArrow: "↦", RightTeeVector: "⥛", rightthreetimes: "⋌", RightTriangle: "⊳", RightTriangleBar: "⧐", RightTriangleEqual: "⊵", RightUpDownVector: "⥏", RightUpTeeVector: "⥜", RightUpVector: "↾", RightUpVectorBar: "⥔", RightVector: "⇀", RightVectorBar: "⥓", ring: "˚", risingdotseq: "≓", rlarr: "⇄", rlhar: "⇌", rlm: "‏", rmoust: "⎱", rmoustache: "⎱", rnmid: "⫮", roang: "⟭", roarr: "⇾", robrk: "⟧", ropar: "⦆", Ropf: "ℝ", ropf: "𝕣", roplus: "⨮", rotimes: "⨵", RoundImplies: "⥰", rpar: ")", rpargt: "⦔", rppolint: "⨒", rrarr: "⇉", Rrightarrow: "⇛", rsaquo: "›", Rscr: "ℛ", rscr: "𝓇", Rsh: "↱", rsh: "↱", rsqb: "]", rsquo: "’", rsquor: "’", rthree: "⋌", rtimes: "⋊", rtri: "▹", rtrie: "⊵", rtrif: "▸", rtriltri: "⧎", RuleDelayed: "⧴", ruluhar: "⥨", rx: "℞", Sacute: "Ś", sacute: "ś", sbquo: "‚", Sc: "⪼", sc: "≻", scap: "⪸", Scaron: "Š", scaron: "š", sccue: "≽", scE: "⪴", sce: "⪰", Scedil: "Ş", scedil: "ş", Scirc: "Ŝ", scirc: "ŝ", scnap: "⪺", scnE: "⪶", scnsim: "⋩", scpolint: "⨓", scsim: "≿", Scy: "С", scy: "с", sdot: "⋅", sdotb: "⊡", sdote: "⩦", searhk: "⤥", seArr: "⇘", searr: "↘", searrow: "↘", sect: "§", semi: ";", seswar: "⤩", setminus: "∖", setmn: "∖", sext: "✶", Sfr: "𝔖", sfr: "𝔰", sfrown: "⌢", sharp: "♯", SHCHcy: "Щ", shchcy: "щ", SHcy: "Ш", shcy: "ш", ShortDownArrow: "↓", ShortLeftArrow: "←", shortmid: "∣", shortparallel: "∥", ShortRightArrow: "→", ShortUpArrow: "↑", shy: "­", Sigma: "Σ", sigma: "σ", sigmaf: "ς", sigmav: "ς", sim: "∼", simdot: "⩪", sime: "≃", simeq: "≃", simg: "⪞", simgE: "⪠", siml: "⪝", simlE: "⪟", simne: "≆", simplus: "⨤", simrarr: "⥲", slarr: "←", SmallCircle: "∘", smallsetminus: "∖", smashp: "⨳", smeparsl: "⧤", smid: "∣", smile: "⌣", smt: "⪪", smte: "⪬", smtes: "⪬︀", SOFTcy: "Ь", softcy: "ь", sol: "/", solb: "⧄", solbar: "⌿", Sopf: "𝕊", sopf: "𝕤", spades: "♠", spadesuit: "♠", spar: "∥", sqcap: "⊓", sqcaps: "⊓︀", sqcup: "⊔", sqcups: "⊔︀", Sqrt: "√", sqsub: "⊏", sqsube: "⊑", sqsubset: "⊏", sqsubseteq: "⊑", sqsup: "⊐", sqsupe: "⊒", sqsupset: "⊐", sqsupseteq: "⊒", squ: "□", Square: "□", square: "□", SquareIntersection: "⊓", SquareSubset: "⊏", SquareSubsetEqual: "⊑", SquareSuperset: "⊐", SquareSupersetEqual: "⊒", SquareUnion: "⊔", squarf: "▪", squf: "▪", srarr: "→", Sscr: "𝒮", sscr: "𝓈", ssetmn: "∖", ssmile: "⌣", sstarf: "⋆", Star: "⋆", star: "☆", starf: "★", straightepsilon: "ϵ", straightphi: "ϕ", strns: "¯", Sub: "⋐", sub: "⊂", subdot: "⪽", subE: "⫅", sube: "⊆", subedot: "⫃", submult: "⫁", subnE: "⫋", subne: "⊊", subplus: "⪿", subrarr: "⥹", Subset: "⋐", subset: "⊂", subseteq: "⊆", subseteqq: "⫅", SubsetEqual: "⊆", subsetneq: "⊊", subsetneqq: "⫋", subsim: "⫇", subsub: "⫕", subsup: "⫓", succ: "≻", succapprox: "⪸", succcurlyeq: "≽", Succeeds: "≻", SucceedsEqual: "⪰", SucceedsSlantEqual: "≽", SucceedsTilde: "≿", succeq: "⪰", succnapprox: "⪺", succneqq: "⪶", succnsim: "⋩", succsim: "≿", SuchThat: "∋", Sum: "∑", sum: "∑", sung: "♪", Sup: "⋑", sup: "⊃", sup1: "¹", sup2: "²", sup3: "³", supdot: "⪾", supdsub: "⫘", supE: "⫆", supe: "⊇", supedot: "⫄", Superset: "⊃", SupersetEqual: "⊇", suphsol: "⟉", suphsub: "⫗", suplarr: "⥻", supmult: "⫂", supnE: "⫌", supne: "⊋", supplus: "⫀", Supset: "⋑", supset: "⊃", supseteq: "⊇", supseteqq: "⫆", supsetneq: "⊋", supsetneqq: "⫌", supsim: "⫈", supsub: "⫔", supsup: "⫖", swarhk: "⤦", swArr: "⇙", swarr: "↙", swarrow: "↙", swnwar: "⤪", szlig: "ß", Tab: " ", target: "⌖", Tau: "Τ", tau: "τ", tbrk: "⎴", Tcaron: "Ť", tcaron: "ť", Tcedil: "Ţ", tcedil: "ţ", Tcy: "Т", tcy: "т", tdot: "⃛", telrec: "⌕", Tfr: "𝔗", tfr: "𝔱", there4: "∴", Therefore: "∴", therefore: "∴", Theta: "Θ", theta: "θ", thetasym: "ϑ", thetav: "ϑ", thickapprox: "≈", thicksim: "∼", ThickSpace: "  ", thinsp: " ", ThinSpace: " ", thkap: "≈", thksim: "∼", THORN: "Þ", thorn: "þ", Tilde: "∼", tilde: "˜", TildeEqual: "≃", TildeFullEqual: "≅", TildeTilde: "≈", times: "×", timesb: "⊠", timesbar: "⨱", timesd: "⨰", tint: "∭", toea: "⤨", top: "⊤", topbot: "⌶", topcir: "⫱", Topf: "𝕋", topf: "𝕥", topfork: "⫚", tosa: "⤩", tprime: "‴", TRADE: "™", trade: "™", triangle: "▵", triangledown: "▿", triangleleft: "◃", trianglelefteq: "⊴", triangleq: "≜", triangleright: "▹", trianglerighteq: "⊵", tridot: "◬", trie: "≜", triminus: "⨺", TripleDot: "⃛", triplus: "⨹", trisb: "⧍", tritime: "⨻", trpezium: "⏢", Tscr: "𝒯", tscr: "𝓉", TScy: "Ц", tscy: "ц", TSHcy: "Ћ", tshcy: "ћ", Tstrok: "Ŧ", tstrok: "ŧ", twixt: "≬", twoheadleftarrow: "↞", twoheadrightarrow: "↠", Uacute: "Ú", uacute: "ú", Uarr: "↟", uArr: "⇑", uarr: "↑", Uarrocir: "⥉", Ubrcy: "Ў", ubrcy: "ў", Ubreve: "Ŭ", ubreve: "ŭ", Ucirc: "Û", ucirc: "û", Ucy: "У", ucy: "у", udarr: "⇅", Udblac: "Ű", udblac: "ű", udhar: "⥮", ufisht: "⥾", Ufr: "𝔘", ufr: "𝔲", Ugrave: "Ù", ugrave: "ù", uHar: "⥣", uharl: "↿", uharr: "↾", uhblk: "▀", ulcorn: "⌜", ulcorner: "⌜", ulcrop: "⌏", ultri: "◸", Umacr: "Ū", umacr: "ū", uml: "¨", UnderBar: "_", UnderBrace: "⏟", UnderBracket: "⎵", UnderParenthesis: "⏝", Union: "⋃", UnionPlus: "⊎", Uogon: "Ų", uogon: "ų", Uopf: "𝕌", uopf: "𝕦", UpArrow: "↑", Uparrow: "⇑", uparrow: "↑", UpArrowBar: "⤒", UpArrowDownArrow: "⇅", UpDownArrow: "↕", Updownarrow: "⇕", updownarrow: "↕", UpEquilibrium: "⥮", upharpoonleft: "↿", upharpoonright: "↾", uplus: "⊎", UpperLeftArrow: "↖", UpperRightArrow: "↗", Upsi: "ϒ", upsi: "υ", upsih: "ϒ", Upsilon: "Υ", upsilon: "υ", UpTee: "⊥", UpTeeArrow: "↥", upuparrows: "⇈", urcorn: "⌝", urcorner: "⌝", urcrop: "⌎", Uring: "Ů", uring: "ů", urtri: "◹", Uscr: "𝒰", uscr: "𝓊", utdot: "⋰", Utilde: "Ũ", utilde: "ũ", utri: "▵", utrif: "▴", uuarr: "⇈", Uuml: "Ü", uuml: "ü", uwangle: "⦧", vangrt: "⦜", varepsilon: "ϵ", varkappa: "ϰ", varnothing: "∅", varphi: "ϕ", varpi: "ϖ", varpropto: "∝", vArr: "⇕", varr: "↕", varrho: "ϱ", varsigma: "ς", varsubsetneq: "⊊︀", varsubsetneqq: "⫋︀", varsupsetneq: "⊋︀", varsupsetneqq: "⫌︀", vartheta: "ϑ", vartriangleleft: "⊲", vartriangleright: "⊳", Vbar: "⫫", vBar: "⫨", vBarv: "⫩", Vcy: "В", vcy: "в", VDash: "⊫", Vdash: "⊩", vDash: "⊨", vdash: "⊢", Vdashl: "⫦", Vee: "⋁", vee: "∨", veebar: "⊻", veeeq: "≚", vellip: "⋮", Verbar: "‖", verbar: "|", Vert: "‖", vert: "|", VerticalBar: "∣", VerticalLine: "|", VerticalSeparator: "❘", VerticalTilde: "≀", VeryThinSpace: " ", Vfr: "𝔙", vfr: "𝔳", vltri: "⊲", vnsub: "⊂⃒", vnsup: "⊃⃒", Vopf: "𝕍", vopf: "𝕧", vprop: "∝", vrtri: "⊳", Vscr: "𝒱", vscr: "𝓋", vsubnE: "⫋︀", vsubne: "⊊︀", vsupnE: "⫌︀", vsupne: "⊋︀", Vvdash: "⊪", vzigzag: "⦚", Wcirc: "Ŵ", wcirc: "ŵ", wedbar: "⩟", Wedge: "⋀", wedge: "∧", wedgeq: "≙", weierp: "℘", Wfr: "𝔚", wfr: "𝔴", Wopf: "𝕎", wopf: "𝕨", wp: "℘", wr: "≀", wreath: "≀", Wscr: "𝒲", wscr: "𝓌", xcap: "⋂", xcirc: "◯", xcup: "⋃", xdtri: "▽", Xfr: "𝔛", xfr: "𝔵", xhArr: "⟺", xharr: "⟷", Xi: "Ξ", xi: "ξ", xlArr: "⟸", xlarr: "⟵", xmap: "⟼", xnis: "⋻", xodot: "⨀", Xopf: "𝕏", xopf: "𝕩", xoplus: "⨁", xotime: "⨂", xrArr: "⟹", xrarr: "⟶", Xscr: "𝒳", xscr: "𝓍", xsqcup: "⨆", xuplus: "⨄", xutri: "△", xvee: "⋁", xwedge: "⋀", Yacute: "Ý", yacute: "ý", YAcy: "Я", yacy: "я", Ycirc: "Ŷ", ycirc: "ŷ", Ycy: "Ы", ycy: "ы", yen: "¥", Yfr: "𝔜", yfr: "𝔶", YIcy: "Ї", yicy: "ї", Yopf: "𝕐", yopf: "𝕪", Yscr: "𝒴", yscr: "𝓎", YUcy: "Ю", yucy: "ю", Yuml: "Ÿ", yuml: "ÿ", Zacute: "Ź", zacute: "ź", Zcaron: "Ž", zcaron: "ž", Zcy: "З", zcy: "з", Zdot: "Ż", zdot: "ż", zeetrf: "ℨ", ZeroWidthSpace: "​", Zeta: "Ζ", zeta: "ζ", Zfr: "ℨ", zfr: "𝔷", ZHcy: "Ж", zhcy: "ж", zigrarr: "⇝", Zopf: "ℤ", zopf: "𝕫", Zscr: "𝒵", zscr: "𝓏", zwj: "‍", zwnj: "‌" }); exports.entityMap = exports.HTML_ENTITIES; } }); // node_modules/@xmldom/xmldom/lib/sax.js var require_sax = __commonJS({ "node_modules/@xmldom/xmldom/lib/sax.js"(exports) { var NAMESPACE = require_conventions().NAMESPACE; var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/; var nameChar = new RegExp("[\\-\\.0-9" + nameStartChar.source.slice(1, -1) + "\\u00B7\\u0300-\\u036F\\u203F-\\u2040]"); var tagNamePattern = new RegExp("^" + nameStartChar.source + nameChar.source + "*(?::" + nameStartChar.source + nameChar.source + "*)?$"); var S_TAG = 0; var S_ATTR = 1; var S_ATTR_SPACE = 2; var S_EQ = 3; var S_ATTR_NOQUOT_VALUE = 4; var S_ATTR_END = 5; var S_TAG_SPACE = 6; var S_TAG_CLOSE = 7; function ParseError(message, locator) { this.message = message; this.locator = locator; if (Error.captureStackTrace) Error.captureStackTrace(this, ParseError); } ParseError.prototype = new Error(); ParseError.prototype.name = ParseError.name; function XMLReader() { } XMLReader.prototype = { parse: function(source, defaultNSMap, entityMap) { var domBuilder = this.domBuilder; domBuilder.startDocument(); _copy(defaultNSMap, defaultNSMap = {}); parse2( source, defaultNSMap, entityMap, domBuilder, this.errorHandler ); domBuilder.endDocument(); } }; function parse2(source, defaultNSMapCopy, entityMap, domBuilder, errorHandler) { function fixedFromCharCode(code) { if (code > 65535) { code -= 65536; var surrogate1 = 55296 + (code >> 10), surrogate2 = 56320 + (code & 1023); return String.fromCharCode(surrogate1, surrogate2); } else { return String.fromCharCode(code); } } function entityReplacer(a2) { var k = a2.slice(1, -1); if (Object.hasOwnProperty.call(entityMap, k)) { return entityMap[k]; } else if (k.charAt(0) === "#") { return fixedFromCharCode(parseInt(k.substr(1).replace("x", "0x"))); } else { errorHandler.error("entity not found:" + a2); return a2; } } function appendText(end2) { if (end2 > start) { var xt = source.substring(start, end2).replace(/&#?\w+;/g, entityReplacer); locator && position(start); domBuilder.characters(xt, 0, end2 - start); start = end2; } } function position(p, m) { while (p >= lineEnd && (m = linePattern.exec(source))) { lineStart = m.index; lineEnd = lineStart + m[0].length; locator.lineNumber++; } locator.columnNumber = p - lineStart + 1; } var lineStart = 0; var lineEnd = 0; var linePattern = /.*(?:\r\n?|\n)|.*$/g; var locator = domBuilder.locator; var parseStack = [{ currentNSMap: defaultNSMapCopy }]; var closeMap = {}; var start = 0; while (true) { try { var tagStart = source.indexOf("<", start); if (tagStart < 0) { if (!source.substr(start).match(/^\s*$/)) { var doc = domBuilder.doc; var text = doc.createTextNode(source.substr(start)); doc.appendChild(text); domBuilder.currentElement = text; } return; } if (tagStart > start) { appendText(tagStart); } switch (source.charAt(tagStart + 1)) { case "/": var end = source.indexOf(">", tagStart + 3); var tagName = source.substring(tagStart + 2, end).replace(/[ \t\n\r]+$/g, ""); var config = parseStack.pop(); if (end < 0) { tagName = source.substring(tagStart + 2).replace(/[\s<].*/, ""); errorHandler.error("end tag name: " + tagName + " is not complete:" + config.tagName); end = tagStart + 1 + tagName.length; } else if (tagName.match(/\s start) { start = end; } else { appendText(Math.max(tagStart, start) + 1); } } } function copyLocator(f, t) { t.lineNumber = f.lineNumber; t.columnNumber = f.columnNumber; return t; } function parseElementStartPart(source, start, el, currentNSMap, entityReplacer, errorHandler) { function addAttribute(qname, value2, startIndex) { if (el.attributeNames.hasOwnProperty(qname)) { errorHandler.fatalError("Attribute " + qname + " redefined"); } el.addValue( qname, // @see https://www.w3.org/TR/xml/#AVNormalize // since the xmldom sax parser does not "interpret" DTD the following is not implemented: // - recursive replacement of (DTD) entity references // - trimming and collapsing multiple spaces into a single one for attributes that are not of type CDATA value2.replace(/[\t\n\r]/g, " ").replace(/&#?\w+;/g, entityReplacer), startIndex ); } var attrName; var value; var p = ++start; var s = S_TAG; while (true) { var c = source.charAt(p); switch (c) { case "=": if (s === S_ATTR) { attrName = source.slice(start, p); s = S_EQ; } else if (s === S_ATTR_SPACE) { s = S_EQ; } else { throw new Error("attribute equal must after attrName"); } break; case "'": case '"': if (s === S_EQ || s === S_ATTR) { if (s === S_ATTR) { errorHandler.warning('attribute value must after "="'); attrName = source.slice(start, p); } start = p + 1; p = source.indexOf(c, start); if (p > 0) { value = source.slice(start, p); addAttribute(attrName, value, start - 1); s = S_ATTR_END; } else { throw new Error("attribute value no end '" + c + "' match"); } } else if (s == S_ATTR_NOQUOT_VALUE) { value = source.slice(start, p); addAttribute(attrName, value, start); errorHandler.warning('attribute "' + attrName + '" missed start quot(' + c + ")!!"); start = p + 1; s = S_ATTR_END; } else { throw new Error('attribute value must after "="'); } break; case "/": switch (s) { case S_TAG: el.setTagName(source.slice(start, p)); case S_ATTR_END: case S_TAG_SPACE: case S_TAG_CLOSE: s = S_TAG_CLOSE; el.closed = true; case S_ATTR_NOQUOT_VALUE: case S_ATTR: break; case S_ATTR_SPACE: el.closed = true; break; default: throw new Error("attribute invalid close char('/')"); } break; case "": errorHandler.error("unexpected end of input"); if (s == S_TAG) { el.setTagName(source.slice(start, p)); } return p; case ">": switch (s) { case S_TAG: el.setTagName(source.slice(start, p)); case S_ATTR_END: case S_TAG_SPACE: case S_TAG_CLOSE: break; case S_ATTR_NOQUOT_VALUE: case S_ATTR: value = source.slice(start, p); if (value.slice(-1) === "/") { el.closed = true; value = value.slice(0, -1); } case S_ATTR_SPACE: if (s === S_ATTR_SPACE) { value = attrName; } if (s == S_ATTR_NOQUOT_VALUE) { errorHandler.warning('attribute "' + value + '" missed quot(")!'); addAttribute(attrName, value, start); } else { if (!NAMESPACE.isHTML(currentNSMap[""]) || !value.match(/^(?:disabled|checked|selected)$/i)) { errorHandler.warning('attribute "' + value + '" missed value!! "' + value + '" instead!!'); } addAttribute(value, value, start); } break; case S_EQ: throw new Error("attribute value missed!!"); } return p; case "€": c = " "; default: if (c <= " ") { switch (s) { case S_TAG: el.setTagName(source.slice(start, p)); s = S_TAG_SPACE; break; case S_ATTR: attrName = source.slice(start, p); s = S_ATTR_SPACE; break; case S_ATTR_NOQUOT_VALUE: var value = source.slice(start, p); errorHandler.warning('attribute "' + value + '" missed quot(")!!'); addAttribute(attrName, value, start); case S_ATTR_END: s = S_TAG_SPACE; break; } } else { switch (s) { case S_ATTR_SPACE: var tagName = el.tagName; if (!NAMESPACE.isHTML(currentNSMap[""]) || !attrName.match(/^(?:disabled|checked|selected)$/i)) { errorHandler.warning('attribute "' + attrName + '" missed value!! "' + attrName + '" instead2!!'); } addAttribute(attrName, attrName, start); start = p; s = S_ATTR; break; case S_ATTR_END: errorHandler.warning('attribute space is required"' + attrName + '"!!'); case S_TAG_SPACE: s = S_ATTR; start = p; break; case S_EQ: s = S_ATTR_NOQUOT_VALUE; start = p; break; case S_TAG_CLOSE: throw new Error("elements closed character '/' and '>' must be connected to"); } } } p++; } } function appendElement(el, domBuilder, currentNSMap) { var tagName = el.tagName; var localNSMap = null; var i = el.length; while (i--) { var a = el[i]; var qName = a.qName; var value = a.value; var nsp = qName.indexOf(":"); if (nsp > 0) { var prefix = a.prefix = qName.slice(0, nsp); var localName = qName.slice(nsp + 1); var nsPrefix = prefix === "xmlns" && localName; } else { localName = qName; prefix = null; nsPrefix = qName === "xmlns" && ""; } a.localName = localName; if (nsPrefix !== false) { if (localNSMap == null) { localNSMap = {}; _copy(currentNSMap, currentNSMap = {}); } currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value; a.uri = NAMESPACE.XMLNS; domBuilder.startPrefixMapping(nsPrefix, value); } } var i = el.length; while (i--) { a = el[i]; var prefix = a.prefix; if (prefix) { if (prefix === "xml") { a.uri = NAMESPACE.XML; } if (prefix !== "xmlns") { a.uri = currentNSMap[prefix || ""]; } } } var nsp = tagName.indexOf(":"); if (nsp > 0) { prefix = el.prefix = tagName.slice(0, nsp); localName = el.localName = tagName.slice(nsp + 1); } else { prefix = null; localName = el.localName = tagName; } var ns = el.uri = currentNSMap[prefix || ""]; domBuilder.startElement(ns, localName, tagName, el); if (el.closed) { domBuilder.endElement(ns, localName, tagName); if (localNSMap) { for (prefix in localNSMap) { if (Object.prototype.hasOwnProperty.call(localNSMap, prefix)) { domBuilder.endPrefixMapping(prefix); } } } } else { el.currentNSMap = currentNSMap; el.localNSMap = localNSMap; return true; } } function parseHtmlSpecialContent(source, elStartEnd, tagName, entityReplacer, domBuilder) { if (/^(?:script|textarea)$/i.test(tagName)) { var elEndStart = source.indexOf("", elStartEnd); var text = source.substring(elStartEnd + 1, elEndStart); if (/[&<]/.test(text)) { if (/^script$/i.test(tagName)) { domBuilder.characters(text, 0, text.length); return elEndStart; } text = text.replace(/&#?\w+;/g, entityReplacer); domBuilder.characters(text, 0, text.length); return elEndStart; } } return elStartEnd + 1; } function fixSelfClosed(source, elStartEnd, tagName, closeMap) { var pos = closeMap[tagName]; if (pos == null) { pos = source.lastIndexOf(""); if (pos < elStartEnd) { pos = source.lastIndexOf("", start + 4); if (end > start) { domBuilder.comment(source, start + 4, end - start - 4); return end + 3; } else { errorHandler.error("Unclosed comment"); return -1; } } else { return -1; } default: if (source.substr(start + 3, 6) == "CDATA[") { var end = source.indexOf("]]>", start + 9); domBuilder.startCDATA(); domBuilder.characters(source, start + 9, end - start - 9); domBuilder.endCDATA(); return end + 3; } var matchs = split(source, start); var len = matchs.length; if (len > 1 && /!doctype/i.test(matchs[0][0])) { var name = matchs[1][0]; var pubid = false; var sysid = false; if (len > 3) { if (/^public$/i.test(matchs[2][0])) { pubid = matchs[3][0]; sysid = len > 4 && matchs[4][0]; } else if (/^system$/i.test(matchs[2][0])) { sysid = matchs[3][0]; } } var lastMatch = matchs[len - 1]; domBuilder.startDTD(name, pubid, sysid); domBuilder.endDTD(); return lastMatch.index + lastMatch[0].length; } } return -1; } function parseInstruction(source, start, domBuilder) { var end = source.indexOf("?>", start); if (end) { var match = source.substring(start, end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/); if (match) { var len = match[0].length; domBuilder.processingInstruction(match[1], match[2]); return end + 2; } else { return -1; } } return -1; } function ElementAttributes() { this.attributeNames = {}; } ElementAttributes.prototype = { setTagName: function(tagName) { if (!tagNamePattern.test(tagName)) { throw new Error("invalid tagName:" + tagName); } this.tagName = tagName; }, addValue: function(qName, value, offset) { if (!tagNamePattern.test(qName)) { throw new Error("invalid attribute:" + qName); } this.attributeNames[qName] = this.length; this[this.length++] = { qName, value, offset }; }, length: 0, getLocalName: function(i) { return this[i].localName; }, getLocator: function(i) { return this[i].locator; }, getQName: function(i) { return this[i].qName; }, getURI: function(i) { return this[i].uri; }, getValue: function(i) { return this[i].value; } // ,getIndex:function(uri, localName)){ // if(localName){ // // }else{ // var qName = uri // } // }, // getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))}, // getType:function(uri,localName){} // getType:function(i){}, }; function split(source, start) { var match; var buf = []; var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g; reg.lastIndex = start; reg.exec(source); while (match = reg.exec(source)) { buf.push(match); if (match[1]) return buf; } } exports.XMLReader = XMLReader; exports.ParseError = ParseError; } }); // node_modules/@xmldom/xmldom/lib/dom-parser.js var require_dom_parser = __commonJS({ "node_modules/@xmldom/xmldom/lib/dom-parser.js"(exports) { var conventions = require_conventions(); var dom = require_dom(); var entities = require_entities(); var sax = require_sax(); var DOMImplementation = dom.DOMImplementation; var NAMESPACE = conventions.NAMESPACE; var ParseError = sax.ParseError; var XMLReader = sax.XMLReader; function normalizeLineEndings(input) { return input.replace(/\r[\n\u0085]/g, "\n").replace(/[\r\u0085\u2028]/g, "\n"); } function DOMParser2(options) { this.options = options || { locator: {} }; } DOMParser2.prototype.parseFromString = function(source, mimeType) { var options = this.options; var sax2 = new XMLReader(); var domBuilder = options.domBuilder || new DOMHandler(); var errorHandler = options.errorHandler; var locator = options.locator; var defaultNSMap = options.xmlns || {}; var isHTML = /\/x?html?$/.test(mimeType); var entityMap = isHTML ? entities.HTML_ENTITIES : entities.XML_ENTITIES; if (locator) { domBuilder.setDocumentLocator(locator); } sax2.errorHandler = buildErrorHandler(errorHandler, domBuilder, locator); sax2.domBuilder = options.domBuilder || domBuilder; if (isHTML) { defaultNSMap[""] = NAMESPACE.HTML; } defaultNSMap.xml = defaultNSMap.xml || NAMESPACE.XML; var normalize = options.normalizeLineEndings || normalizeLineEndings; if (source && typeof source === "string") { sax2.parse( normalize(source), defaultNSMap, entityMap ); } else { sax2.errorHandler.error("invalid doc source"); } return domBuilder.doc; }; function buildErrorHandler(errorImpl, domBuilder, locator) { if (!errorImpl) { if (domBuilder instanceof DOMHandler) { return domBuilder; } errorImpl = domBuilder; } var errorHandler = {}; var isCallback = errorImpl instanceof Function; locator = locator || {}; function build(key) { var fn = errorImpl[key]; if (!fn && isCallback) { fn = errorImpl.length == 2 ? function(msg) { errorImpl(key, msg); } : errorImpl; } errorHandler[key] = fn && function(msg) { fn("[xmldom " + key + "] " + msg + _locator(locator)); } || function() { }; } build("warning"); build("error"); build("fatalError"); return errorHandler; } function DOMHandler() { this.cdata = false; } function position(locator, node) { node.lineNumber = locator.lineNumber; node.columnNumber = locator.columnNumber; } DOMHandler.prototype = { startDocument: function() { this.doc = new DOMImplementation().createDocument(null, null, null); if (this.locator) { this.doc.documentURI = this.locator.systemId; } }, startElement: function(namespaceURI, localName, qName, attrs) { var doc = this.doc; var el = doc.createElementNS(namespaceURI, qName || localName); var len = attrs.length; appendElement(this, el); this.currentElement = el; this.locator && position(this.locator, el); for (var i = 0; i < len; i++) { var namespaceURI = attrs.getURI(i); var value = attrs.getValue(i); var qName = attrs.getQName(i); var attr = doc.createAttributeNS(namespaceURI, qName); this.locator && position(attrs.getLocator(i), attr); attr.value = attr.nodeValue = value; el.setAttributeNode(attr); } }, endElement: function(namespaceURI, localName, qName) { var current = this.currentElement; var tagName = current.tagName; this.currentElement = current.parentNode; }, startPrefixMapping: function(prefix, uri) { }, endPrefixMapping: function(prefix) { }, processingInstruction: function(target, data) { var ins = this.doc.createProcessingInstruction(target, data); this.locator && position(this.locator, ins); appendElement(this, ins); }, ignorableWhitespace: function(ch, start, length) { }, characters: function(chars, start, length) { chars = _toString.apply(this, arguments); if (chars) { if (this.cdata) { var charNode = this.doc.createCDATASection(chars); } else { var charNode = this.doc.createTextNode(chars); } if (this.currentElement) { this.currentElement.appendChild(charNode); } else if (/^\s*$/.test(chars)) { this.doc.appendChild(charNode); } this.locator && position(this.locator, charNode); } }, skippedEntity: function(name) { }, endDocument: function() { this.doc.normalize(); }, setDocumentLocator: function(locator) { if (this.locator = locator) { locator.lineNumber = 0; } }, //LexicalHandler comment: function(chars, start, length) { chars = _toString.apply(this, arguments); var comm = this.doc.createComment(chars); this.locator && position(this.locator, comm); appendElement(this, comm); }, startCDATA: function() { this.cdata = true; }, endCDATA: function() { this.cdata = false; }, startDTD: function(name, publicId, systemId) { var impl = this.doc.implementation; if (impl && impl.createDocumentType) { var dt = impl.createDocumentType(name, publicId, systemId); this.locator && position(this.locator, dt); appendElement(this, dt); this.doc.doctype = dt; } }, /** * @see org.xml.sax.ErrorHandler * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html */ warning: function(error) { console.warn("[xmldom warning] " + error, _locator(this.locator)); }, error: function(error) { console.error("[xmldom error] " + error, _locator(this.locator)); }, fatalError: function(error) { throw new ParseError(error, this.locator); } }; function _locator(l) { if (l) { return "\n@" + (l.systemId || "") + "#[line:" + l.lineNumber + ",col:" + l.columnNumber + "]"; } } function _toString(chars, start, length) { if (typeof chars == "string") { return chars.substr(start, length); } else { if (chars.length >= start + length || start) { return new java.lang.String(chars, start, length) + ""; } return chars; } } "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g, function(key) { DOMHandler.prototype[key] = function() { return null; }; }); function appendElement(hander, node) { if (!hander.currentElement) { hander.doc.appendChild(node); } else { hander.currentElement.appendChild(node); } } exports.__DOMHandler = DOMHandler; exports.normalizeLineEndings = normalizeLineEndings; exports.DOMParser = DOMParser2; } }); // node_modules/@xmldom/xmldom/lib/index.js var require_lib2 = __commonJS({ "node_modules/@xmldom/xmldom/lib/index.js"(exports) { var dom = require_dom(); exports.DOMImplementation = dom.DOMImplementation; exports.XMLSerializer = dom.XMLSerializer; exports.DOMParser = require_dom_parser().DOMParser; } }); // node_modules/mux.js/lib/utils/numbers.js var require_numbers = __commonJS({ "node_modules/mux.js/lib/utils/numbers.js"(exports, module) { 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, MAX_UINT32 }; } }); // node_modules/mux.js/lib/tools/parse-sidx.js var require_parse_sidx = __commonJS({ "node_modules/mux.js/lib/tools/parse-sidx.js"(exports, module) { var getUint64 = require_numbers().getUint64; var parseSidx2 = 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 { result.earliestPresentationTime = getUint64(data.subarray(i)); result.firstOffset = getUint64(data.subarray(i + 8)); i += 16; } i += 2; var referenceCount = view.getUint16(i); i += 2; for (; referenceCount > 0; i += 12, referenceCount--) { result.references.push({ referenceType: (data[i] & 128) >>> 7, referencedSize: view.getUint32(i) & 2147483647, subsegmentDuration: view.getUint32(i + 4), startsWithSap: !!(data[i + 8] & 128), sapType: (data[i + 8] & 112) >>> 4, sapDeltaTime: view.getUint32(i + 8) & 268435455 }); } return result; }; module.exports = parseSidx2; } }); // node_modules/mux.js/lib/utils/clock.js var require_clock = __commonJS({ "node_modules/mux.js/lib/utils/clock.js"(exports, module) { var ONE_SECOND_IN_TS2 = 9e4; var secondsToVideoTs; var secondsToAudioTs; var videoTsToSeconds; var audioTsToSeconds; var audioTsToVideoTs; var videoTsToAudioTs; var metadataTsToSeconds; secondsToVideoTs = function(seconds) { return seconds * ONE_SECOND_IN_TS2; }; secondsToAudioTs = function(seconds, sampleRate) { return seconds * sampleRate; }; videoTsToSeconds = function(timestamp) { return timestamp / ONE_SECOND_IN_TS2; }; 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); }; metadataTsToSeconds = function(timestamp, timelineStartPts, keepOriginalTimestamps) { return videoTsToSeconds(keepOriginalTimestamps ? timestamp : timestamp - timelineStartPts); }; module.exports = { ONE_SECOND_IN_TS: ONE_SECOND_IN_TS2, secondsToVideoTs, secondsToAudioTs, videoTsToSeconds, audioTsToSeconds, audioTsToVideoTs, videoTsToAudioTs, metadataTsToSeconds }; } }); // node_modules/video.js/dist/video.es.js var import_window6 = __toESM(require_window()); var import_document = __toESM(require_document()); var import_xhr = __toESM(require_lib()); var import_videojs_vtt = __toESM(require_browser_index()); // node_modules/@babel/runtime/helpers/esm/extends.js function _extends() { _extends = Object.assign ? Object.assign.bind() : function(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } // node_modules/@videojs/vhs-utils/es/resolve-url.js var import_window = __toESM(require_window()); var DEFAULT_LOCATION = "https://example.com"; var resolveUrl = function resolveUrl2(baseUrl, relativeUrl) { if (/^[a-z]+:/i.test(relativeUrl)) { return relativeUrl; } if (/^data:/.test(baseUrl)) { baseUrl = import_window.default.location && import_window.default.location.href || ""; } var protocolLess = /^\/\//.test(baseUrl); var removeLocation = !import_window.default.location && !/\/\//i.test(baseUrl); baseUrl = new import_window.default.URL(baseUrl, import_window.default.location || DEFAULT_LOCATION); var newUrl = new URL(relativeUrl, baseUrl); if (removeLocation) { return newUrl.href.slice(DEFAULT_LOCATION.length); } else if (protocolLess) { return newUrl.href.slice(newUrl.protocol.length); } return newUrl.href; }; var resolve_url_default = resolveUrl; // node_modules/@videojs/vhs-utils/es/stream.js var Stream = function() { function Stream2() { this.listeners = {}; } var _proto = Stream2.prototype; _proto.on = function on2(type, listener) { if (!this.listeners[type]) { this.listeners[type] = []; } this.listeners[type].push(listener); }; _proto.off = function off2(type, listener) { if (!this.listeners[type]) { return false; } var index = this.listeners[type].indexOf(listener); this.listeners[type] = this.listeners[type].slice(0); this.listeners[type].splice(index, 1); return index > -1; }; _proto.trigger = function trigger2(type) { var callbacks = this.listeners[type]; if (!callbacks) { return; } if (arguments.length === 2) { var length = callbacks.length; for (var i = 0; i < length; ++i) { callbacks[i].call(this, arguments[1]); } } else { var args = Array.prototype.slice.call(arguments, 1); var _length = callbacks.length; for (var _i = 0; _i < _length; ++_i) { callbacks[_i].apply(this, args); } } }; _proto.dispose = function dispose() { this.listeners = {}; }; _proto.pipe = function pipe(destination) { this.on("data", function(data) { destination.push(data); }); }; return Stream2; }(); // node_modules/@videojs/vhs-utils/es/decode-b64-to-uint8-array.js var import_window2 = __toESM(require_window()); var atob = function atob2(s) { return import_window2.default.atob ? import_window2.default.atob(s) : Buffer.from(s, "base64").toString("binary"); }; function decodeB64ToUint8Array(b64Text) { var decodedString = atob(b64Text); var array = new Uint8Array(decodedString.length); for (var i = 0; i < decodedString.length; i++) { array[i] = decodedString.charCodeAt(i); } return array; } // node_modules/m3u8-parser/dist/m3u8-parser.es.js var LineStream = class extends Stream { constructor() { super(); this.buffer = ""; } /** * Add new data to be parsed. * * @param {string} data the text to process */ push(data) { let 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); } } }; var TAB = String.fromCharCode(9); var parseByterange = function(byterangeString) { const match = /([0-9.]*)?@?([0-9.]*)?/.exec(byterangeString || ""); const result = {}; if (match[1]) { result.length = parseInt(match[1], 10); } if (match[2]) { result.offset = parseInt(match[2], 10); } return result; }; var attributeSeparator = function() { const key = "[^=]*"; const value = '"[^"]*"|[^,]*'; const keyvalue = "(?:" + key + ")=(?:" + value + ")"; return new RegExp("(?:^|,)(" + keyvalue + ")"); }; var parseAttributes = function(attributes) { const result = {}; if (!attributes) { return result; } const attrs = attributes.split(attributeSeparator()); let i = attrs.length; let attr; while (i--) { if (attrs[i] === "") { continue; } attr = /([^=]*)=(.*)/.exec(attrs[i]).slice(1); 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; }; var parseResolution = (resolution) => { const split = resolution.split("x"); const result = {}; if (split[0]) { result.width = parseInt(split[0], 10); } if (split[1]) { result.height = parseInt(split[1], 10); } return result; }; var ParseStream = class extends Stream { constructor() { super(); this.customParsers = []; this.tagMappers = []; } /** * Parses an additional line of input. * * @param {string} line a single line of an M3U8 file to parse */ push(line) { let match; let event; line = line.trim(); if (line.length === 0) { return; } if (line[0] !== "#") { this.trigger("data", { type: "uri", uri: line }); return; } const newLines = this.tagMappers.reduce((acc, mapper) => { const mappedLine = mapper(line); if (mappedLine === line) { return acc; } return acc.concat([mappedLine]); }, [line]); newLines.forEach((newLine) => { for (let i = 0; i < this.customParsers.length; i++) { if (this.customParsers[i].call(this, newLine)) { return; } } if (newLine.indexOf("#EXT") !== 0) { this.trigger("data", { type: "comment", text: newLine.slice(1) }); return; } newLine = newLine.replace("\r", ""); match = /^#EXTM3U/.exec(newLine); if (match) { this.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]; } this.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); } this.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); } this.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); } this.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); } this.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]; } this.trigger("data", event); return; } match = /^#EXT-X-BYTERANGE:(.*)?$/.exec(newLine); if (match) { event = _extends(parseByterange(match[1]), { type: "tag", tagType: "byterange" }); this.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]); } this.trigger("data", event); return; } match = /^#EXT-X-MAP:(.*)$/.exec(newLine); if (match) { event = { type: "tag", tagType: "map" }; if (match[1]) { const attributes = parseAttributes(match[1]); if (attributes.URI) { event.uri = attributes.URI; } if (attributes.BYTERANGE) { event.byterange = parseByterange(attributes.BYTERANGE); } } this.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) { event.attributes.RESOLUTION = parseResolution(event.attributes.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); } } this.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]); } this.trigger("data", event); return; } match = /^#EXT-X-ENDLIST/.exec(newLine); if (match) { this.trigger("data", { type: "tag", tagType: "endlist" }); return; } match = /^#EXT-X-DISCONTINUITY/.exec(newLine); if (match) { this.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]); } this.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]); 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); } } this.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); } this.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 = ""; } this.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 = ""; } this.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 = ""; } this.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); } this.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); } this.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]); } }); this.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]); } }); this.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); const subkey = key === "BYTERANGE-LENGTH" ? "length" : "offset"; event.attributes.byterange = event.attributes.byterange || {}; event.attributes.byterange[subkey] = event.attributes[key]; delete event.attributes[key]; } }); this.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); } }); this.trigger("data", event); return; } match = /^#EXT-X-DATERANGE:(.*)$/.exec(newLine); if (match && match[1]) { event = { type: "tag", tagType: "daterange" }; event.attributes = parseAttributes(match[1]); ["ID", "CLASS"].forEach(function(key) { if (event.attributes.hasOwnProperty(key)) { event.attributes[key] = String(event.attributes[key]); } }); ["START-DATE", "END-DATE"].forEach(function(key) { if (event.attributes.hasOwnProperty(key)) { event.attributes[key] = new Date(event.attributes[key]); } }); ["DURATION", "PLANNED-DURATION"].forEach(function(key) { if (event.attributes.hasOwnProperty(key)) { event.attributes[key] = parseFloat(event.attributes[key]); } }); ["END-ON-NEXT"].forEach(function(key) { if (event.attributes.hasOwnProperty(key)) { event.attributes[key] = /YES/i.test(event.attributes[key]); } }); ["SCTE35-CMD", " SCTE35-OUT", "SCTE35-IN"].forEach(function(key) { if (event.attributes.hasOwnProperty(key)) { event.attributes[key] = event.attributes[key].toString(16); } }); const clientAttributePattern = /^X-([A-Z]+-)+[A-Z]+$/; for (const key in event.attributes) { if (!clientAttributePattern.test(key)) { continue; } const isHexaDecimal = /[0-9A-Fa-f]{6}/g.test(event.attributes[key]); const isDecimalFloating = /^\d+(\.\d+)?$/.test(event.attributes[key]); event.attributes[key] = isHexaDecimal ? event.attributes[key].toString(16) : isDecimalFloating ? parseFloat(event.attributes[key]) : String(event.attributes[key]); } this.trigger("data", event); return; } match = /^#EXT-X-INDEPENDENT-SEGMENTS/.exec(newLine); if (match) { this.trigger("data", { type: "tag", tagType: "independent-segments" }); return; } match = /^#EXT-X-I-FRAMES-ONLY/.exec(newLine); if (match) { this.trigger("data", { type: "tag", tagType: "i-frames-only" }); return; } match = /^#EXT-X-CONTENT-STEERING:(.*)$/.exec(newLine); if (match) { event = { type: "tag", tagType: "content-steering" }; event.attributes = parseAttributes(match[1]); this.trigger("data", event); return; } match = /^#EXT-X-I-FRAME-STREAM-INF:(.*)$/.exec(newLine); if (match) { event = { type: "tag", tagType: "i-frame-playlist" }; event.attributes = parseAttributes(match[1]); if (event.attributes.URI) { event.uri = event.attributes.URI; } if (event.attributes.BANDWIDTH) { event.attributes.BANDWIDTH = parseInt(event.attributes.BANDWIDTH, 10); } if (event.attributes.RESOLUTION) { event.attributes.RESOLUTION = parseResolution(event.attributes.RESOLUTION); } if (event.attributes["AVERAGE-BANDWIDTH"]) { event.attributes["AVERAGE-BANDWIDTH"] = parseInt(event.attributes["AVERAGE-BANDWIDTH"], 10); } if (event.attributes["FRAME-RATE"]) { event.attributes["FRAME-RATE"] = parseFloat(event.attributes["FRAME-RATE"]); } this.trigger("data", event); return; } match = /^#EXT-X-DEFINE:(.*)$/.exec(newLine); if (match) { event = { type: "tag", tagType: "define" }; event.attributes = parseAttributes(match[1]); this.trigger("data", event); return; } this.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 */ addParser({ expression, customType, dataParser, segment }) { if (typeof dataParser !== "function") { dataParser = (line) => line; } this.customParsers.push((line) => { const match = expression.exec(line); if (match) { this.trigger("data", { type: "custom", data: dataParser(line), customType, 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 */ addTagMapper({ expression, map }) { const mapFn = (line) => { if (expression.test(line)) { return map(line); } return line; }; this.tagMappers.push(mapFn); } }; var camelCase = (str) => str.toLowerCase().replace(/-(\w)/g, (a) => a[1].toUpperCase()); var camelCaseKeys = function(attributes) { const result = {}; Object.keys(attributes).forEach(function(key) { result[camelCase(key)] = attributes[key]; }); return result; }; var setHoldBack = function(manifest) { const { serverControl, targetDuration, partTargetDuration } = manifest; if (!serverControl) { return; } const tag = "#EXT-X-SERVER-CONTROL"; const hb = "holdBack"; const phb = "partHoldBack"; const minTargetDuration = targetDuration && targetDuration * 3; const 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; } if (partTargetDuration && !serverControl.hasOwnProperty(phb)) { serverControl[phb] = partTargetDuration * 3; this.trigger("info", { message: `${tag} defaulting PART-HOLD-BACK to partTargetDuration * 3 (${serverControl[phb]}).` }); } if (partTargetDuration && serverControl[phb] < minPartDuration) { this.trigger("warn", { message: `${tag} clamping PART-HOLD-BACK (${serverControl[phb]}) to partTargetDuration * 2 (${minPartDuration}).` }); serverControl[phb] = minPartDuration; } }; var Parser = class extends Stream { constructor(opts = {}) { super(); this.lineStream = new LineStream(); this.parseStream = new ParseStream(); this.lineStream.pipe(this.parseStream); this.mainDefinitions = opts.mainDefinitions || {}; this.params = new URL(opts.uri, "https://a.com").searchParams; this.lastProgramDateTime = null; const self2 = this; const uris = []; let currentUri = {}; let currentMap; let key; let hasParts = false; const noop2 = function() { }; const defaultMediaGroups = { "AUDIO": {}, "VIDEO": {}, "CLOSED-CAPTIONS": {}, "SUBTITLES": {} }; const widevineUuid = "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"; let currentTimeline = 0; this.manifest = { allowCache: true, discontinuityStarts: [], dateRanges: [], iFramePlaylists: [], segments: [] }; let lastByterangeEnd = 0; let lastPartByterangeEnd = 0; const dateRangeTags = {}; this.on("end", () => { 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; }); this.parseStream.on("data", function(entry) { let mediaGroup; let rendition; if (self2.manifest.definitions) { for (const def in self2.manifest.definitions) { if (entry.uri) { entry.uri = entry.uri.replace(`{$${def}}`, self2.manifest.definitions[def]); } if (entry.attributes) { for (const attr in entry.attributes) { if (typeof entry.attributes[attr] === "string") { entry.attributes[attr] = entry.attributes[attr].replace(`{$${def}}`, self2.manifest.definitions[def]); } } } } } ({ tag() { ({ version() { if (entry.version) { this.manifest.version = entry.version; } }, "allow-cache"() { this.manifest.allowCache = entry.allowed; if (!("allowed" in entry)) { this.trigger("info", { message: "defaulting allowCache to YES" }); this.manifest.allowCache = true; } }, byterange() { const byterange = {}; if ("length" in entry) { currentUri.byterange = byterange; byterange.length = entry.length; if (!("offset" in entry)) { entry.offset = lastByterangeEnd; } } if ("offset" in entry) { currentUri.byterange = byterange; byterange.offset = entry.offset; } lastByterangeEnd = byterange.offset + byterange.length; }, endlist() { this.manifest.endList = true; }, 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.title) { currentUri.title = entry.title; } 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() { if (!entry.attributes) { this.trigger("warn", { message: "ignoring key declaration without attribute list" }); return; } 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 || {}; 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 || {}; this.manifest.contentProtection["com.microsoft.playready"] = { uri: entry.attributes.URI }; return; } if (entry.attributes.KEYFORMAT === widevineUuid) { const 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; } 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: decodeB64ToUint8Array(entry.attributes.URI.split(",")[1]) }; return; } if (!entry.attributes.METHOD) { this.trigger("warn", { message: "defaulting key method to AES-128" }); } key = { method: entry.attributes.METHOD || "AES-128", uri: entry.attributes.URI }; if (typeof entry.attributes.IV !== "undefined") { key.iv = entry.attributes.IV; } }, "media-sequence"() { if (!isFinite(entry.number)) { this.trigger("warn", { message: "ignoring invalid media sequence: " + entry.number }); return; } this.manifest.mediaSequence = entry.number; }, "discontinuity-sequence"() { 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"() { if (!/VOD|EVENT/.test(entry.playlistType)) { this.trigger("warn", { message: "ignoring unknown playlist type: " + entry.playlist }); return; } this.manifest.playlistType = entry.playlistType; }, map() { currentMap = {}; if (entry.uri) { currentMap.uri = entry.uri; } if (entry.byterange) { currentMap.byterange = entry.byterange; } if (key) { currentMap.key = key; } }, "stream-inf"() { 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 = {}; } _extends(currentUri.attributes, entry.attributes); }, 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; } const mediaGroupType = this.manifest.mediaGroups[entry.attributes.TYPE]; mediaGroupType[entry.attributes["GROUP-ID"]] = mediaGroupType[entry.attributes["GROUP-ID"]] || {}; mediaGroup = mediaGroupType[entry.attributes["GROUP-ID"]]; 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); } mediaGroup[entry.attributes.NAME] = rendition; }, discontinuity() { currentTimeline += 1; currentUri.discontinuity = true; this.manifest.discontinuityStarts.push(uris.length); }, "program-date-time"() { if (typeof this.manifest.dateTimeString === "undefined") { this.manifest.dateTimeString = entry.dateTimeString; this.manifest.dateTimeObject = entry.dateTimeObject; } currentUri.dateTimeString = entry.dateTimeString; currentUri.dateTimeObject = entry.dateTimeObject; const { lastProgramDateTime } = this; this.lastProgramDateTime = new Date(entry.dateTimeString).getTime(); if (lastProgramDateTime === null) { this.manifest.segments.reduceRight((programDateTime, segment) => { segment.programDateTime = programDateTime - segment.duration * 1e3; return segment.programDateTime; }, this.lastProgramDateTime); } }, 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() { 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"() { currentUri.cueOut = entry.data; }, "cue-out-cont"() { currentUri.cueOutCont = entry.data; }, "cue-in"() { currentUri.cueIn = entry.data; }, "skip"() { this.manifest.skip = camelCaseKeys(entry.attributes); this.warnOnMissingAttributes_("#EXT-X-SKIP", entry.attributes, ["SKIPPED-SEGMENTS"]); }, "part"() { hasParts = true; const segmentIndex = this.manifest.segments.length; const 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; } const 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((r, i) => { if (!r.hasOwnProperty("lastPart")) { this.trigger("warn", { message: `#EXT-X-RENDITION-REPORT #${i} lacks required attribute(s): LAST-PART` }); } }); } }, "server-control"() { const 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"() { const segmentIndex = this.manifest.segments.length; const hint = camelCaseKeys(entry.attributes); const isPart = hint.type && hint.type === "PART"; currentUri.preloadHints = currentUri.preloadHints || []; currentUri.preloadHints.push(hint); if (hint.byterange) { if (!hint.byterange.hasOwnProperty("offset")) { hint.byterange.offset = isPart ? lastPartByterangeEnd : 0; if (isPart) { lastPartByterangeEnd = hint.byterange.offset + hint.byterange.length; } } } const index = currentUri.preloadHints.length - 1; this.warnOnMissingAttributes_(`#EXT-X-PRELOAD-HINT #${index} for segment #${segmentIndex}`, entry.attributes, ["TYPE", "URI"]); if (!hint.type) { return; } for (let i = 0; i < currentUri.preloadHints.length - 1; i++) { const 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"() { const report = camelCaseKeys(entry.attributes); this.manifest.renditionReports = this.manifest.renditionReports || []; this.manifest.renditionReports.push(report); const index = this.manifest.renditionReports.length - 1; const required = ["LAST-MSN", "URI"]; if (hasParts) { required.push("LAST-PART"); } this.warnOnMissingAttributes_(`#EXT-X-RENDITION-REPORT #${index}`, entry.attributes, required); }, "part-inf"() { 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); }, "daterange"() { this.manifest.dateRanges.push(camelCaseKeys(entry.attributes)); const index = this.manifest.dateRanges.length - 1; this.warnOnMissingAttributes_(`#EXT-X-DATERANGE #${index}`, entry.attributes, ["ID", "START-DATE"]); const dateRange = this.manifest.dateRanges[index]; if (dateRange.endDate && dateRange.startDate && new Date(dateRange.endDate) < new Date(dateRange.startDate)) { this.trigger("warn", { message: "EXT-X-DATERANGE END-DATE must be equal to or later than the value of the START-DATE" }); } if (dateRange.duration && dateRange.duration < 0) { this.trigger("warn", { message: "EXT-X-DATERANGE DURATION must not be negative" }); } if (dateRange.plannedDuration && dateRange.plannedDuration < 0) { this.trigger("warn", { message: "EXT-X-DATERANGE PLANNED-DURATION must not be negative" }); } const endOnNextYes = !!dateRange.endOnNext; if (endOnNextYes && !dateRange.class) { this.trigger("warn", { message: "EXT-X-DATERANGE with an END-ON-NEXT=YES attribute must have a CLASS attribute" }); } if (endOnNextYes && (dateRange.duration || dateRange.endDate)) { this.trigger("warn", { message: "EXT-X-DATERANGE with an END-ON-NEXT=YES attribute must not contain DURATION or END-DATE attributes" }); } if (dateRange.duration && dateRange.endDate) { const startDate = dateRange.startDate; const newDateInSeconds = startDate.getTime() + dateRange.duration * 1e3; this.manifest.dateRanges[index].endDate = new Date(newDateInSeconds); } if (!dateRangeTags[dateRange.id]) { dateRangeTags[dateRange.id] = dateRange; } else { for (const attribute in dateRangeTags[dateRange.id]) { if (!!dateRange[attribute] && JSON.stringify(dateRangeTags[dateRange.id][attribute]) !== JSON.stringify(dateRange[attribute])) { this.trigger("warn", { message: "EXT-X-DATERANGE tags with the same ID in a playlist must have the same attributes values" }); break; } } const dateRangeWithSameId = this.manifest.dateRanges.findIndex((dateRangeToFind) => dateRangeToFind.id === dateRange.id); this.manifest.dateRanges[dateRangeWithSameId] = _extends(this.manifest.dateRanges[dateRangeWithSameId], dateRange); dateRangeTags[dateRange.id] = _extends(dateRangeTags[dateRange.id], dateRange); this.manifest.dateRanges.pop(); } }, "independent-segments"() { this.manifest.independentSegments = true; }, "i-frames-only"() { this.manifest.iFramesOnly = true; this.requiredCompatibilityversion(this.manifest.version, 4); }, "content-steering"() { this.manifest.contentSteering = camelCaseKeys(entry.attributes); this.warnOnMissingAttributes_("#EXT-X-CONTENT-STEERING", entry.attributes, ["SERVER-URI"]); }, /** @this {Parser} */ define() { this.manifest.definitions = this.manifest.definitions || {}; const addDef = (n, v) => { if (n in this.manifest.definitions) { this.trigger("error", { message: `EXT-X-DEFINE: Duplicate name ${n}` }); return; } this.manifest.definitions[n] = v; }; if ("QUERYPARAM" in entry.attributes) { if ("NAME" in entry.attributes || "IMPORT" in entry.attributes) { this.trigger("error", { message: "EXT-X-DEFINE: Invalid attributes" }); return; } const val = this.params.get(entry.attributes.QUERYPARAM); if (!val) { this.trigger("error", { message: `EXT-X-DEFINE: No query param ${entry.attributes.QUERYPARAM}` }); return; } addDef(entry.attributes.QUERYPARAM, decodeURIComponent(val)); return; } if ("NAME" in entry.attributes) { if ("IMPORT" in entry.attributes) { this.trigger("error", { message: "EXT-X-DEFINE: Invalid attributes" }); return; } if (!("VALUE" in entry.attributes) || typeof entry.attributes.VALUE !== "string") { this.trigger("error", { message: `EXT-X-DEFINE: No value for ${entry.attributes.NAME}` }); return; } addDef(entry.attributes.NAME, entry.attributes.VALUE); return; } if ("IMPORT" in entry.attributes) { if (!this.mainDefinitions[entry.attributes.IMPORT]) { this.trigger("error", { message: `EXT-X-DEFINE: No value ${entry.attributes.IMPORT} to import, or IMPORT used on main playlist` }); return; } addDef(entry.attributes.IMPORT, this.mainDefinitions[entry.attributes.IMPORT]); return; } this.trigger("error", { message: "EXT-X-DEFINE: No attribute" }); }, "i-frame-playlist"() { this.manifest.iFramePlaylists.push({ attributes: entry.attributes, uri: entry.uri, timeline: currentTimeline }); this.warnOnMissingAttributes_("#EXT-X-I-FRAME-STREAM-INF", entry.attributes, ["BANDWIDTH", "URI"]); } }[entry.tagType] || noop2).call(self2); }, uri() { currentUri.uri = entry.uri; uris.push(currentUri); if (this.manifest.targetDuration && !("duration" in currentUri)) { this.trigger("warn", { message: "defaulting segment duration to the target duration" }); currentUri.duration = this.manifest.targetDuration; } if (key) { currentUri.key = key; } currentUri.timeline = currentTimeline; if (currentMap) { currentUri.map = currentMap; } lastPartByterangeEnd = 0; if (this.lastProgramDateTime !== null) { currentUri.programDateTime = this.lastProgramDateTime; this.lastProgramDateTime += currentUri.duration * 1e3; } currentUri = {}; }, comment() { }, custom() { if (entry.segment) { currentUri.custom = currentUri.custom || {}; currentUri.custom[entry.customType] = entry.data; } else { this.manifest.custom = this.manifest.custom || {}; this.manifest.custom[entry.customType] = entry.data; } } })[entry.type].call(self2); }); } requiredCompatibilityversion(currentVersion, targetVersion) { if (currentVersion < targetVersion || !currentVersion) { this.trigger("warn", { message: `manifest must be at least version ${targetVersion}` }); } } warnOnMissingAttributes_(identifier, attributes, required) { const 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 */ 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. */ end() { this.lineStream.push("\n"); if (this.manifest.dateRanges.length && this.lastProgramDateTime === null) { this.trigger("warn", { message: "A playlist with EXT-X-DATERANGE tag must contain atleast one EXT-X-PROGRAM-DATE-TIME tag" }); } this.lastProgramDateTime = null; 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.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 */ 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 */ addTagMapper(options) { this.parseStream.addTagMapper(options); } }; // node_modules/@videojs/vhs-utils/es/codecs.js var import_window3 = __toESM(require_window()); var regexs = { // to determine mime types mp4: /^(av0?1|avc0?[1234]|vp0?9|flac|opus|mp3|mp4a|mp4v|stpp.ttml.im1t)/, webm: /^(vp0?[89]|av0?1|opus|vorbis)/, ogg: /^(vp0?[89]|theora|flac|opus|vorbis)/, // to determine if a codec is audio or video video: /^(av0?1|avc0?[1234]|vp0?[89]|hvc1|hev1|theora|mp4v)/, audio: /^(mp4a|flac|vorbis|opus|ac-[34]|ec-3|alac|mp3|speex|aac)/, text: /^(stpp.ttml.im1t)/, // mux.js support regex muxerVideo: /^(avc0?1)/, muxerAudio: /^(mp4a)/, // match nothing as muxer does not support text right now. // there cannot never be a character before the start of a string // so this matches nothing. muxerText: /a^/ }; var mediaTypes = ["video", "audio", "text"]; var upperMediaTypes = ["Video", "Audio", "Text"]; var translateLegacyCodec = function translateLegacyCodec2(codec) { if (!codec) { return codec; } return codec.replace(/avc1\.(\d+)\.(\d+)/i, function(orig, profile, avcLevel) { var profileHex = ("00" + Number(profile).toString(16)).slice(-2); var avcLevelHex = ("00" + Number(avcLevel).toString(16)).slice(-2); return "avc1." + profileHex + "00" + avcLevelHex; }); }; var parseCodecs = function parseCodecs2(codecString) { if (codecString === void 0) { codecString = ""; } var codecs = codecString.split(","); var result = []; codecs.forEach(function(codec) { codec = codec.trim(); var codecType; mediaTypes.forEach(function(name) { var match = regexs[name].exec(codec.toLowerCase()); if (!match || match.length <= 1) { return; } codecType = name; var type = codec.substring(0, match[1].length); var details = codec.replace(type, ""); result.push({ type, details, mediaType: name }); }); if (!codecType) { result.push({ type: codec, details: "", mediaType: "unknown" }); } }); return result; }; var codecsFromDefault = function codecsFromDefault2(master, audioGroupId) { if (!master.mediaGroups.AUDIO || !audioGroupId) { return null; } var audioGroup = master.mediaGroups.AUDIO[audioGroupId]; if (!audioGroup) { return null; } for (var name in audioGroup) { var audioType = audioGroup[name]; if (audioType.default && audioType.playlists) { return parseCodecs(audioType.playlists[0].attributes.CODECS); } } return null; }; var isAudioCodec = function isAudioCodec2(codec) { if (codec === void 0) { codec = ""; } return regexs.audio.test(codec.trim().toLowerCase()); }; var isTextCodec = function isTextCodec2(codec) { if (codec === void 0) { codec = ""; } return regexs.text.test(codec.trim().toLowerCase()); }; var getMimeForCodec = function getMimeForCodec2(codecString) { if (!codecString || typeof codecString !== "string") { return; } var codecs = codecString.toLowerCase().split(",").map(function(c) { return translateLegacyCodec(c.trim()); }); var type = "video"; if (codecs.length === 1 && isAudioCodec(codecs[0])) { type = "audio"; } else if (codecs.length === 1 && isTextCodec(codecs[0])) { type = "application"; } var container = "mp4"; if (codecs.every(function(c) { return regexs.mp4.test(c); })) { container = "mp4"; } else if (codecs.every(function(c) { return regexs.webm.test(c); })) { container = "webm"; } else if (codecs.every(function(c) { return regexs.ogg.test(c); })) { container = "ogg"; } return type + "/" + container + ';codecs="' + codecString + '"'; }; var browserSupportsCodec = function browserSupportsCodec2(codecString, withMMS) { if (codecString === void 0) { codecString = ""; } if (withMMS === void 0) { withMMS = false; } return import_window3.default.MediaSource && import_window3.default.MediaSource.isTypeSupported && import_window3.default.MediaSource.isTypeSupported(getMimeForCodec(codecString)) || withMMS && import_window3.default.ManagedMediaSource && import_window3.default.ManagedMediaSource.isTypeSupported && import_window3.default.ManagedMediaSource.isTypeSupported(getMimeForCodec(codecString)) || false; }; var muxerSupportsCodec = function muxerSupportsCodec2(codecString) { if (codecString === void 0) { codecString = ""; } return codecString.toLowerCase().split(",").every(function(codec) { codec = codec.trim(); for (var i = 0; i < upperMediaTypes.length; i++) { var type = upperMediaTypes[i]; if (regexs["muxer" + type].test(codec)) { return true; } } return false; }); }; var DEFAULT_AUDIO_CODEC = "mp4a.40.2"; var DEFAULT_VIDEO_CODEC = "avc1.4d400d"; // node_modules/@videojs/vhs-utils/es/media-types.js var MPEGURL_REGEX = /^(audio|video|application)\/(x-|vnd\.apple\.)?mpegurl/i; var DASH_REGEX = /^application\/dash\+xml/i; var simpleTypeFromSourceType = function simpleTypeFromSourceType2(type) { if (MPEGURL_REGEX.test(type)) { return "hls"; } if (DASH_REGEX.test(type)) { return "dash"; } if (type === "application/vnd.videojs.vhs+json") { return "vhs-json"; } return null; }; // node_modules/@videojs/vhs-utils/es/byte-helpers.js var import_window4 = __toESM(require_window()); var countBits = function countBits2(x) { return x.toString(2).length; }; var countBytes = function countBytes2(x) { return Math.ceil(countBits(x) / 8); }; var isArrayBufferView = function isArrayBufferView2(obj) { if (ArrayBuffer.isView === "function") { return ArrayBuffer.isView(obj); } return obj && obj.buffer instanceof ArrayBuffer; }; var isTypedArray = function isTypedArray2(obj) { return isArrayBufferView(obj); }; var toUint8 = function toUint82(bytes) { if (bytes instanceof Uint8Array) { return bytes; } if (!Array.isArray(bytes) && !isTypedArray(bytes) && !(bytes instanceof ArrayBuffer)) { if (typeof bytes !== "number" || typeof bytes === "number" && bytes !== bytes) { bytes = 0; } else { bytes = [bytes]; } } return new Uint8Array(bytes && bytes.buffer || bytes, bytes && bytes.byteOffset || 0, bytes && bytes.byteLength || 0); }; var BigInt = import_window4.default.BigInt || Number; var BYTE_TABLE = [BigInt("0x1"), BigInt("0x100"), BigInt("0x10000"), BigInt("0x1000000"), BigInt("0x100000000"), BigInt("0x10000000000"), BigInt("0x1000000000000"), BigInt("0x100000000000000"), BigInt("0x10000000000000000")]; var ENDIANNESS = function() { var a = new Uint16Array([65484]); var b = new Uint8Array(a.buffer, a.byteOffset, a.byteLength); if (b[0] === 255) { return "big"; } if (b[0] === 204) { return "little"; } return "unknown"; }(); var bytesToNumber = function bytesToNumber2(bytes, _temp) { var _ref = _temp === void 0 ? {} : _temp, _ref$signed = _ref.signed, signed = _ref$signed === void 0 ? false : _ref$signed, _ref$le = _ref.le, le = _ref$le === void 0 ? false : _ref$le; bytes = toUint8(bytes); var fn = le ? "reduce" : "reduceRight"; var obj = bytes[fn] ? bytes[fn] : Array.prototype[fn]; var number = obj.call(bytes, function(total, byte, i) { var exponent = le ? i : Math.abs(i + 1 - bytes.length); return total + BigInt(byte) * BYTE_TABLE[exponent]; }, BigInt(0)); if (signed) { var max = BYTE_TABLE[bytes.length] / BigInt(2) - BigInt(1); number = BigInt(number); if (number > max) { number -= max; number -= max; number -= BigInt(2); } } return Number(number); }; var numberToBytes = function numberToBytes2(number, _temp2) { var _ref2 = _temp2 === void 0 ? {} : _temp2, _ref2$le = _ref2.le, le = _ref2$le === void 0 ? false : _ref2$le; if (typeof number !== "bigint" && typeof number !== "number" || typeof number === "number" && number !== number) { number = 0; } number = BigInt(number); var byteCount = countBytes(number); var bytes = new Uint8Array(new ArrayBuffer(byteCount)); for (var i = 0; i < byteCount; i++) { var byteIndex = le ? i : Math.abs(i + 1 - bytes.length); bytes[byteIndex] = Number(number / BYTE_TABLE[i] & BigInt(255)); if (number < 0) { bytes[byteIndex] = Math.abs(~bytes[byteIndex]); bytes[byteIndex] -= i === 0 ? 1 : 2; } } return bytes; }; var bytesToString = function bytesToString2(bytes) { if (!bytes) { return ""; } bytes = Array.prototype.slice.call(bytes); var string = String.fromCharCode.apply(null, toUint8(bytes)); try { return decodeURIComponent(escape(string)); } catch (e) { } return string; }; var stringToBytes = function stringToBytes2(string, stringIsBytes) { if (typeof string !== "string" && string && typeof string.toString === "function") { string = string.toString(); } if (typeof string !== "string") { return new Uint8Array(); } if (!stringIsBytes) { string = unescape(encodeURIComponent(string)); } var view = new Uint8Array(string.length); for (var i = 0; i < string.length; i++) { view[i] = string.charCodeAt(i); } return view; }; var concatTypedArrays = function concatTypedArrays2() { for (var _len = arguments.length, buffers = new Array(_len), _key = 0; _key < _len; _key++) { buffers[_key] = arguments[_key]; } buffers = buffers.filter(function(b) { return b && (b.byteLength || b.length) && typeof b !== "string"; }); if (buffers.length <= 1) { return toUint8(buffers[0]); } var totalLen = buffers.reduce(function(total, buf, i) { return total + (buf.byteLength || buf.length); }, 0); var tempBuffer = new Uint8Array(totalLen); var offset = 0; buffers.forEach(function(buf) { buf = toUint8(buf); tempBuffer.set(buf, offset); offset += buf.byteLength; }); return tempBuffer; }; var bytesMatch = function bytesMatch2(a, b, _temp3) { var _ref3 = _temp3 === void 0 ? {} : _temp3, _ref3$offset = _ref3.offset, offset = _ref3$offset === void 0 ? 0 : _ref3$offset, _ref3$mask = _ref3.mask, mask = _ref3$mask === void 0 ? [] : _ref3$mask; a = toUint8(a); b = toUint8(b); var fn = b.every ? b.every : Array.prototype.every; return b.length && a.length - offset >= b.length && // ie 11 doesn't support every on uin8 fn.call(b, function(bByte, i) { var aByte = mask[i] ? mask[i] & a[offset + i] : a[offset + i]; return bByte === aByte; }); }; // node_modules/mpd-parser/dist/mpd-parser.es.js var import_window5 = __toESM(require_window()); // node_modules/@videojs/vhs-utils/es/media-groups.js var forEachMediaGroup = function forEachMediaGroup2(master, groups, callback) { groups.forEach(function(mediaType) { for (var groupKey in master.mediaGroups[mediaType]) { for (var labelKey in master.mediaGroups[mediaType][groupKey]) { var mediaProperties = master.mediaGroups[mediaType][groupKey][labelKey]; callback(mediaProperties, mediaType, groupKey, labelKey); } } }); }; // node_modules/mpd-parser/dist/mpd-parser.es.js var import_xmldom = __toESM(require_lib2()); var isObject = (obj) => { return !!obj && typeof obj === "object"; }; var merge = (...objects) => { return objects.reduce((result, source) => { if (typeof source !== "object") { return result; } Object.keys(source).forEach((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 = (o) => Object.keys(o).map((k) => o[k]); var range = (start, end) => { const result = []; for (let i = start; i < end; i++) { result.push(i); } return result; }; var flatten = (lists) => lists.reduce((x, y) => x.concat(y), []); var from = (list) => { if (!list.length) { return []; } const result = []; for (let i = 0; i < list.length; i++) { result.push(list[i]); } return result; }; var findIndexes = (l, key) => l.reduce((a, e, i) => { if (e[key]) { a.push(i); } return a; }, []); var union = (lists, keyFunction) => { return values(lists.reduce((acc, list) => { list.forEach((el) => { acc[keyFunction(el)] = el; }); return acc; }, {})); }; var errors = { INVALID_NUMBER_OF_PERIOD: "INVALID_NUMBER_OF_PERIOD", INVALID_NUMBER_OF_CONTENT_STEERING: "INVALID_NUMBER_OF_CONTENT_STEERING", 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" }; var urlTypeToSegment = ({ baseUrl = "", source = "", range: range2 = "", indexRange = "" }) => { const segment = { uri: source, resolvedUri: resolve_url_default(baseUrl || "", source) }; if (range2 || indexRange) { const rangeStr = range2 ? range2 : indexRange; const ranges = rangeStr.split("-"); let startRange = import_window5.default.BigInt ? import_window5.default.BigInt(ranges[0]) : parseInt(ranges[0], 10); let endRange = import_window5.default.BigInt ? import_window5.default.BigInt(ranges[1]) : parseInt(ranges[1], 10); if (startRange < Number.MAX_SAFE_INTEGER && typeof startRange === "bigint") { startRange = Number(startRange); } if (endRange < Number.MAX_SAFE_INTEGER && typeof endRange === "bigint") { endRange = Number(endRange); } let length; if (typeof endRange === "bigint" || typeof startRange === "bigint") { length = import_window5.default.BigInt(endRange) - import_window5.default.BigInt(startRange) + import_window5.default.BigInt(1); } else { length = endRange - startRange + 1; } if (typeof length === "bigint" && length < Number.MAX_SAFE_INTEGER) { length = Number(length); } segment.byterange = { length, offset: startRange }; } return segment; }; var byteRangeToString = (byterange) => { let endRange; if (typeof byterange.offset === "bigint" || typeof byterange.length === "bigint") { endRange = import_window5.default.BigInt(byterange.offset) + import_window5.default.BigInt(byterange.length) - import_window5.default.BigInt(1); } else { endRange = byterange.offset + byterange.length - 1; } return `${byterange.offset}-${endRange}`; }; var parseEndNumber = (endNumber) => { if (endNumber && typeof endNumber !== "number") { endNumber = parseInt(endNumber, 10); } if (isNaN(endNumber)) { return null; } return endNumber; }; 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(attributes) { const { duration: duration2, timescale = 1, sourceDuration, periodDuration } = attributes; const endNumber = parseEndNumber(attributes.endNumber); const segmentDuration = duration2 / 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(attributes) { const { NOW, clientOffset, availabilityStartTime, timescale = 1, duration: duration2, periodStart = 0, minimumUpdatePeriod = 0, timeShiftBufferDepth = Infinity } = attributes; const endNumber = parseEndNumber(attributes.endNumber); const now = (NOW + clientOffset) / 1e3; const periodStartWC = availabilityStartTime + periodStart; const periodEndWC = now + minimumUpdatePeriod; const periodDuration = periodEndWC - periodStartWC; const segmentCount = Math.ceil(periodDuration * timescale / duration2); const availableStart = Math.floor((now - periodStartWC - timeShiftBufferDepth) * timescale / duration2); const availableEnd = Math.floor((now - periodStartWC) * timescale / duration2); return { start: Math.max(0, availableStart), end: typeof endNumber === "number" ? endNumber : Math.min(segmentCount, availableEnd) }; } }; var toSegments = (attributes) => (number) => { const { duration: duration2, timescale = 1, periodStart, startNumber = 1 } = attributes; return { number: startNumber + number, duration: duration2 / timescale, timeline: periodStart, time: number * duration2 }; }; var parseByDuration = (attributes) => { const { type, duration: duration2, timescale = 1, periodDuration, sourceDuration } = attributes; const { start, end } = segmentRange[type](attributes); const segments = range(start, end).map(toSegments(attributes)); if (type === "static") { const index = segments.length - 1; const sectionDuration = typeof periodDuration === "number" ? periodDuration : sourceDuration; segments[index].duration = sectionDuration - duration2 / timescale * index; } return segments; }; var segmentsFromBase = (attributes) => { const { baseUrl, initialization = {}, sourceDuration, indexRange = "", periodStart, presentationTime, number = 0, duration: duration2 } = attributes; if (!baseUrl) { throw new Error(errors.NO_BASE_URL); } const initSegment = urlTypeToSegment({ baseUrl, source: initialization.sourceURL, range: initialization.range }); const segment = urlTypeToSegment({ baseUrl, source: baseUrl, indexRange }); segment.map = initSegment; if (duration2) { const 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; } segment.presentationTime = presentationTime || periodStart; segment.number = number; return [segment]; }; var addSidxSegmentsToPlaylist$1 = (playlist, sidx, baseUrl) => { const initSegment = playlist.sidx.map ? playlist.sidx.map : null; const sourceDuration = playlist.sidx.duration; const timeline = playlist.timeline || 0; const sidxByteRange = playlist.sidx.byterange; const sidxEnd = sidxByteRange.offset + sidxByteRange.length; const timescale = sidx.timescale; const mediaReferences = sidx.references.filter((r) => r.referenceType !== 1); const segments = []; const type = playlist.endList ? "static" : "dynamic"; const periodStart = playlist.sidx.timeline; let presentationTime = periodStart; let number = playlist.mediaSequence || 0; let startIndex; if (typeof sidx.firstOffset === "bigint") { startIndex = import_window5.default.BigInt(sidxEnd) + sidx.firstOffset; } else { startIndex = sidxEnd + sidx.firstOffset; } for (let i = 0; i < mediaReferences.length; i++) { const reference = sidx.references[i]; const size = reference.referencedSize; const duration2 = reference.subsegmentDuration; let endIndex; if (typeof startIndex === "bigint") { endIndex = startIndex + import_window5.default.BigInt(size) - import_window5.default.BigInt(1); } else { endIndex = startIndex + size - 1; } const indexRange = `${startIndex}-${endIndex}`; const attributes = { baseUrl, timescale, timeline, periodStart, presentationTime, number, duration: duration2, sourceDuration, indexRange, type }; const segment = segmentsFromBase(attributes)[0]; if (initSegment) { segment.map = initSegment; } segments.push(segment); if (typeof startIndex === "bigint") { startIndex += import_window5.default.BigInt(size); } else { startIndex += size; } presentationTime += duration2 / timescale; number++; } playlist.segments = segments; return playlist; }; var SUPPORTED_MEDIA_TYPES = ["AUDIO", "SUBTITLES"]; var TIME_FUDGE = 1 / 60; var getUniqueTimelineStarts = (timelineStarts) => { return union(timelineStarts, ({ timeline }) => timeline).sort((a, b) => a.timeline > b.timeline ? 1 : -1); }; var findPlaylistWithName = (playlists, name) => { for (let i = 0; i < playlists.length; i++) { if (playlists[i].attributes.NAME === name) { return playlists[i]; } } return null; }; var getMediaGroupPlaylists = (manifest) => { let mediaGroupPlaylists = []; forEachMediaGroup(manifest, SUPPORTED_MEDIA_TYPES, (properties, type, group, label) => { mediaGroupPlaylists = mediaGroupPlaylists.concat(properties.playlists || []); }); return mediaGroupPlaylists; }; var updateMediaSequenceForPlaylist = ({ playlist, mediaSequence }) => { playlist.mediaSequence = mediaSequence; playlist.segments.forEach((segment, index) => { segment.number = playlist.mediaSequence + index; }); }; var updateSequenceNumbers = ({ oldPlaylists, newPlaylists, timelineStarts }) => { newPlaylists.forEach((playlist) => { playlist.discontinuitySequence = timelineStarts.findIndex(function({ timeline }) { return timeline === playlist.timeline; }); const oldPlaylist = findPlaylistWithName(oldPlaylists, playlist.attributes.NAME); if (!oldPlaylist) { return; } if (playlist.sidx) { return; } const firstNewSegment = playlist.segments[0]; const oldMatchingSegmentIndex = oldPlaylist.segments.findIndex(function(oldSegment) { return Math.abs(oldSegment.presentationTime - firstNewSegment.presentationTime) < TIME_FUDGE; }); if (oldMatchingSegmentIndex === -1) { updateMediaSequenceForPlaylist({ playlist, mediaSequence: oldPlaylist.mediaSequence + oldPlaylist.segments.length }); playlist.segments[0].discontinuity = true; playlist.discontinuityStarts.unshift(0); if (!oldPlaylist.segments.length && playlist.timeline > oldPlaylist.timeline || oldPlaylist.segments.length && playlist.timeline > oldPlaylist.segments[oldPlaylist.segments.length - 1].timeline) { playlist.discontinuitySequence--; } return; } const oldMatchingSegment = oldPlaylist.segments[oldMatchingSegmentIndex]; if (oldMatchingSegment.discontinuity && !firstNewSegment.discontinuity) { firstNewSegment.discontinuity = true; playlist.discontinuityStarts.unshift(0); playlist.discontinuitySequence--; } updateMediaSequenceForPlaylist({ playlist, mediaSequence: oldPlaylist.segments[oldMatchingSegmentIndex].number }); }); }; var positionManifestOnTimeline = ({ oldManifest, newManifest }) => { const oldPlaylists = oldManifest.playlists.concat(getMediaGroupPlaylists(oldManifest)); const newPlaylists = newManifest.playlists.concat(getMediaGroupPlaylists(newManifest)); newManifest.timelineStarts = getUniqueTimelineStarts([oldManifest.timelineStarts, newManifest.timelineStarts]); updateSequenceNumbers({ oldPlaylists, newPlaylists, timelineStarts: newManifest.timelineStarts }); return newManifest; }; var generateSidxKey = (sidx) => sidx && sidx.uri + "-" + byteRangeToString(sidx.byterange); var mergeDiscontiguousPlaylists = (playlists) => { const playlistsByBaseUrl = playlists.reduce(function(acc, cur) { if (!acc[cur.attributes.baseUrl]) { acc[cur.attributes.baseUrl] = []; } acc[cur.attributes.baseUrl].push(cur); return acc; }, {}); let allPlaylists = []; Object.values(playlistsByBaseUrl).forEach((playlistGroup) => { const mergedPlaylists = values(playlistGroup.reduce((acc, playlist) => { const name = playlist.attributes.id + (playlist.attributes.lang || ""); if (!acc[name]) { acc[name] = playlist; acc[name].attributes.timelineStarts = []; } else { if (playlist.segments) { if (playlist.segments[0]) { playlist.segments[0].discontinuity = true; } acc[name].segments.push(...playlist.segments); } 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; }, {})); allPlaylists = allPlaylists.concat(mergedPlaylists); }); return allPlaylists.map((playlist) => { playlist.discontinuityStarts = findIndexes(playlist.segments || [], "discontinuity"); return playlist; }); }; var addSidxSegmentsToPlaylist = (playlist, sidxMapping) => { const sidxKey = generateSidxKey(playlist.sidx); const sidxMatch = sidxKey && sidxMapping[sidxKey] && sidxMapping[sidxKey].sidx; if (sidxMatch) { addSidxSegmentsToPlaylist$1(playlist, sidxMatch, playlist.sidx.resolvedUri); } return playlist; }; var addSidxSegmentsToPlaylists = (playlists, sidxMapping = {}) => { if (!Object.keys(sidxMapping).length) { return playlists; } for (const i in playlists) { playlists[i] = addSidxSegmentsToPlaylist(playlists[i], sidxMapping); } return playlists; }; var formatAudioPlaylist = ({ attributes, segments, sidx, mediaSequence, discontinuitySequence, discontinuityStarts }, isAudioOnly2) => { const playlist = { attributes: { NAME: attributes.id, BANDWIDTH: attributes.bandwidth, CODECS: attributes.codecs, ["PROGRAM-ID"]: 1 }, uri: "", endList: attributes.type === "static", timeline: attributes.periodStart, resolvedUri: attributes.baseUrl || "", targetDuration: attributes.duration, discontinuitySequence, discontinuityStarts, timelineStarts: attributes.timelineStarts, mediaSequence, segments }; if (attributes.contentProtection) { playlist.contentProtection = attributes.contentProtection; } if (attributes.serviceLocation) { playlist.attributes.serviceLocation = attributes.serviceLocation; } if (sidx) { playlist.sidx = sidx; } if (isAudioOnly2) { playlist.attributes.AUDIO = "audio"; playlist.attributes.SUBTITLES = "subs"; } return playlist; }; var formatVttPlaylist = ({ attributes, segments, mediaSequence, discontinuityStarts, discontinuitySequence }) => { if (typeof segments === "undefined") { segments = [{ uri: attributes.baseUrl, timeline: attributes.periodStart, resolvedUri: attributes.baseUrl || "", duration: attributes.sourceDuration, number: 0 }]; attributes.duration = attributes.sourceDuration; } const m3u8Attributes = { NAME: attributes.id, BANDWIDTH: attributes.bandwidth, ["PROGRAM-ID"]: 1 }; if (attributes.codecs) { m3u8Attributes.CODECS = attributes.codecs; } const vttPlaylist = { attributes: m3u8Attributes, uri: "", endList: attributes.type === "static", timeline: attributes.periodStart, resolvedUri: attributes.baseUrl || "", targetDuration: attributes.duration, timelineStarts: attributes.timelineStarts, discontinuityStarts, discontinuitySequence, mediaSequence, segments }; if (attributes.serviceLocation) { vttPlaylist.attributes.serviceLocation = attributes.serviceLocation; } return vttPlaylist; }; var organizeAudioPlaylists = (playlists, sidxMapping = {}, isAudioOnly2 = false) => { let mainPlaylist; const formattedPlaylists = playlists.reduce((a, playlist) => { const role = playlist.attributes.role && playlist.attributes.role.value || ""; const language = playlist.attributes.lang || ""; let label = playlist.attributes.label || "main"; if (language && !playlist.attributes.label) { const roleLabel = role ? ` (${role})` : ""; label = `${playlist.attributes.lang}${roleLabel}`; } if (!a[label]) { a[label] = { language, autoselect: true, default: role === "main", playlists: [], uri: "" }; } const formatted = addSidxSegmentsToPlaylist(formatAudioPlaylist(playlist, isAudioOnly2), sidxMapping); a[label].playlists.push(formatted); if (typeof mainPlaylist === "undefined" && role === "main") { mainPlaylist = playlist; mainPlaylist.default = true; } return a; }, {}); if (!mainPlaylist) { const firstLabel = Object.keys(formattedPlaylists)[0]; formattedPlaylists[firstLabel].default = true; } return formattedPlaylists; }; var organizeVttPlaylists = (playlists, sidxMapping = {}) => { return playlists.reduce((a, playlist) => { const label = playlist.attributes.label || playlist.attributes.lang || "text"; const language = playlist.attributes.lang || "und"; if (!a[label]) { a[label] = { language, default: false, autoselect: false, playlists: [], uri: "" }; } a[label].playlists.push(addSidxSegmentsToPlaylist(formatVttPlaylist(playlist), sidxMapping)); return a; }, {}); }; var organizeCaptionServices = (captionServices) => captionServices.reduce((svcObj, svc) => { if (!svc) { return svcObj; } svc.forEach((service) => { const { channel, language } = service; svcObj[language] = { autoselect: false, default: false, instreamId: channel, 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 = ({ attributes, segments, sidx, discontinuityStarts }) => { const playlist = { attributes: { NAME: attributes.id, AUDIO: "audio", SUBTITLES: "subs", RESOLUTION: { width: attributes.width, height: attributes.height }, CODECS: attributes.codecs, BANDWIDTH: attributes.bandwidth, ["PROGRAM-ID"]: 1 }, uri: "", endList: attributes.type === "static", timeline: attributes.periodStart, resolvedUri: attributes.baseUrl || "", targetDuration: attributes.duration, discontinuityStarts, timelineStarts: attributes.timelineStarts, segments }; if (attributes.frameRate) { playlist.attributes["FRAME-RATE"] = attributes.frameRate; } if (attributes.contentProtection) { playlist.contentProtection = attributes.contentProtection; } if (attributes.serviceLocation) { playlist.attributes.serviceLocation = attributes.serviceLocation; } if (sidx) { playlist.sidx = sidx; } return playlist; }; var videoOnly = ({ attributes }) => attributes.mimeType === "video/mp4" || attributes.mimeType === "video/webm" || attributes.contentType === "video"; var audioOnly = ({ attributes }) => attributes.mimeType === "audio/mp4" || attributes.mimeType === "audio/webm" || attributes.contentType === "audio"; var vttOnly = ({ attributes }) => attributes.mimeType === "text/vtt" || attributes.contentType === "text"; var addMediaSequenceValues = (playlists, timelineStarts) => { playlists.forEach((playlist) => { playlist.mediaSequence = 0; playlist.discontinuitySequence = timelineStarts.findIndex(function({ timeline }) { return timeline === playlist.timeline; }); if (!playlist.segments) { return; } playlist.segments.forEach((segment, index) => { segment.number = index; }); }); }; var flattenMediaGroupPlaylists = (mediaGroupObject) => { if (!mediaGroupObject) { return []; } return Object.keys(mediaGroupObject).reduce((acc, label) => { const labelContents = mediaGroupObject[label]; return acc.concat(labelContents.playlists); }, []); }; var toM3u8 = ({ dashPlaylists, locations, contentSteering, sidxMapping = {}, previousManifest, eventStream }) => { if (!dashPlaylists.length) { return {}; } const { sourceDuration: duration2, type, suggestedPresentationDelay, minimumUpdatePeriod } = dashPlaylists[0].attributes; const videoPlaylists = mergeDiscontiguousPlaylists(dashPlaylists.filter(videoOnly)).map(formatVideoPlaylist); const audioPlaylists = mergeDiscontiguousPlaylists(dashPlaylists.filter(audioOnly)); const vttPlaylists = mergeDiscontiguousPlaylists(dashPlaylists.filter(vttOnly)); const captions = dashPlaylists.map((playlist) => playlist.attributes.captionServices).filter(Boolean); const manifest = { allowCache: true, discontinuityStarts: [], segments: [], endList: true, mediaGroups: { AUDIO: {}, VIDEO: {}, ["CLOSED-CAPTIONS"]: {}, SUBTITLES: {} }, uri: "", duration: duration2, playlists: addSidxSegmentsToPlaylists(videoPlaylists, sidxMapping) }; if (minimumUpdatePeriod >= 0) { manifest.minimumUpdatePeriod = minimumUpdatePeriod * 1e3; } if (locations) { manifest.locations = locations; } if (contentSteering) { manifest.contentSteering = contentSteering; } if (type === "dynamic") { manifest.suggestedPresentationDelay = suggestedPresentationDelay; } if (eventStream && eventStream.length > 0) { manifest.eventStream = eventStream; } const isAudioOnly2 = manifest.playlists.length === 0; const organizedAudioGroup = audioPlaylists.length ? organizeAudioPlaylists(audioPlaylists, sidxMapping, isAudioOnly2) : null; const organizedVttGroup = vttPlaylists.length ? organizeVttPlaylists(vttPlaylists, sidxMapping) : null; const formattedPlaylists = videoPlaylists.concat(flattenMediaGroupPlaylists(organizedAudioGroup), flattenMediaGroupPlaylists(organizedVttGroup)); const playlistTimelineStarts = formattedPlaylists.map(({ timelineStarts }) => 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; }; var getLiveRValue = (attributes, time, duration2) => { const { NOW, clientOffset, availabilityStartTime, timescale = 1, periodStart = 0, minimumUpdatePeriod = 0 } = attributes; const now = (NOW + clientOffset) / 1e3; const periodStartWC = availabilityStartTime + periodStart; const periodEndWC = now + minimumUpdatePeriod; const periodDuration = periodEndWC - periodStartWC; return Math.ceil((periodDuration * timescale - time) / duration2); }; var parseByTimeline = (attributes, segmentTimeline) => { const { type, minimumUpdatePeriod = 0, media = "", sourceDuration, timescale = 1, startNumber = 1, periodStart: timeline } = attributes; const segments = []; let time = -1; for (let sIndex = 0; sIndex < segmentTimeline.length; sIndex++) { const S = segmentTimeline[sIndex]; const duration2 = S.d; const repeat = S.r || 0; const segmentTime = S.t || 0; if (time < 0) { time = segmentTime; } if (segmentTime && segmentTime > time) { time = segmentTime; } let count; if (repeat < 0) { const nextS = sIndex + 1; if (nextS === segmentTimeline.length) { if (type === "dynamic" && minimumUpdatePeriod > 0 && media.indexOf("$Number$") > 0) { count = getLiveRValue(attributes, time, duration2); } else { count = (sourceDuration * timescale - time) / duration2; } } else { count = (segmentTimeline[nextS].t - time) / duration2; } } else { count = repeat + 1; } const end = startNumber + segments.length + count; let number = startNumber + segments.length; while (number < end) { segments.push({ number, duration: duration2 / timescale, time, timeline }); time += duration2; number++; } } return segments; }; var identifierPattern = /\$([A-z]*)(?:(%0)([0-9]+)d)?\$/g; var identifierReplacement = (values3) => (match, identifier, format, width) => { if (match === "$$") { return "$"; } if (typeof values3[identifier] === "undefined") { return match; } const value = "" + values3[identifier]; if (identifier === "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}`; }; var constructTemplateUrl = (url, values3) => url.replace(identifierPattern, identifierReplacement(values3)); var parseTemplateInfo = (attributes, segmentTimeline) => { if (!attributes.duration && !segmentTimeline) { return [{ number: attributes.startNumber || 1, duration: attributes.sourceDuration, time: 0, timeline: attributes.periodStart }]; } if (attributes.duration) { return parseByDuration(attributes); } return parseByTimeline(attributes, segmentTimeline); }; var segmentsFromTemplate = (attributes, segmentTimeline) => { const templateValues = { RepresentationID: attributes.id, Bandwidth: attributes.bandwidth || 0 }; const { initialization = { sourceURL: "", range: "" } } = attributes; const mapSegment = urlTypeToSegment({ baseUrl: attributes.baseUrl, source: constructTemplateUrl(initialization.sourceURL, templateValues), range: initialization.range }); const segments = parseTemplateInfo(attributes, segmentTimeline); return segments.map((segment) => { templateValues.Number = segment.number; templateValues.Time = segment.time; const uri = constructTemplateUrl(attributes.media || "", templateValues); const timescale = attributes.timescale || 1; const presentationTimeOffset = attributes.presentationTimeOffset || 0; const 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 ); const map = { uri, timeline: segment.timeline, duration: segment.duration, resolvedUri: resolve_url_default(attributes.baseUrl || "", uri), map: mapSegment, number: segment.number, presentationTime }; return map; }); }; var SegmentURLToSegmentObject = (attributes, segmentUrl) => { const { baseUrl, initialization = {} } = attributes; const initSegment = urlTypeToSegment({ baseUrl, source: initialization.sourceURL, range: initialization.range }); const segment = urlTypeToSegment({ baseUrl, source: segmentUrl.media, range: segmentUrl.mediaRange }); segment.map = initSegment; return segment; }; var segmentsFromList = (attributes, segmentTimeline) => { const { duration: duration2, segmentUrls = [], periodStart } = attributes; if (!duration2 && !segmentTimeline || duration2 && segmentTimeline) { throw new Error(errors.SEGMENT_TIME_UNSPECIFIED); } const segmentUrlMap = segmentUrls.map((segmentUrlObject) => SegmentURLToSegmentObject(attributes, segmentUrlObject)); let segmentTimeInfo; if (duration2) { segmentTimeInfo = parseByDuration(attributes); } if (segmentTimeline) { segmentTimeInfo = parseByTimeline(attributes, segmentTimeline); } const segments = segmentTimeInfo.map((segmentTime, index) => { if (segmentUrlMap[index]) { const segment = segmentUrlMap[index]; const timescale = attributes.timescale || 1; const 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; } }).filter((segment) => segment); return segments; }; var generateSegments = ({ attributes, segmentInfo }) => { let segmentAttributes; let 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); } const segmentsInfo = { attributes }; if (!segmentsFn) { return segmentsInfo; } const segments = segmentsFn(segmentAttributes, segmentInfo.segmentTimeline); if (segmentAttributes.duration) { const { duration: duration2, timescale = 1 } = segmentAttributes; segmentAttributes.duration = duration2 / timescale; } else if (segments.length) { segmentAttributes.duration = segments.reduce((max, segment) => { return Math.max(max, Math.ceil(segment.duration)); }, 0); } else { segmentAttributes.duration = 0; } segmentsInfo.attributes = segmentAttributes; segmentsInfo.segments = segments; if (segmentInfo.base && segmentAttributes.indexRange) { segmentsInfo.sidx = segments[0]; segmentsInfo.segments = []; } return segmentsInfo; }; var toPlaylists = (representations) => representations.map(generateSegments); var findChildren = (element, name) => from(element.childNodes).filter(({ tagName }) => tagName === name); var getContent = (element) => element.textContent.trim(); var parseDivisionValue = (value) => { return parseFloat(value.split("/").reduce((prev, current) => prev / current)); }; var parseDuration = (str) => { const SECONDS_IN_YEAR = 365 * 24 * 60 * 60; const SECONDS_IN_MONTH = 30 * 24 * 60 * 60; const SECONDS_IN_DAY = 24 * 60 * 60; const SECONDS_IN_HOUR = 60 * 60; const SECONDS_IN_MIN = 60; const durationRegex = /P(?:(\d*)Y)?(?:(\d*)M)?(?:(\d*)D)?(?:T(?:(\d*)H)?(?:(\d*)M)?(?:([\d.]*)S)?)?/; const match = durationRegex.exec(str); if (!match) { return 0; } const [year, month, day, hour, minute, second] = match.slice(1); 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 = (str) => { const dateRegex = /^\d+-\d+-\d+T\d+:\d+:\d+(\.\d+)?$/; 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(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(value) { return parseDate(value) / 1e3; }, /** * 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(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(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(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(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(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(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(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(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(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(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(value) { return parseInt(value, 10); }, /** * Specifies the presentationTimeOffset. * * @param {string} value * value of the attribute as a string * * @return {number} * The parsed presentationTimeOffset */ 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(value) { const 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(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(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(value) { return parseInt(value, 10); }, /** * Specifies the presentationTime. * * @param {string} value * value of the attribute as a string * * @return {number} * The parsed presentationTime */ presentationTime(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(value) { return value; } }; var parseAttributes2 = (el) => { if (!(el && el.attributes)) { return {}; } return from(el.attributes).reduce((a, e) => { const 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", // ISO_IEC 23009-1_2022 5.8.5.2.2 The mp4 Protection Scheme "urn:mpeg:dash:mp4protection:2011": "mp4protection" }; var buildBaseUrls = (references, baseUrlElements) => { if (!baseUrlElements.length) { return references; } return flatten(references.map(function(reference) { return baseUrlElements.map(function(baseUrlElement) { const initialBaseUrl = getContent(baseUrlElement); const resolvedBaseUrl = resolve_url_default(reference.baseUrl, initialBaseUrl); const finalBaseUrl = merge(parseAttributes2(baseUrlElement), { baseUrl: resolvedBaseUrl }); if (resolvedBaseUrl !== initialBaseUrl && !finalBaseUrl.serviceLocation && reference.serviceLocation) { finalBaseUrl.serviceLocation = reference.serviceLocation; } return finalBaseUrl; }); })); }; var getSegmentInformation = (adaptationSet) => { const segmentTemplate = findChildren(adaptationSet, "SegmentTemplate")[0]; const segmentList = findChildren(adaptationSet, "SegmentList")[0]; const segmentUrls = segmentList && findChildren(segmentList, "SegmentURL").map((s) => merge({ tag: "SegmentURL" }, parseAttributes2(s))); const segmentBase = findChildren(adaptationSet, "SegmentBase")[0]; const segmentTimelineParentNode = segmentList || segmentTemplate; const segmentTimeline = segmentTimelineParentNode && findChildren(segmentTimelineParentNode, "SegmentTimeline")[0]; const segmentInitializationParentNode = segmentList || segmentBase || segmentTemplate; const segmentInitialization = segmentInitializationParentNode && findChildren(segmentInitializationParentNode, "Initialization")[0]; const template = segmentTemplate && parseAttributes2(segmentTemplate); if (template && segmentInitialization) { template.initialization = segmentInitialization && parseAttributes2(segmentInitialization); } else if (template && template.initialization) { template.initialization = { sourceURL: template.initialization }; } const segmentInfo = { template, segmentTimeline: segmentTimeline && findChildren(segmentTimeline, "S").map((s) => parseAttributes2(s)), list: segmentList && merge(parseAttributes2(segmentList), { segmentUrls, initialization: parseAttributes2(segmentInitialization) }), base: segmentBase && merge(parseAttributes2(segmentBase), { initialization: parseAttributes2(segmentInitialization) }) }; Object.keys(segmentInfo).forEach((key) => { if (!segmentInfo[key]) { delete segmentInfo[key]; } }); return segmentInfo; }; var inheritBaseUrls = (adaptationSetAttributes, adaptationSetBaseUrls, adaptationSetSegmentInfo) => (representation) => { const repBaseUrlElements = findChildren(representation, "BaseURL"); const repBaseUrls = buildBaseUrls(adaptationSetBaseUrls, repBaseUrlElements); const attributes = merge(adaptationSetAttributes, parseAttributes2(representation)); const representationSegmentInfo = getSegmentInformation(representation); return repBaseUrls.map((baseUrl) => { return { segmentInfo: merge(adaptationSetSegmentInfo, representationSegmentInfo), attributes: merge(attributes, baseUrl) }; }); }; var generateKeySystemInformation = (contentProtectionNodes) => { return contentProtectionNodes.reduce((acc, node) => { const attributes = parseAttributes2(node); if (attributes.schemeIdUri) { attributes.schemeIdUri = attributes.schemeIdUri.toLowerCase(); } const keySystem = keySystemsMap[attributes.schemeIdUri]; if (keySystem) { acc[keySystem] = { attributes }; const psshNode = findChildren(node, "cenc:pssh")[0]; if (psshNode) { const pssh = getContent(psshNode); acc[keySystem].pssh = pssh && decodeB64ToUint8Array(pssh); } } return acc; }, {}); }; var parseCaptionServiceMetadata = (service) => { if (service.schemeIdUri === "urn:scte:dash:cc:cea-608:2015") { const values3 = typeof service.value !== "string" ? [] : service.value.split(";"); return values3.map((value) => { let channel; let language; language = value; if (/^CC\d=/.test(value)) { [channel, language] = value.split("="); } else if (/^CC\d$/.test(value)) { channel = value; } return { channel, language }; }); } else if (service.schemeIdUri === "urn:scte:dash:cc:cea-708:2015") { const values3 = typeof service.value !== "string" ? [] : service.value.split(";"); return values3.map((value) => { const flags = { // service or channel number 1-63 "channel": void 0, // language is a 3ALPHA per ISO 639.2/B // field is required "language": void 0, // 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)) { const [channel, opts = ""] = value.split("="); flags.channel = channel; flags.language = value; opts.split(",").forEach((opt) => { const [name, val] = opt.split(":"); if (name === "lang") { flags.language = val; } else if (name === "er") { flags.easyReader = Number(val); } 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; }); } }; var toEventStream = (period) => { return flatten(findChildren(period.node, "EventStream").map((eventStream) => { const eventStreamAttributes = parseAttributes2(eventStream); const schemeIdUri = eventStreamAttributes.schemeIdUri; return findChildren(eventStream, "Event").map((event) => { const eventAttributes = parseAttributes2(event); const presentationTime = eventAttributes.presentationTime || 0; const timescale = eventStreamAttributes.timescale || 1; const duration2 = eventAttributes.duration || 0; const start = presentationTime / timescale + period.attributes.start; return { schemeIdUri, value: eventStreamAttributes.value, id: eventAttributes.id, start, end: start + duration2 / timescale, messageData: getContent(event) || eventAttributes.messageData, contentEncoding: eventStreamAttributes.contentEncoding, presentationTimeOffset: eventStreamAttributes.presentationTimeOffset || 0 }; }); })); }; var toRepresentations = (periodAttributes, periodBaseUrls, periodSegmentInfo) => (adaptationSet) => { const adaptationSetAttributes = parseAttributes2(adaptationSet); const adaptationSetBaseUrls = buildBaseUrls(periodBaseUrls, findChildren(adaptationSet, "BaseURL")); const role = findChildren(adaptationSet, "Role")[0]; const roleAttributes = { role: parseAttributes2(role) }; let attrs = merge(periodAttributes, adaptationSetAttributes, roleAttributes); const accessibility = findChildren(adaptationSet, "Accessibility")[0]; const captionServices = parseCaptionServiceMetadata(parseAttributes2(accessibility)); if (captionServices) { attrs = merge(attrs, { captionServices }); } const label = findChildren(adaptationSet, "Label")[0]; if (label && label.childNodes.length) { const labelVal = label.childNodes[0].nodeValue.trim(); attrs = merge(attrs, { label: labelVal }); } const contentProtection = generateKeySystemInformation(findChildren(adaptationSet, "ContentProtection")); if (Object.keys(contentProtection).length) { attrs = merge(attrs, { contentProtection }); } const segmentInfo = getSegmentInformation(adaptationSet); const representations = findChildren(adaptationSet, "Representation"); const adaptationSetSegmentInfo = merge(periodSegmentInfo, segmentInfo); return flatten(representations.map(inheritBaseUrls(attrs, adaptationSetBaseUrls, adaptationSetSegmentInfo))); }; var toAdaptationSets = (mpdAttributes, mpdBaseUrls) => (period, index) => { const periodBaseUrls = buildBaseUrls(mpdBaseUrls, findChildren(period.node, "BaseURL")); const periodAttributes = merge(mpdAttributes, { periodStart: period.attributes.start }); if (typeof period.attributes.duration === "number") { periodAttributes.periodDuration = period.attributes.duration; } const adaptationSets = findChildren(period.node, "AdaptationSet"); const periodSegmentInfo = getSegmentInformation(period.node); return flatten(adaptationSets.map(toRepresentations(periodAttributes, periodBaseUrls, periodSegmentInfo))); }; var generateContentSteeringInformation = (contentSteeringNodes, eventHandler) => { if (contentSteeringNodes.length > 1) { eventHandler({ type: "warn", message: "The MPD manifest should contain no more than one ContentSteering tag" }); } if (!contentSteeringNodes.length) { return null; } const infoFromContentSteeringTag = merge({ serverURL: getContent(contentSteeringNodes[0]) }, parseAttributes2(contentSteeringNodes[0])); infoFromContentSteeringTag.queryBeforeStart = infoFromContentSteeringTag.queryBeforeStart === "true"; return infoFromContentSteeringTag; }; var getPeriodStart = ({ attributes, priorPeriodAttributes, mpdType }) => { if (typeof attributes.start === "number") { return attributes.start; } if (priorPeriodAttributes && typeof priorPeriodAttributes.start === "number" && typeof priorPeriodAttributes.duration === "number") { return priorPeriodAttributes.start + priorPeriodAttributes.duration; } if (!priorPeriodAttributes && mpdType === "static") { return 0; } return null; }; var inheritAttributes = (mpd, options = {}) => { const { manifestUri = "", NOW = Date.now(), clientOffset = 0, // TODO: For now, we are expecting an eventHandler callback function // to be passed into the mpd parser as an option. // In the future, we should enable stream parsing by using the Stream class from vhs-utils. // This will support new features including a standardized event handler. // See the m3u8 parser for examples of how stream parsing is currently used for HLS parsing. // https://github.com/videojs/vhs-utils/blob/88d6e10c631e57a5af02c5a62bc7376cd456b4f5/src/stream.js#L9 eventHandler = function() { } } = options; const periodNodes = findChildren(mpd, "Period"); if (!periodNodes.length) { throw new Error(errors.INVALID_NUMBER_OF_PERIOD); } const locations = findChildren(mpd, "Location"); const mpdAttributes = parseAttributes2(mpd); const mpdBaseUrls = buildBaseUrls([{ baseUrl: manifestUri }], findChildren(mpd, "BaseURL")); const contentSteeringNodes = findChildren(mpd, "ContentSteering"); mpdAttributes.type = mpdAttributes.type || "static"; mpdAttributes.sourceDuration = mpdAttributes.mediaPresentationDuration || 0; mpdAttributes.NOW = NOW; mpdAttributes.clientOffset = clientOffset; if (locations.length) { mpdAttributes.locations = locations.map(getContent); } const periods = []; periodNodes.forEach((node, index) => { const attributes = parseAttributes2(node); const priorPeriod = periods[index - 1]; attributes.start = getPeriodStart({ attributes, priorPeriodAttributes: priorPeriod ? priorPeriod.attributes : null, mpdType: mpdAttributes.type }); periods.push({ node, attributes }); }); return { locations: mpdAttributes.locations, contentSteeringInfo: generateContentSteeringInformation(contentSteeringNodes, eventHandler), // TODO: There are occurences where this `representationInfo` array contains undesired // duplicates. This generally occurs when there are multiple BaseURL nodes that are // direct children of the MPD node. When we attempt to resolve URLs from a combination of the // parent BaseURL and a child BaseURL, and the value does not resolve, // we end up returning the child BaseURL multiple times. // We need to determine a way to remove these duplicates in a safe way. // See: https://github.com/videojs/mpd-parser/pull/17#discussion_r162750527 representationInfo: flatten(periods.map(toAdaptationSets(mpdAttributes, mpdBaseUrls))), eventStream: flatten(periods.map(toEventStream)) }; }; var stringToMpdXml = (manifestString) => { if (manifestString === "") { throw new Error(errors.DASH_EMPTY_MANIFEST); } const parser5 = new import_xmldom.DOMParser(); let xml; let mpd; try { xml = parser5.parseFromString(manifestString, "application/xml"); mpd = xml && xml.documentElement.tagName === "MPD" ? xml.documentElement : null; } catch (e) { } if (!mpd || mpd && mpd.getElementsByTagName("parsererror").length > 0) { throw new Error(errors.DASH_INVALID_XML); } return mpd; }; var parseUTCTimingScheme = (mpd) => { const UTCTimingNode = findChildren(mpd, "UTCTiming")[0]; if (!UTCTimingNode) { return null; } const attributes = parseAttributes2(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 parse = (manifestString, options = {}) => { const parsedManifestInfo = inheritAttributes(stringToMpdXml(manifestString), options); const playlists = toPlaylists(parsedManifestInfo.representationInfo); return toM3u8({ dashPlaylists: playlists, locations: parsedManifestInfo.locations, contentSteering: parsedManifestInfo.contentSteeringInfo, sidxMapping: options.sidxMapping, previousManifest: options.previousManifest, eventStream: parsedManifestInfo.eventStream }); }; var parseUTCTiming = (manifestString) => parseUTCTimingScheme(stringToMpdXml(manifestString)); // node_modules/video.js/dist/video.es.js var import_parse_sidx = __toESM(require_parse_sidx()); // node_modules/@videojs/vhs-utils/es/id3-helpers.js var ID3 = toUint8([73, 68, 51]); var getId3Size = function getId3Size2(bytes, offset) { if (offset === void 0) { offset = 0; } bytes = toUint8(bytes); var flags = bytes[offset + 5]; var returnSize = bytes[offset + 6] << 21 | bytes[offset + 7] << 14 | bytes[offset + 8] << 7 | bytes[offset + 9]; var footerPresent = (flags & 16) >> 4; if (footerPresent) { return returnSize + 20; } return returnSize + 10; }; var getId3Offset = function getId3Offset2(bytes, offset) { if (offset === void 0) { offset = 0; } bytes = toUint8(bytes); if (bytes.length - offset < 10 || !bytesMatch(bytes, ID3, { offset })) { return offset; } offset += getId3Size(bytes, offset); return getId3Offset2(bytes, offset); }; // node_modules/@videojs/vhs-utils/es/opus-helpers.js var OPUS_HEAD = new Uint8Array([ // O, p, u, s 79, 112, 117, 115, // H, e, a, d 72, 101, 97, 100 ]); // node_modules/@videojs/vhs-utils/es/mp4-helpers.js var normalizePath = function normalizePath2(path) { if (typeof path === "string") { return stringToBytes(path); } if (typeof path === "number") { return path; } return path; }; var normalizePaths = function normalizePaths2(paths) { if (!Array.isArray(paths)) { return [normalizePath(paths)]; } return paths.map(function(p) { return normalizePath(p); }); }; var DESCRIPTORS; var parseDescriptors = function parseDescriptors2(bytes) { bytes = toUint8(bytes); var results = []; var i = 0; while (bytes.length > i) { var tag = bytes[i]; var size = 0; var headerSize = 0; headerSize++; var byte = bytes[headerSize]; headerSize++; while (byte & 128) { size = (byte & 127) << 7; byte = bytes[headerSize]; headerSize++; } size += byte & 127; for (var z = 0; z < DESCRIPTORS.length; z++) { var _DESCRIPTORS$z = DESCRIPTORS[z], id = _DESCRIPTORS$z.id, parser5 = _DESCRIPTORS$z.parser; if (tag === id) { results.push(parser5(bytes.subarray(headerSize, headerSize + size))); break; } } i += size + headerSize; } return results; }; DESCRIPTORS = [{ id: 3, parser: function parser(bytes) { var desc = { tag: 3, id: bytes[0] << 8 | bytes[1], flags: bytes[2], size: 3, dependsOnEsId: 0, ocrEsId: 0, descriptors: [], url: "" }; if (desc.flags & 128) { desc.dependsOnEsId = bytes[desc.size] << 8 | bytes[desc.size + 1]; desc.size += 2; } if (desc.flags & 64) { var len = bytes[desc.size]; desc.url = bytesToString(bytes.subarray(desc.size + 1, desc.size + 1 + len)); desc.size += len; } if (desc.flags & 32) { desc.ocrEsId = bytes[desc.size] << 8 | bytes[desc.size + 1]; desc.size += 2; } desc.descriptors = parseDescriptors(bytes.subarray(desc.size)) || []; return desc; } }, { id: 4, parser: function parser2(bytes) { var desc = { tag: 4, oti: bytes[0], streamType: bytes[1], bufferSize: bytes[2] << 16 | bytes[3] << 8 | bytes[4], maxBitrate: bytes[5] << 24 | bytes[6] << 16 | bytes[7] << 8 | bytes[8], avgBitrate: bytes[9] << 24 | bytes[10] << 16 | bytes[11] << 8 | bytes[12], descriptors: parseDescriptors(bytes.subarray(13)) }; return desc; } }, { id: 5, parser: function parser3(bytes) { return { tag: 5, bytes }; } }, { id: 6, parser: function parser4(bytes) { return { tag: 6, bytes }; } }]; var findBox = function findBox2(bytes, paths, complete) { if (complete === void 0) { complete = false; } paths = normalizePaths(paths); bytes = toUint8(bytes); var results = []; if (!paths.length) { return results; } var i = 0; while (i < bytes.length) { var size = (bytes[i] << 24 | bytes[i + 1] << 16 | bytes[i + 2] << 8 | bytes[i + 3]) >>> 0; var type = bytes.subarray(i + 4, i + 8); if (size === 0) { break; } var end = i + size; if (end > bytes.length) { if (complete) { break; } end = bytes.length; } var data = bytes.subarray(i + 8, end); if (bytesMatch(type, paths[0])) { if (paths.length === 1) { results.push(data); } else { results.push.apply(results, findBox2(data, paths.slice(1), complete)); } } i = end; } return results; }; // node_modules/@videojs/vhs-utils/es/ebml-helpers.js var EBML_TAGS = { EBML: toUint8([26, 69, 223, 163]), DocType: toUint8([66, 130]), Segment: toUint8([24, 83, 128, 103]), SegmentInfo: toUint8([21, 73, 169, 102]), Tracks: toUint8([22, 84, 174, 107]), Track: toUint8([174]), TrackNumber: toUint8([215]), DefaultDuration: toUint8([35, 227, 131]), TrackEntry: toUint8([174]), TrackType: toUint8([131]), FlagDefault: toUint8([136]), CodecID: toUint8([134]), CodecPrivate: toUint8([99, 162]), VideoTrack: toUint8([224]), AudioTrack: toUint8([225]), // Not used yet, but will be used for live webm/mkv // see https://www.matroska.org/technical/basics.html#block-structure // see https://www.matroska.org/technical/basics.html#simpleblock-structure Cluster: toUint8([31, 67, 182, 117]), Timestamp: toUint8([231]), TimestampScale: toUint8([42, 215, 177]), BlockGroup: toUint8([160]), BlockDuration: toUint8([155]), Block: toUint8([161]), SimpleBlock: toUint8([163]) }; var LENGTH_TABLE = [128, 64, 32, 16, 8, 4, 2, 1]; var getLength = function getLength2(byte) { var len = 1; for (var i = 0; i < LENGTH_TABLE.length; i++) { if (byte & LENGTH_TABLE[i]) { break; } len++; } return len; }; var getvint = function getvint2(bytes, offset, removeLength, signed) { if (removeLength === void 0) { removeLength = true; } if (signed === void 0) { signed = false; } var length = getLength(bytes[offset]); var valueBytes = bytes.subarray(offset, offset + length); if (removeLength) { valueBytes = Array.prototype.slice.call(bytes, offset, offset + length); valueBytes[0] ^= LENGTH_TABLE[length - 1]; } return { length, value: bytesToNumber(valueBytes, { signed }), bytes: valueBytes }; }; var normalizePath3 = function normalizePath4(path) { if (typeof path === "string") { return path.match(/.{1,2}/g).map(function(p) { return normalizePath4(p); }); } if (typeof path === "number") { return numberToBytes(path); } return path; }; var normalizePaths3 = function normalizePaths4(paths) { if (!Array.isArray(paths)) { return [normalizePath3(paths)]; } return paths.map(function(p) { return normalizePath3(p); }); }; var getInfinityDataSize = function getInfinityDataSize2(id, bytes, offset) { if (offset >= bytes.length) { return bytes.length; } var innerid = getvint(bytes, offset, false); if (bytesMatch(id.bytes, innerid.bytes)) { return offset; } var dataHeader = getvint(bytes, offset + innerid.length); return getInfinityDataSize2(id, bytes, offset + dataHeader.length + dataHeader.value + innerid.length); }; var findEbml = function findEbml2(bytes, paths) { paths = normalizePaths3(paths); bytes = toUint8(bytes); var results = []; if (!paths.length) { return results; } var i = 0; while (i < bytes.length) { var id = getvint(bytes, i, false); var dataHeader = getvint(bytes, i + id.length); var dataStart = i + id.length + dataHeader.length; if (dataHeader.value === 127) { dataHeader.value = getInfinityDataSize(id, bytes, dataStart); if (dataHeader.value !== bytes.length) { dataHeader.value -= dataStart; } } var dataEnd = dataStart + dataHeader.value > bytes.length ? bytes.length : dataStart + dataHeader.value; var data = bytes.subarray(dataStart, dataEnd); if (bytesMatch(paths[0], id.bytes)) { if (paths.length === 1) { results.push(data); } else { results = results.concat(findEbml2(data, paths.slice(1))); } } var totalLength = id.length + dataHeader.length + data.length; i += totalLength; } return results; }; // node_modules/@videojs/vhs-utils/es/nal-helpers.js var NAL_TYPE_ONE = toUint8([0, 0, 0, 1]); var NAL_TYPE_TWO = toUint8([0, 0, 1]); var EMULATION_PREVENTION = toUint8([0, 0, 3]); var discardEmulationPreventionBytes = function discardEmulationPreventionBytes2(bytes) { var positions = []; var i = 1; while (i < bytes.length - 2) { if (bytesMatch(bytes.subarray(i, i + 3), EMULATION_PREVENTION)) { positions.push(i + 2); i++; } i++; } if (positions.length === 0) { return bytes; } var newLength = bytes.length - positions.length; var newData = new Uint8Array(newLength); var sourceIndex = 0; for (i = 0; i < newLength; sourceIndex++, i++) { if (sourceIndex === positions[0]) { sourceIndex++; positions.shift(); } newData[i] = bytes[sourceIndex]; } return newData; }; var findNal = function findNal2(bytes, dataType, types, nalLimit) { if (nalLimit === void 0) { nalLimit = Infinity; } bytes = toUint8(bytes); types = [].concat(types); var i = 0; var nalStart; var nalsFound = 0; while (i < bytes.length && (nalsFound < nalLimit || nalStart)) { var nalOffset = void 0; if (bytesMatch(bytes.subarray(i), NAL_TYPE_ONE)) { nalOffset = 4; } else if (bytesMatch(bytes.subarray(i), NAL_TYPE_TWO)) { nalOffset = 3; } if (!nalOffset) { i++; continue; } nalsFound++; if (nalStart) { return discardEmulationPreventionBytes(bytes.subarray(nalStart, i)); } var nalType = void 0; if (dataType === "h264") { nalType = bytes[i + nalOffset] & 31; } else if (dataType === "h265") { nalType = bytes[i + nalOffset] >> 1 & 63; } if (types.indexOf(nalType) !== -1) { nalStart = i + nalOffset; } i += nalOffset + (dataType === "h264" ? 1 : 2); } return bytes.subarray(0, 0); }; var findH264Nal = function findH264Nal2(bytes, type, nalLimit) { return findNal(bytes, "h264", type, nalLimit); }; var findH265Nal = function findH265Nal2(bytes, type, nalLimit) { return findNal(bytes, "h265", type, nalLimit); }; // node_modules/@videojs/vhs-utils/es/containers.js var CONSTANTS = { // "webm" string literal in hex "webm": toUint8([119, 101, 98, 109]), // "matroska" string literal in hex "matroska": toUint8([109, 97, 116, 114, 111, 115, 107, 97]), // "fLaC" string literal in hex "flac": toUint8([102, 76, 97, 67]), // "OggS" string literal in hex "ogg": toUint8([79, 103, 103, 83]), // ac-3 sync byte, also works for ec-3 as that is simply a codec // of ac-3 "ac3": toUint8([11, 119]), // "RIFF" string literal in hex used for wav and avi "riff": toUint8([82, 73, 70, 70]), // "AVI" string literal in hex "avi": toUint8([65, 86, 73]), // "WAVE" string literal in hex "wav": toUint8([87, 65, 86, 69]), // "ftyp3g" string literal in hex "3gp": toUint8([102, 116, 121, 112, 51, 103]), // "ftyp" string literal in hex "mp4": toUint8([102, 116, 121, 112]), // "styp" string literal in hex "fmp4": toUint8([115, 116, 121, 112]), // "ftypqt" string literal in hex "mov": toUint8([102, 116, 121, 112, 113, 116]), // moov string literal in hex "moov": toUint8([109, 111, 111, 118]), // moof string literal in hex "moof": toUint8([109, 111, 111, 102]) }; var _isLikely = { aac: function aac(bytes) { var offset = getId3Offset(bytes); return bytesMatch(bytes, [255, 16], { offset, mask: [255, 22] }); }, mp3: function mp3(bytes) { var offset = getId3Offset(bytes); return bytesMatch(bytes, [255, 2], { offset, mask: [255, 6] }); }, webm: function webm(bytes) { var docType = findEbml(bytes, [EBML_TAGS.EBML, EBML_TAGS.DocType])[0]; return bytesMatch(docType, CONSTANTS.webm); }, mkv: function mkv(bytes) { var docType = findEbml(bytes, [EBML_TAGS.EBML, EBML_TAGS.DocType])[0]; return bytesMatch(docType, CONSTANTS.matroska); }, mp4: function mp4(bytes) { if (_isLikely["3gp"](bytes) || _isLikely.mov(bytes)) { return false; } if (bytesMatch(bytes, CONSTANTS.mp4, { offset: 4 }) || bytesMatch(bytes, CONSTANTS.fmp4, { offset: 4 })) { return true; } if (bytesMatch(bytes, CONSTANTS.moof, { offset: 4 }) || bytesMatch(bytes, CONSTANTS.moov, { offset: 4 })) { return true; } }, mov: function mov(bytes) { return bytesMatch(bytes, CONSTANTS.mov, { offset: 4 }); }, "3gp": function gp(bytes) { return bytesMatch(bytes, CONSTANTS["3gp"], { offset: 4 }); }, ac3: function ac3(bytes) { var offset = getId3Offset(bytes); return bytesMatch(bytes, CONSTANTS.ac3, { offset }); }, ts: function ts(bytes) { if (bytes.length < 189 && bytes.length >= 1) { return bytes[0] === 71; } var i = 0; while (i + 188 < bytes.length && i < 188) { if (bytes[i] === 71 && bytes[i + 188] === 71) { return true; } i += 1; } return false; }, flac: function flac(bytes) { var offset = getId3Offset(bytes); return bytesMatch(bytes, CONSTANTS.flac, { offset }); }, ogg: function ogg(bytes) { return bytesMatch(bytes, CONSTANTS.ogg); }, avi: function avi(bytes) { return bytesMatch(bytes, CONSTANTS.riff) && bytesMatch(bytes, CONSTANTS.avi, { offset: 8 }); }, wav: function wav(bytes) { return bytesMatch(bytes, CONSTANTS.riff) && bytesMatch(bytes, CONSTANTS.wav, { offset: 8 }); }, "h264": function h264(bytes) { return findH264Nal(bytes, 7, 3).length; }, "h265": function h265(bytes) { return findH265Nal(bytes, [32, 33], 3).length; } }; var isLikelyTypes = Object.keys(_isLikely).filter(function(t) { return t !== "ts" && t !== "h264" && t !== "h265"; }).concat(["ts", "h264", "h265"]); isLikelyTypes.forEach(function(type) { var isLikelyFn = _isLikely[type]; _isLikely[type] = function(bytes) { return isLikelyFn(toUint8(bytes)); }; }); var isLikely = _isLikely; var detectContainerForBytes = function detectContainerForBytes2(bytes) { bytes = toUint8(bytes); for (var i = 0; i < isLikelyTypes.length; i++) { var type = isLikelyTypes[i]; if (isLikely[type](bytes)) { return type; } } return ""; }; var isLikelyFmp4MediaSegment = function isLikelyFmp4MediaSegment2(bytes) { return findBox(bytes, ["moof"]).length > 0; }; // node_modules/video.js/dist/video.es.js var import_clock = __toESM(require_clock()); var version$6 = "8.22.0"; var hooks_ = {}; var hooks = function(type, fn) { hooks_[type] = hooks_[type] || []; if (fn) { hooks_[type] = hooks_[type].concat(fn); } return hooks_[type]; }; var hook = function(type, fn) { hooks(type, fn); }; var removeHook = function(type, fn) { const index = hooks(type).indexOf(fn); if (index <= -1) { return false; } hooks_[type] = hooks_[type].slice(); hooks_[type].splice(index, 1); return true; }; var hookOnce = function(type, fn) { hooks(type, [].concat(fn).map((original) => { const wrapper = (...args) => { removeHook(type, wrapper); return original(...args); }; return wrapper; })); }; var FullscreenApi = { prefixed: true }; var apiMap = [ ["requestFullscreen", "exitFullscreen", "fullscreenElement", "fullscreenEnabled", "fullscreenchange", "fullscreenerror", "fullscreen"], // WebKit ["webkitRequestFullscreen", "webkitExitFullscreen", "webkitFullscreenElement", "webkitFullscreenEnabled", "webkitfullscreenchange", "webkitfullscreenerror", "-webkit-full-screen"] ]; var specApi = apiMap[0]; var browserApi; for (let i = 0; i < apiMap.length; i++) { if (apiMap[i][1] in import_document.default) { browserApi = apiMap[i]; break; } } if (browserApi) { for (let i = 0; i < browserApi.length; i++) { FullscreenApi[specApi[i]] = browserApi[i]; } FullscreenApi.prefixed = browserApi[0] !== specApi[0]; } var history = []; var LogByTypeFactory = (name, log2, styles) => (type, level, args) => { const lvl = log2.levels[level]; const lvlRegExp = new RegExp(`^(${lvl})$`); let resultName = name; if (type !== "log") { args.unshift(type.toUpperCase() + ":"); } if (styles) { resultName = `%c${name}`; args.unshift(styles); } args.unshift(resultName + ":"); if (history) { history.push([].concat(args)); const splice = history.length - 1e3; history.splice(0, splice > 0 ? splice : 0); } if (!import_window6.default.console) { return; } let fn = import_window6.default.console[type]; if (!fn && type === "debug") { fn = import_window6.default.console.info || import_window6.default.console.log; } if (!fn || !lvl || !lvlRegExp.test(type)) { return; } fn[Array.isArray(args) ? "apply" : "call"](import_window6.default.console, args); }; function createLogger$1(name, delimiter = ":", styles = "") { let level = "info"; let logByType; function log2(...args) { logByType("log", level, args); } logByType = LogByTypeFactory(name, log2, styles); log2.createLogger = (subName, subDelimiter, subStyles) => { const resultDelimiter = subDelimiter !== void 0 ? subDelimiter : delimiter; const resultStyles = subStyles !== void 0 ? subStyles : styles; const resultName = `${name} ${resultDelimiter} ${subName}`; return createLogger$1(resultName, resultDelimiter, resultStyles); }; log2.createNewLogger = (newName, newDelimiter, newStyles) => { return createLogger$1(newName, newDelimiter, newStyles); }; log2.levels = { all: "debug|log|warn|error", off: "", debug: "debug|log|warn|error", info: "log|warn|error", warn: "warn|error", error: "error", DEFAULT: level }; log2.level = (lvl) => { if (typeof lvl === "string") { if (!log2.levels.hasOwnProperty(lvl)) { throw new Error(`"${lvl}" in not a valid log level`); } level = lvl; } return level; }; log2.history = () => history ? [].concat(history) : []; log2.history.filter = (fname) => { return (history || []).filter((historyItem) => { return new RegExp(`.*${fname}.*`).test(historyItem[0]); }); }; log2.history.clear = () => { if (history) { history.length = 0; } }; log2.history.disable = () => { if (history !== null) { history.length = 0; history = null; } }; log2.history.enable = () => { if (history === null) { history = []; } }; log2.error = (...args) => logByType("error", level, args); log2.warn = (...args) => logByType("warn", level, args); log2.debug = (...args) => logByType("debug", level, args); return log2; } var log$1 = createLogger$1("VIDEOJS"); var createLogger = log$1.createLogger; var toString = Object.prototype.toString; var keys = function(object) { return isObject2(object) ? Object.keys(object) : []; }; function each(object, fn) { keys(object).forEach((key) => fn(object[key], key)); } function reduce(object, fn, initial = 0) { return keys(object).reduce((accum, key) => fn(accum, object[key], key), initial); } function isObject2(value) { return !!value && typeof value === "object"; } function isPlain(value) { return isObject2(value) && toString.call(value) === "[object Object]" && value.constructor === Object; } function merge$1(...sources) { const result = {}; sources.forEach((source) => { if (!source) { return; } each(source, (value, key) => { if (!isPlain(value)) { result[key] = value; return; } if (!isPlain(result[key])) { result[key] = {}; } result[key] = merge$1(result[key], value); }); }); return result; } function values2(source = {}) { const result = []; for (const key in source) { if (source.hasOwnProperty(key)) { const value = source[key]; result.push(value); } } return result; } function defineLazyProperty(obj, key, getValue, setter = true) { const set2 = (value) => Object.defineProperty(obj, key, { value, enumerable: true, writable: true }); const options = { configurable: true, enumerable: true, get() { const value = getValue(); set2(value); return value; } }; if (setter) { options.set = set2; } return Object.defineProperty(obj, key, options); } var Obj = Object.freeze({ __proto__: null, each, reduce, isObject: isObject2, isPlain, merge: merge$1, values: values2, defineLazyProperty }); var IS_IPOD = false; var IOS_VERSION = null; var IS_ANDROID = false; var ANDROID_VERSION; var IS_FIREFOX = false; var IS_EDGE = false; var IS_CHROMIUM = false; var IS_CHROME = false; var CHROMIUM_VERSION = null; var CHROME_VERSION = null; var IS_CHROMECAST_RECEIVER = Boolean(import_window6.default.cast && import_window6.default.cast.framework && import_window6.default.cast.framework.CastReceiverContext); var IE_VERSION = null; var IS_SAFARI = false; var IS_WINDOWS = false; var IS_IPAD = false; var IS_IPHONE = false; var IS_TIZEN = false; var IS_WEBOS = false; var IS_SMART_TV = false; var TOUCH_ENABLED = Boolean(isReal() && ("ontouchstart" in import_window6.default || import_window6.default.navigator.maxTouchPoints || import_window6.default.DocumentTouch && import_window6.default.document instanceof import_window6.default.DocumentTouch)); var UAD = import_window6.default.navigator && import_window6.default.navigator.userAgentData; if (UAD && UAD.platform && UAD.brands) { IS_ANDROID = UAD.platform === "Android"; IS_EDGE = Boolean(UAD.brands.find((b) => b.brand === "Microsoft Edge")); IS_CHROMIUM = Boolean(UAD.brands.find((b) => b.brand === "Chromium")); IS_CHROME = !IS_EDGE && IS_CHROMIUM; CHROMIUM_VERSION = CHROME_VERSION = (UAD.brands.find((b) => b.brand === "Chromium") || {}).version || null; IS_WINDOWS = UAD.platform === "Windows"; } if (!IS_CHROMIUM) { const USER_AGENT = import_window6.default.navigator && import_window6.default.navigator.userAgent || ""; IS_IPOD = /iPod/i.test(USER_AGENT); IOS_VERSION = function() { const match = USER_AGENT.match(/OS (\d+)_/i); if (match && match[1]) { return match[1]; } return null; }(); IS_ANDROID = /Android/i.test(USER_AGENT); ANDROID_VERSION = function() { const match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i); if (!match) { return null; } const major = match[1] && parseFloat(match[1]); const minor = match[2] && parseFloat(match[2]); if (major && minor) { return parseFloat(match[1] + "." + match[2]); } else if (major) { return major; } return null; }(); IS_FIREFOX = /Firefox/i.test(USER_AGENT); IS_EDGE = /Edg/i.test(USER_AGENT); IS_CHROMIUM = /Chrome/i.test(USER_AGENT) || /CriOS/i.test(USER_AGENT); IS_CHROME = !IS_EDGE && IS_CHROMIUM; CHROMIUM_VERSION = CHROME_VERSION = function() { const match = USER_AGENT.match(/(Chrome|CriOS)\/(\d+)/); if (match && match[2]) { return parseFloat(match[2]); } return null; }(); IE_VERSION = function() { const result = /MSIE\s(\d+)\.\d/.exec(USER_AGENT); let version2 = result && parseFloat(result[1]); if (!version2 && /Trident\/7.0/i.test(USER_AGENT) && /rv:11.0/.test(USER_AGENT)) { version2 = 11; } return version2; }(); IS_TIZEN = /Tizen/i.test(USER_AGENT); IS_WEBOS = /Web0S/i.test(USER_AGENT); IS_SMART_TV = IS_TIZEN || IS_WEBOS; IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE && !IS_SMART_TV; IS_WINDOWS = /Windows/i.test(USER_AGENT); IS_IPAD = /iPad/i.test(USER_AGENT) || IS_SAFARI && TOUCH_ENABLED && !/iPhone/i.test(USER_AGENT); IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD; } var IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD; var IS_ANY_SAFARI = (IS_SAFARI || IS_IOS) && !IS_CHROME; var browser = Object.freeze({ __proto__: null, get IS_IPOD() { return IS_IPOD; }, get IOS_VERSION() { return IOS_VERSION; }, get IS_ANDROID() { return IS_ANDROID; }, get ANDROID_VERSION() { return ANDROID_VERSION; }, get IS_FIREFOX() { return IS_FIREFOX; }, get IS_EDGE() { return IS_EDGE; }, get IS_CHROMIUM() { return IS_CHROMIUM; }, get IS_CHROME() { return IS_CHROME; }, get CHROMIUM_VERSION() { return CHROMIUM_VERSION; }, get CHROME_VERSION() { return CHROME_VERSION; }, IS_CHROMECAST_RECEIVER, get IE_VERSION() { return IE_VERSION; }, get IS_SAFARI() { return IS_SAFARI; }, get IS_WINDOWS() { return IS_WINDOWS; }, get IS_IPAD() { return IS_IPAD; }, get IS_IPHONE() { return IS_IPHONE; }, get IS_TIZEN() { return IS_TIZEN; }, get IS_WEBOS() { return IS_WEBOS; }, get IS_SMART_TV() { return IS_SMART_TV; }, TOUCH_ENABLED, IS_IOS, IS_ANY_SAFARI }); function isNonBlankString(str) { return typeof str === "string" && Boolean(str.trim()); } function throwIfWhitespace(str) { if (str.indexOf(" ") >= 0) { throw new Error("class has illegal whitespace characters"); } } function isReal() { return import_document.default === import_window6.default.document; } function isEl(value) { return isObject2(value) && value.nodeType === 1; } function isInFrame() { try { return import_window6.default.parent !== import_window6.default.self; } catch (x) { return true; } } function createQuerier(method) { return function(selector, context) { if (!isNonBlankString(selector)) { return import_document.default[method](null); } if (isNonBlankString(context)) { context = import_document.default.querySelector(context); } const ctx = isEl(context) ? context : import_document.default; return ctx[method] && ctx[method](selector); }; } function createEl(tagName = "div", properties = {}, attributes = {}, content) { const el = import_document.default.createElement(tagName); Object.getOwnPropertyNames(properties).forEach(function(propName) { const val = properties[propName]; if (propName === "textContent") { textContent(el, val); } else if (el[propName] !== val || propName === "tabIndex") { el[propName] = val; } }); Object.getOwnPropertyNames(attributes).forEach(function(attrName) { el.setAttribute(attrName, attributes[attrName]); }); if (content) { appendContent(el, content); } return el; } function textContent(el, text) { if (typeof el.textContent === "undefined") { el.innerText = text; } else { el.textContent = text; } return el; } function prependTo(child, parent) { if (parent.firstChild) { parent.insertBefore(child, parent.firstChild); } else { parent.appendChild(child); } } function hasClass(element, classToCheck) { throwIfWhitespace(classToCheck); return element.classList.contains(classToCheck); } function addClass(element, ...classesToAdd) { element.classList.add(...classesToAdd.reduce((prev, current) => prev.concat(current.split(/\s+/)), [])); return element; } function removeClass(element, ...classesToRemove) { if (!element) { log$1.warn("removeClass was called with an element that doesn't exist"); return null; } element.classList.remove(...classesToRemove.reduce((prev, current) => prev.concat(current.split(/\s+/)), [])); return element; } function toggleClass(element, classToToggle, predicate) { if (typeof predicate === "function") { predicate = predicate(element, classToToggle); } if (typeof predicate !== "boolean") { predicate = void 0; } classToToggle.split(/\s+/).forEach((className) => element.classList.toggle(className, predicate)); return element; } function setAttributes(el, attributes) { Object.getOwnPropertyNames(attributes).forEach(function(attrName) { const attrValue = attributes[attrName]; if (attrValue === null || typeof attrValue === "undefined" || attrValue === false) { el.removeAttribute(attrName); } else { el.setAttribute(attrName, attrValue === true ? "" : attrValue); } }); } function getAttributes(tag) { const obj = {}; const knownBooleans = ["autoplay", "controls", "playsinline", "loop", "muted", "default", "defaultMuted"]; if (tag && tag.attributes && tag.attributes.length > 0) { const attrs = tag.attributes; for (let i = attrs.length - 1; i >= 0; i--) { const attrName = attrs[i].name; let attrVal = attrs[i].value; if (knownBooleans.includes(attrName)) { attrVal = attrVal !== null ? true : false; } obj[attrName] = attrVal; } } return obj; } function getAttribute(el, attribute) { return el.getAttribute(attribute); } function setAttribute(el, attribute, value) { el.setAttribute(attribute, value); } function removeAttribute(el, attribute) { el.removeAttribute(attribute); } function blockTextSelection() { import_document.default.body.focus(); import_document.default.onselectstart = function() { return false; }; } function unblockTextSelection() { import_document.default.onselectstart = function() { return true; }; } function getBoundingClientRect(el) { if (el && el.getBoundingClientRect && el.parentNode) { const rect = el.getBoundingClientRect(); const result = {}; ["bottom", "height", "left", "right", "top", "width"].forEach((k) => { if (rect[k] !== void 0) { result[k] = rect[k]; } }); if (!result.height) { result.height = parseFloat(computedStyle(el, "height")); } if (!result.width) { result.width = parseFloat(computedStyle(el, "width")); } return result; } } function findPosition(el) { if (!el || el && !el.offsetParent) { return { left: 0, top: 0, width: 0, height: 0 }; } const width = el.offsetWidth; const height = el.offsetHeight; let left = 0; let top = 0; while (el.offsetParent && el !== import_document.default[FullscreenApi.fullscreenElement]) { left += el.offsetLeft; top += el.offsetTop; el = el.offsetParent; } return { left, top, width, height }; } function getPointerPosition(el, event) { const translated = { x: 0, y: 0 }; if (IS_IOS) { let item = el; while (item && item.nodeName.toLowerCase() !== "html") { const transform2 = computedStyle(item, "transform"); if (/^matrix/.test(transform2)) { const values3 = transform2.slice(7, -1).split(/,\s/).map(Number); translated.x += values3[4]; translated.y += values3[5]; } else if (/^matrix3d/.test(transform2)) { const values3 = transform2.slice(9, -1).split(/,\s/).map(Number); translated.x += values3[12]; translated.y += values3[13]; } if (item.assignedSlot && item.assignedSlot.parentElement && import_window6.default.WebKitCSSMatrix) { const transformValue = import_window6.default.getComputedStyle(item.assignedSlot.parentElement).transform; const matrix = new import_window6.default.WebKitCSSMatrix(transformValue); translated.x += matrix.m41; translated.y += matrix.m42; } item = item.parentNode || item.host; } } const position = {}; const boxTarget = findPosition(event.target); const box = findPosition(el); const boxW = box.width; const boxH = box.height; let offsetY = event.offsetY - (box.top - boxTarget.top); let offsetX = event.offsetX - (box.left - boxTarget.left); if (event.changedTouches) { offsetX = event.changedTouches[0].pageX - box.left; offsetY = event.changedTouches[0].pageY + box.top; if (IS_IOS) { offsetX -= translated.x; offsetY -= translated.y; } } position.y = 1 - Math.max(0, Math.min(1, offsetY / boxH)); position.x = Math.max(0, Math.min(1, offsetX / boxW)); return position; } function isTextNode(value) { return isObject2(value) && value.nodeType === 3; } function emptyEl(el) { while (el.firstChild) { el.removeChild(el.firstChild); } return el; } function normalizeContent(content) { if (typeof content === "function") { content = content(); } return (Array.isArray(content) ? content : [content]).map((value) => { if (typeof value === "function") { value = value(); } if (isEl(value) || isTextNode(value)) { return value; } if (typeof value === "string" && /\S/.test(value)) { return import_document.default.createTextNode(value); } }).filter((value) => value); } function appendContent(el, content) { normalizeContent(content).forEach((node) => el.appendChild(node)); return el; } function insertContent(el, content) { return appendContent(emptyEl(el), content); } function isSingleLeftClick(event) { if (event.button === void 0 && event.buttons === void 0) { return true; } if (event.button === 0 && event.buttons === void 0) { return true; } if (event.type === "mouseup" && event.button === 0 && event.buttons === 0) { return true; } if (event.type === "mousedown" && event.button === 0 && event.buttons === 0) { return true; } if (event.button !== 0 || event.buttons !== 1) { return false; } return true; } var $ = createQuerier("querySelector"); var $$ = createQuerier("querySelectorAll"); function computedStyle(el, prop) { if (!el || !prop) { return ""; } if (typeof import_window6.default.getComputedStyle === "function") { let computedStyleValue; try { computedStyleValue = import_window6.default.getComputedStyle(el); } catch (e) { return ""; } return computedStyleValue ? computedStyleValue.getPropertyValue(prop) || computedStyleValue[prop] : ""; } return ""; } function copyStyleSheetsToWindow(win) { [...import_document.default.styleSheets].forEach((styleSheet) => { try { const cssRules = [...styleSheet.cssRules].map((rule) => rule.cssText).join(""); const style = import_document.default.createElement("style"); style.textContent = cssRules; win.document.head.appendChild(style); } catch (e) { const link = import_document.default.createElement("link"); link.rel = "stylesheet"; link.type = styleSheet.type; link.media = styleSheet.media.mediaText; link.href = styleSheet.href; win.document.head.appendChild(link); } }); } var Dom = Object.freeze({ __proto__: null, isReal, isEl, isInFrame, createEl, textContent, prependTo, hasClass, addClass, removeClass, toggleClass, setAttributes, getAttributes, getAttribute, setAttribute, removeAttribute, blockTextSelection, unblockTextSelection, getBoundingClientRect, findPosition, getPointerPosition, isTextNode, emptyEl, normalizeContent, appendContent, insertContent, isSingleLeftClick, $, $$, computedStyle, copyStyleSheetsToWindow }); var _windowLoaded = false; var videojs$1; var autoSetup = function() { if (videojs$1.options.autoSetup === false) { return; } const vids = Array.prototype.slice.call(import_document.default.getElementsByTagName("video")); const audios = Array.prototype.slice.call(import_document.default.getElementsByTagName("audio")); const divs = Array.prototype.slice.call(import_document.default.getElementsByTagName("video-js")); const mediaEls = vids.concat(audios, divs); if (mediaEls && mediaEls.length > 0) { for (let i = 0, e = mediaEls.length; i < e; i++) { const mediaEl = mediaEls[i]; if (mediaEl && mediaEl.getAttribute) { if (mediaEl.player === void 0) { const options = mediaEl.getAttribute("data-setup"); if (options !== null) { videojs$1(mediaEl); } } } else { autoSetupTimeout(1); break; } } } else if (!_windowLoaded) { autoSetupTimeout(1); } }; function autoSetupTimeout(wait, vjs) { if (!isReal()) { return; } if (vjs) { videojs$1 = vjs; } import_window6.default.setTimeout(autoSetup, wait); } function setWindowLoaded() { _windowLoaded = true; import_window6.default.removeEventListener("load", setWindowLoaded); } if (isReal()) { if (import_document.default.readyState === "complete") { setWindowLoaded(); } else { import_window6.default.addEventListener("load", setWindowLoaded); } } var createStyleElement = function(className) { const style = import_document.default.createElement("style"); style.className = className; return style; }; var setTextContent = function(el, content) { if (el.styleSheet) { el.styleSheet.cssText = content; } else { el.textContent = content; } }; var DomData = /* @__PURE__ */ new WeakMap(); var _initialGuid = 3; var _guid = _initialGuid; function newGUID() { return _guid++; } function _cleanUpEvents(elem, type) { if (!DomData.has(elem)) { return; } const data = DomData.get(elem); if (data.handlers[type].length === 0) { delete data.handlers[type]; if (elem.removeEventListener) { elem.removeEventListener(type, data.dispatcher, false); } else if (elem.detachEvent) { elem.detachEvent("on" + type, data.dispatcher); } } if (Object.getOwnPropertyNames(data.handlers).length <= 0) { delete data.handlers; delete data.dispatcher; delete data.disabled; } if (Object.getOwnPropertyNames(data).length === 0) { DomData.delete(elem); } } function _handleMultipleEvents(fn, elem, types, callback) { types.forEach(function(type) { fn(elem, type, callback); }); } function fixEvent(event) { if (event.fixed_) { return event; } function returnTrue() { return true; } function returnFalse() { return false; } if (!event || !event.isPropagationStopped || !event.isImmediatePropagationStopped) { const old = event || import_window6.default.event; event = {}; const deprecatedProps = ["layerX", "layerY", "keyLocation", "path", "webkitMovementX", "webkitMovementY", "mozPressure", "mozInputSource"]; for (const key in old) { if (!deprecatedProps.includes(key)) { if (!(key === "returnValue" && old.preventDefault)) { event[key] = old[key]; } } } if (!event.target) { event.target = event.srcElement || import_document.default; } if (!event.relatedTarget) { event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; } event.preventDefault = function() { if (old.preventDefault) { old.preventDefault(); } event.returnValue = false; old.returnValue = false; event.defaultPrevented = true; }; event.defaultPrevented = false; event.stopPropagation = function() { if (old.stopPropagation) { old.stopPropagation(); } event.cancelBubble = true; old.cancelBubble = true; event.isPropagationStopped = returnTrue; }; event.isPropagationStopped = returnFalse; event.stopImmediatePropagation = function() { if (old.stopImmediatePropagation) { old.stopImmediatePropagation(); } event.isImmediatePropagationStopped = returnTrue; event.stopPropagation(); }; event.isImmediatePropagationStopped = returnFalse; if (event.clientX !== null && event.clientX !== void 0) { const doc = import_document.default.documentElement; const body = import_document.default.body; event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); } event.which = event.charCode || event.keyCode; if (event.button !== null && event.button !== void 0) { event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0; } } event.fixed_ = true; return event; } var _supportsPassive; var supportsPassive = function() { if (typeof _supportsPassive !== "boolean") { _supportsPassive = false; try { const opts = Object.defineProperty({}, "passive", { get() { _supportsPassive = true; } }); import_window6.default.addEventListener("test", null, opts); import_window6.default.removeEventListener("test", null, opts); } catch (e) { } } return _supportsPassive; }; var passiveEvents = ["touchstart", "touchmove"]; function on(elem, type, fn) { if (Array.isArray(type)) { return _handleMultipleEvents(on, elem, type, fn); } if (!DomData.has(elem)) { DomData.set(elem, {}); } const data = DomData.get(elem); if (!data.handlers) { data.handlers = {}; } if (!data.handlers[type]) { data.handlers[type] = []; } if (!fn.guid) { fn.guid = newGUID(); } data.handlers[type].push(fn); if (!data.dispatcher) { data.disabled = false; data.dispatcher = function(event, hash) { if (data.disabled) { return; } event = fixEvent(event); const handlers = data.handlers[event.type]; if (handlers) { const handlersCopy = handlers.slice(0); for (let m = 0, n = handlersCopy.length; m < n; m++) { if (event.isImmediatePropagationStopped()) { break; } else { try { handlersCopy[m].call(elem, event, hash); } catch (e) { log$1.error(e); } } } } }; } if (data.handlers[type].length === 1) { if (elem.addEventListener) { let options = false; if (supportsPassive() && passiveEvents.indexOf(type) > -1) { options = { passive: true }; } elem.addEventListener(type, data.dispatcher, options); } else if (elem.attachEvent) { elem.attachEvent("on" + type, data.dispatcher); } } } function off(elem, type, fn) { if (!DomData.has(elem)) { return; } const data = DomData.get(elem); if (!data.handlers) { return; } if (Array.isArray(type)) { return _handleMultipleEvents(off, elem, type, fn); } const removeType = function(el, t) { data.handlers[t] = []; _cleanUpEvents(el, t); }; if (type === void 0) { for (const t in data.handlers) { if (Object.prototype.hasOwnProperty.call(data.handlers || {}, t)) { removeType(elem, t); } } return; } const handlers = data.handlers[type]; if (!handlers) { return; } if (!fn) { removeType(elem, type); return; } if (fn.guid) { for (let n = 0; n < handlers.length; n++) { if (handlers[n].guid === fn.guid) { handlers.splice(n--, 1); } } } _cleanUpEvents(elem, type); } function trigger(elem, event, hash) { const elemData = DomData.has(elem) ? DomData.get(elem) : {}; const parent = elem.parentNode || elem.ownerDocument; if (typeof event === "string") { event = { type: event, target: elem }; } else if (!event.target) { event.target = elem; } event = fixEvent(event); if (elemData.dispatcher) { elemData.dispatcher.call(elem, event, hash); } if (parent && !event.isPropagationStopped() && event.bubbles === true) { trigger.call(null, parent, event, hash); } else if (!parent && !event.defaultPrevented && event.target && event.target[event.type]) { if (!DomData.has(event.target)) { DomData.set(event.target, {}); } const targetData = DomData.get(event.target); if (event.target[event.type]) { targetData.disabled = true; if (typeof event.target[event.type] === "function") { event.target[event.type](); } targetData.disabled = false; } } return !event.defaultPrevented; } function one(elem, type, fn) { if (Array.isArray(type)) { return _handleMultipleEvents(one, elem, type, fn); } const func = function() { off(elem, type, func); fn.apply(this, arguments); }; func.guid = fn.guid = fn.guid || newGUID(); on(elem, type, func); } function any(elem, type, fn) { const func = function() { off(elem, type, func); fn.apply(this, arguments); }; func.guid = fn.guid = fn.guid || newGUID(); on(elem, type, func); } var Events = Object.freeze({ __proto__: null, fixEvent, on, off, trigger, one, any }); var UPDATE_REFRESH_INTERVAL = 30; var bind_ = function(context, fn, uid) { if (!fn.guid) { fn.guid = newGUID(); } const bound = fn.bind(context); bound.guid = uid ? uid + "_" + fn.guid : fn.guid; return bound; }; var throttle = function(fn, wait) { let last = import_window6.default.performance.now(); const throttled = function(...args) { const now = import_window6.default.performance.now(); if (now - last >= wait) { fn(...args); last = now; } }; return throttled; }; var debounce$1 = function(func, wait, immediate, context = import_window6.default) { let timeout; const cancel = () => { context.clearTimeout(timeout); timeout = null; }; const debounced = function() { const self2 = this; const args = arguments; let later = function() { timeout = null; later = null; if (!immediate) { func.apply(self2, args); } }; if (!timeout && immediate) { func.apply(self2, args); } context.clearTimeout(timeout); timeout = context.setTimeout(later, wait); }; debounced.cancel = cancel; return debounced; }; var Fn = Object.freeze({ __proto__: null, UPDATE_REFRESH_INTERVAL, bind_, throttle, debounce: debounce$1 }); var EVENT_MAP; var EventTarget$2 = class { /** * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a * function that will get called when an event with a certain name gets triggered. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} fn * The function to call with `EventTarget`s */ on(type, fn) { const ael = this.addEventListener; this.addEventListener = () => { }; on(this, type, fn); this.addEventListener = ael; } /** * Removes an `event listener` for a specific event from an instance of `EventTarget`. * This makes it so that the `event listener` will no longer get called when the * named event happens. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} fn * The function to remove. */ off(type, fn) { off(this, type, fn); } /** * This function will add an `event listener` that gets triggered only once. After the * first trigger it will get removed. This is like adding an `event listener` * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} fn * The function to be called once for each event name. */ one(type, fn) { const ael = this.addEventListener; this.addEventListener = () => { }; one(this, type, fn); this.addEventListener = ael; } /** * This function will add an `event listener` that gets triggered only once and is * removed from all events. This is like adding an array of `event listener`s * with {@link EventTarget#on} that calls {@link EventTarget#off} on all events the * first time it is triggered. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} fn * The function to be called once for each event name. */ any(type, fn) { const ael = this.addEventListener; this.addEventListener = () => { }; any(this, type, fn); this.addEventListener = ael; } /** * This function causes an event to happen. This will then cause any `event listeners` * that are waiting for that event, to get called. If there are no `event listeners` * for an event then nothing will happen. * * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`. * Trigger will also call the `on` + `uppercaseEventName` function. * * Example: * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call * `onClick` if it exists. * * @param {string|EventTarget~Event|Object} event * The name of the event, an `Event`, or an object with a key of type set to * an event name. */ trigger(event) { const type = event.type || event; if (typeof event === "string") { event = { type }; } event = fixEvent(event); if (this.allowedEvents_[type] && this["on" + type]) { this["on" + type](event); } trigger(this, event); } queueTrigger(event) { if (!EVENT_MAP) { EVENT_MAP = /* @__PURE__ */ new Map(); } const type = event.type || event; let map = EVENT_MAP.get(this); if (!map) { map = /* @__PURE__ */ new Map(); EVENT_MAP.set(this, map); } const oldTimeout = map.get(type); map.delete(type); import_window6.default.clearTimeout(oldTimeout); const timeout = import_window6.default.setTimeout(() => { map.delete(type); if (map.size === 0) { map = null; EVENT_MAP.delete(this); } this.trigger(event); }, 0); map.set(type, timeout); } }; EventTarget$2.prototype.allowedEvents_ = {}; EventTarget$2.prototype.addEventListener = EventTarget$2.prototype.on; EventTarget$2.prototype.removeEventListener = EventTarget$2.prototype.off; EventTarget$2.prototype.dispatchEvent = EventTarget$2.prototype.trigger; var objName = (obj) => { if (typeof obj.name === "function") { return obj.name(); } if (typeof obj.name === "string") { return obj.name; } if (obj.name_) { return obj.name_; } if (obj.constructor && obj.constructor.name) { return obj.constructor.name; } return typeof obj; }; var isEvented = (object) => object instanceof EventTarget$2 || !!object.eventBusEl_ && ["on", "one", "off", "trigger"].every((k) => typeof object[k] === "function"); var addEventedCallback = (target, callback) => { if (isEvented(target)) { callback(); } else { if (!target.eventedCallbacks) { target.eventedCallbacks = []; } target.eventedCallbacks.push(callback); } }; var isValidEventType = (type) => ( // The regex here verifies that the `type` contains at least one non- // whitespace character. typeof type === "string" && /\S/.test(type) || Array.isArray(type) && !!type.length ); var validateTarget = (target, obj, fnName) => { if (!target || !target.nodeName && !isEvented(target)) { throw new Error(`Invalid target for ${objName(obj)}#${fnName}; must be a DOM node or evented object.`); } }; var validateEventType = (type, obj, fnName) => { if (!isValidEventType(type)) { throw new Error(`Invalid event type for ${objName(obj)}#${fnName}; must be a non-empty string or array.`); } }; var validateListener = (listener, obj, fnName) => { if (typeof listener !== "function") { throw new Error(`Invalid listener for ${objName(obj)}#${fnName}; must be a function.`); } }; var normalizeListenArgs = (self2, args, fnName) => { const isTargetingSelf = args.length < 3 || args[0] === self2 || args[0] === self2.eventBusEl_; let target; let type; let listener; if (isTargetingSelf) { target = self2.eventBusEl_; if (args.length >= 3) { args.shift(); } [type, listener] = args; } else { target = args[0]; type = args[1]; listener = args[2]; } validateTarget(target, self2, fnName); validateEventType(type, self2, fnName); validateListener(listener, self2, fnName); listener = bind_(self2, listener); return { isTargetingSelf, target, type, listener }; }; var listen = (target, method, type, listener) => { validateTarget(target, target, method); if (target.nodeName) { Events[method](target, type, listener); } else { target[method](type, listener); } }; var EventedMixin = { /** * Add a listener to an event (or events) on this object or another evented * object. * * @param {string|Array|Element|Object} targetOrType * If this is a string or array, it represents the event type(s) * that will trigger the listener. * * Another evented object can be passed here instead, which will * cause the listener to listen for events on _that_ object. * * In either case, the listener's `this` value will be bound to * this object. * * @param {string|Array|Function} typeOrListener * If the first argument was a string or array, this should be the * listener function. Otherwise, this is a string or array of event * type(s). * * @param {Function} [listener] * If the first argument was another evented object, this will be * the listener function. */ on(...args) { const { isTargetingSelf, target, type, listener } = normalizeListenArgs(this, args, "on"); listen(target, "on", type, listener); if (!isTargetingSelf) { const removeListenerOnDispose = () => this.off(target, type, listener); removeListenerOnDispose.guid = listener.guid; const removeRemoverOnTargetDispose = () => this.off("dispose", removeListenerOnDispose); removeRemoverOnTargetDispose.guid = listener.guid; listen(this, "on", "dispose", removeListenerOnDispose); listen(target, "on", "dispose", removeRemoverOnTargetDispose); } }, /** * Add a listener to an event (or events) on this object or another evented * object. The listener will be called once per event and then removed. * * @param {string|Array|Element|Object} targetOrType * If this is a string or array, it represents the event type(s) * that will trigger the listener. * * Another evented object can be passed here instead, which will * cause the listener to listen for events on _that_ object. * * In either case, the listener's `this` value will be bound to * this object. * * @param {string|Array|Function} typeOrListener * If the first argument was a string or array, this should be the * listener function. Otherwise, this is a string or array of event * type(s). * * @param {Function} [listener] * If the first argument was another evented object, this will be * the listener function. */ one(...args) { const { isTargetingSelf, target, type, listener } = normalizeListenArgs(this, args, "one"); if (isTargetingSelf) { listen(target, "one", type, listener); } else { const wrapper = (...largs) => { this.off(target, type, wrapper); listener.apply(null, largs); }; wrapper.guid = listener.guid; listen(target, "one", type, wrapper); } }, /** * Add a listener to an event (or events) on this object or another evented * object. The listener will only be called once for the first event that is triggered * then removed. * * @param {string|Array|Element|Object} targetOrType * If this is a string or array, it represents the event type(s) * that will trigger the listener. * * Another evented object can be passed here instead, which will * cause the listener to listen for events on _that_ object. * * In either case, the listener's `this` value will be bound to * this object. * * @param {string|Array|Function} typeOrListener * If the first argument was a string or array, this should be the * listener function. Otherwise, this is a string or array of event * type(s). * * @param {Function} [listener] * If the first argument was another evented object, this will be * the listener function. */ any(...args) { const { isTargetingSelf, target, type, listener } = normalizeListenArgs(this, args, "any"); if (isTargetingSelf) { listen(target, "any", type, listener); } else { const wrapper = (...largs) => { this.off(target, type, wrapper); listener.apply(null, largs); }; wrapper.guid = listener.guid; listen(target, "any", type, wrapper); } }, /** * Removes listener(s) from event(s) on an evented object. * * @param {string|Array|Element|Object} [targetOrType] * If this is a string or array, it represents the event type(s). * * Another evented object can be passed here instead, in which case * ALL 3 arguments are _required_. * * @param {string|Array|Function} [typeOrListener] * If the first argument was a string or array, this may be the * listener function. Otherwise, this is a string or array of event * type(s). * * @param {Function} [listener] * If the first argument was another evented object, this will be * the listener function; otherwise, _all_ listeners bound to the * event type(s) will be removed. */ off(targetOrType, typeOrListener, listener) { if (!targetOrType || isValidEventType(targetOrType)) { off(this.eventBusEl_, targetOrType, typeOrListener); } else { const target = targetOrType; const type = typeOrListener; validateTarget(target, this, "off"); validateEventType(type, this, "off"); validateListener(listener, this, "off"); listener = bind_(this, listener); this.off("dispose", listener); if (target.nodeName) { off(target, type, listener); off(target, "dispose", listener); } else if (isEvented(target)) { target.off(type, listener); target.off("dispose", listener); } } }, /** * Fire an event on this evented object, causing its listeners to be called. * * @param {string|Object} event * An event type or an object with a type property. * * @param {Object} [hash] * An additional object to pass along to listeners. * * @return {boolean} * Whether or not the default behavior was prevented. */ trigger(event, hash) { validateTarget(this.eventBusEl_, this, "trigger"); const type = event && typeof event !== "string" ? event.type : event; if (!isValidEventType(type)) { throw new Error(`Invalid event type for ${objName(this)}#trigger; must be a non-empty string or object with a type key that has a non-empty value.`); } return trigger(this.eventBusEl_, event, hash); } }; function evented(target, options = {}) { const { eventBusKey } = options; if (eventBusKey) { if (!target[eventBusKey].nodeName) { throw new Error(`The eventBusKey "${eventBusKey}" does not refer to an element.`); } target.eventBusEl_ = target[eventBusKey]; } else { target.eventBusEl_ = createEl("span", { className: "vjs-event-bus" }); } Object.assign(target, EventedMixin); if (target.eventedCallbacks) { target.eventedCallbacks.forEach((callback) => { callback(); }); } target.on("dispose", () => { target.off(); [target, target.el_, target.eventBusEl_].forEach(function(val) { if (val && DomData.has(val)) { DomData.delete(val); } }); import_window6.default.setTimeout(() => { target.eventBusEl_ = null; }, 0); }); return target; } var StatefulMixin = { /** * A hash containing arbitrary keys and values representing the state of * the object. * * @type {Object} */ state: {}, /** * Set the state of an object by mutating its * {@link module:stateful~StatefulMixin.state|state} object in place. * * @fires module:stateful~StatefulMixin#statechanged * @param {Object|Function} stateUpdates * A new set of properties to shallow-merge into the plugin state. * Can be a plain object or a function returning a plain object. * * @return {Object|undefined} * An object containing changes that occurred. If no changes * occurred, returns `undefined`. */ setState(stateUpdates) { if (typeof stateUpdates === "function") { stateUpdates = stateUpdates(); } let changes; each(stateUpdates, (value, key) => { if (this.state[key] !== value) { changes = changes || {}; changes[key] = { from: this.state[key], to: value }; } this.state[key] = value; }); if (changes && isEvented(this)) { this.trigger({ changes, type: "statechanged" }); } return changes; } }; function stateful(target, defaultState) { Object.assign(target, StatefulMixin); target.state = Object.assign({}, target.state, defaultState); if (typeof target.handleStateChanged === "function" && isEvented(target)) { target.on("statechanged", target.handleStateChanged); } return target; } var toLowerCase = function(string) { if (typeof string !== "string") { return string; } return string.replace(/./, (w) => w.toLowerCase()); }; var toTitleCase$1 = function(string) { if (typeof string !== "string") { return string; } return string.replace(/./, (w) => w.toUpperCase()); }; var titleCaseEquals = function(str1, str2) { return toTitleCase$1(str1) === toTitleCase$1(str2); }; var Str = Object.freeze({ __proto__: null, toLowerCase, toTitleCase: toTitleCase$1, titleCaseEquals }); var Component$1 = class _Component$1 { /** * Creates an instance of this class. * * @param {Player} player * The `Player` that this class should be attached to. * * @param {Object} [options] * The key/value store of component options. * * @param {Object[]} [options.children] * An array of children objects to initialize this component with. Children objects have * a name property that will be used if more than one component of the same type needs to be * added. * * @param {string} [options.className] * A class or space separated list of classes to add the component * * @param {ReadyCallback} [ready] * Function that gets called when the `Component` is ready. */ constructor(player, options, ready) { if (!player && this.play) { this.player_ = player = this; } else { this.player_ = player; } this.isDisposed_ = false; this.parentComponent_ = null; this.options_ = merge$1({}, this.options_); options = this.options_ = merge$1(this.options_, options); this.id_ = options.id || options.el && options.el.id; if (!this.id_) { const id = player && player.id && player.id() || "no_player"; this.id_ = `${id}_component_${newGUID()}`; } this.name_ = options.name || null; if (options.el) { this.el_ = options.el; } else if (options.createEl !== false) { this.el_ = this.createEl(); } if (options.className && this.el_) { options.className.split(" ").forEach((c) => this.addClass(c)); } ["on", "off", "one", "any", "trigger"].forEach((fn) => { this[fn] = void 0; }); if (options.evented !== false) { evented(this, { eventBusKey: this.el_ ? "el_" : null }); this.handleLanguagechange = this.handleLanguagechange.bind(this); this.on(this.player_, "languagechange", this.handleLanguagechange); } stateful(this, this.constructor.defaultState); this.children_ = []; this.childIndex_ = {}; this.childNameIndex_ = {}; this.setTimeoutIds_ = /* @__PURE__ */ new Set(); this.setIntervalIds_ = /* @__PURE__ */ new Set(); this.rafIds_ = /* @__PURE__ */ new Set(); this.namedRafs_ = /* @__PURE__ */ new Map(); this.clearingTimersOnDispose_ = false; if (options.initChildren !== false) { this.initChildren(); } this.ready(ready); if (options.reportTouchActivity !== false) { this.enableTouchActivity(); } } // `on`, `off`, `one`, `any` and `trigger` are here so tsc includes them in definitions. // They are replaced or removed in the constructor /** * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a * function that will get called when an event with a certain name gets triggered. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} fn * The function to call with `EventTarget`s */ /** * Removes an `event listener` for a specific event from an instance of `EventTarget`. * This makes it so that the `event listener` will no longer get called when the * named event happens. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} [fn] * The function to remove. If not specified, all listeners managed by Video.js will be removed. */ /** * This function will add an `event listener` that gets triggered only once. After the * first trigger it will get removed. This is like adding an `event listener` * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} fn * The function to be called once for each event name. */ /** * This function will add an `event listener` that gets triggered only once and is * removed from all events. This is like adding an array of `event listener`s * with {@link EventTarget#on} that calls {@link EventTarget#off} on all events the * first time it is triggered. * * @param {string|string[]} type * An event name or an array of event names. * * @param {Function} fn * The function to be called once for each event name. */ /** * This function causes an event to happen. This will then cause any `event listeners` * that are waiting for that event, to get called. If there are no `event listeners` * for an event then nothing will happen. * * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`. * Trigger will also call the `on` + `uppercaseEventName` function. * * Example: * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call * `onClick` if it exists. * * @param {string|Event|Object} event * The name of the event, an `Event`, or an object with a key of type set to * an event name. * * @param {Object} [hash] * Optionally extra argument to pass through to an event listener */ /** * Dispose of the `Component` and all child components. * * @fires Component#dispose * * @param {Object} options * @param {Element} options.originalEl element with which to replace player element */ dispose(options = {}) { if (this.isDisposed_) { return; } if (this.readyQueue_) { this.readyQueue_.length = 0; } this.trigger({ type: "dispose", bubbles: false }); this.isDisposed_ = true; if (this.children_) { for (let i = this.children_.length - 1; i >= 0; i--) { if (this.children_[i].dispose) { this.children_[i].dispose(); } } } this.children_ = null; this.childIndex_ = null; this.childNameIndex_ = null; this.parentComponent_ = null; if (this.el_) { if (this.el_.parentNode) { if (options.restoreEl) { this.el_.parentNode.replaceChild(options.restoreEl, this.el_); } else { this.el_.parentNode.removeChild(this.el_); } } this.el_ = null; } this.player_ = null; } /** * Determine whether or not this component has been disposed. * * @return {boolean} * If the component has been disposed, will be `true`. Otherwise, `false`. */ isDisposed() { return Boolean(this.isDisposed_); } /** * Return the {@link Player} that the `Component` has attached to. * * @return {Player} * The player that this `Component` has attached to. */ player() { return this.player_; } /** * Deep merge of options objects with new options. * > Note: When both `obj` and `options` contain properties whose values are objects. * The two properties get merged using {@link module:obj.merge} * * @param {Object} obj * The object that contains new options. * * @return {Object} * A new object of `this.options_` and `obj` merged together. */ options(obj) { if (!obj) { return this.options_; } this.options_ = merge$1(this.options_, obj); return this.options_; } /** * Get the `Component`s DOM element * * @return {Element} * The DOM element for this `Component`. */ el() { return this.el_; } /** * Create the `Component`s DOM element. * * @param {string} [tagName] * Element's DOM node type. e.g. 'div' * * @param {Object} [properties] * An object of properties that should be set. * * @param {Object} [attributes] * An object of attributes that should be set. * * @return {Element} * The element that gets created. */ createEl(tagName, properties, attributes) { return createEl(tagName, properties, attributes); } /** * Localize a string given the string in english. * * If tokens are provided, it'll try and run a simple token replacement on the provided string. * The tokens it looks for look like `{1}` with the index being 1-indexed into the tokens array. * * If a `defaultValue` is provided, it'll use that over `string`, * if a value isn't found in provided language files. * This is useful if you want to have a descriptive key for token replacement * but have a succinct localized string and not require `en.json` to be included. * * Currently, it is used for the progress bar timing. * ```js * { * "progress bar timing: currentTime={1} duration={2}": "{1} of {2}" * } * ``` * It is then used like so: * ```js * this.localize('progress bar timing: currentTime={1} duration{2}', * [this.player_.currentTime(), this.player_.duration()], * '{1} of {2}'); * ``` * * Which outputs something like: `01:23 of 24:56`. * * * @param {string} string * The string to localize and the key to lookup in the language files. * @param {string[]} [tokens] * If the current item has token replacements, provide the tokens here. * @param {string} [defaultValue] * Defaults to `string`. Can be a default value to use for token replacement * if the lookup key is needed to be separate. * * @return {string} * The localized string or if no localization exists the english string. */ localize(string, tokens, defaultValue = string) { const code = this.player_.language && this.player_.language(); const languages = this.player_.languages && this.player_.languages(); const language = languages && languages[code]; const primaryCode = code && code.split("-")[0]; const primaryLang = languages && languages[primaryCode]; let localizedString = defaultValue; if (language && language[string]) { localizedString = language[string]; } else if (primaryLang && primaryLang[string]) { localizedString = primaryLang[string]; } if (tokens) { localizedString = localizedString.replace(/\{(\d+)\}/g, function(match, index) { const value = tokens[index - 1]; let ret = value; if (typeof value === "undefined") { ret = match; } return ret; }); } return localizedString; } /** * Handles language change for the player in components. Should be overridden by sub-components. * * @abstract */ handleLanguagechange() { } /** * Return the `Component`s DOM element. This is where children get inserted. * This will usually be the the same as the element returned in {@link Component#el}. * * @return {Element} * The content element for this `Component`. */ contentEl() { return this.contentEl_ || this.el_; } /** * Get this `Component`s ID * * @return {string} * The id of this `Component` */ id() { return this.id_; } /** * Get the `Component`s name. The name gets used to reference the `Component` * and is set during registration. * * @return {string} * The name of this `Component`. */ name() { return this.name_; } /** * Get an array of all child components * * @return {Array} * The children */ children() { return this.children_; } /** * Returns the child `Component` with the given `id`. * * @param {string} id * The id of the child `Component` to get. * * @return {Component|undefined} * The child `Component` with the given `id` or undefined. */ getChildById(id) { return this.childIndex_[id]; } /** * Returns the child `Component` with the given `name`. * * @param {string} name * The name of the child `Component` to get. * * @return {Component|undefined} * The child `Component` with the given `name` or undefined. */ getChild(name) { if (!name) { return; } return this.childNameIndex_[name]; } /** * Returns the descendant `Component` following the givent * descendant `names`. For instance ['foo', 'bar', 'baz'] would * try to get 'foo' on the current component, 'bar' on the 'foo' * component and 'baz' on the 'bar' component and return undefined * if any of those don't exist. * * @param {...string[]|...string} names * The name of the child `Component` to get. * * @return {Component|undefined} * The descendant `Component` following the given descendant * `names` or undefined. */ getDescendant(...names) { names = names.reduce((acc, n) => acc.concat(n), []); let currentChild = this; for (let i = 0; i < names.length; i++) { currentChild = currentChild.getChild(names[i]); if (!currentChild || !currentChild.getChild) { return; } } return currentChild; } /** * Adds an SVG icon element to another element or component. * * @param {string} iconName * The name of icon. A list of all the icon names can be found at 'sandbox/svg-icons.html' * * @param {Element} [el=this.el()] * Element to set the title on. Defaults to the current Component's element. * * @return {Element} * The newly created icon element. */ setIcon(iconName, el = this.el()) { if (!this.player_.options_.experimentalSvgIcons) { return; } const xmlnsURL = "http://www.w3.org/2000/svg"; const iconContainer = createEl("span", { className: "vjs-icon-placeholder vjs-svg-icon" }, { "aria-hidden": "true" }); const svgEl = import_document.default.createElementNS(xmlnsURL, "svg"); svgEl.setAttributeNS(null, "viewBox", "0 0 512 512"); const useEl = import_document.default.createElementNS(xmlnsURL, "use"); svgEl.appendChild(useEl); useEl.setAttributeNS(null, "href", `#vjs-icon-${iconName}`); iconContainer.appendChild(svgEl); if (this.iconIsSet_) { el.replaceChild(iconContainer, el.querySelector(".vjs-icon-placeholder")); } else { el.appendChild(iconContainer); } this.iconIsSet_ = true; return iconContainer; } /** * Add a child `Component` inside the current `Component`. * * @param {string|Component} child * The name or instance of a child to add. * * @param {Object} [options={}] * The key/value store of options that will get passed to children of * the child. * * @param {number} [index=this.children_.length] * The index to attempt to add a child into. * * * @return {Component} * The `Component` that gets added as a child. When using a string the * `Component` will get created by this process. */ addChild(child, options = {}, index = this.children_.length) { let component; let componentName; if (typeof child === "string") { componentName = toTitleCase$1(child); const componentClassName = options.componentClass || componentName; options.name = componentName; const ComponentClass = _Component$1.getComponent(componentClassName); if (!ComponentClass) { throw new Error(`Component ${componentClassName} does not exist`); } if (typeof ComponentClass !== "function") { return null; } component = new ComponentClass(this.player_ || this, options); } else { component = child; } if (component.parentComponent_) { component.parentComponent_.removeChild(component); } this.children_.splice(index, 0, component); component.parentComponent_ = this; if (typeof component.id === "function") { this.childIndex_[component.id()] = component; } componentName = componentName || component.name && toTitleCase$1(component.name()); if (componentName) { this.childNameIndex_[componentName] = component; this.childNameIndex_[toLowerCase(componentName)] = component; } if (typeof component.el === "function" && component.el()) { let refNode = null; if (this.children_[index + 1]) { if (this.children_[index + 1].el_) { refNode = this.children_[index + 1].el_; } else if (isEl(this.children_[index + 1])) { refNode = this.children_[index + 1]; } } this.contentEl().insertBefore(component.el(), refNode); } return component; } /** * Remove a child `Component` from this `Component`s list of children. Also removes * the child `Component`s element from this `Component`s element. * * @param {Component} component * The child `Component` to remove. */ removeChild(component) { if (typeof component === "string") { component = this.getChild(component); } if (!component || !this.children_) { return; } let childFound = false; for (let i = this.children_.length - 1; i >= 0; i--) { if (this.children_[i] === component) { childFound = true; this.children_.splice(i, 1); break; } } if (!childFound) { return; } component.parentComponent_ = null; this.childIndex_[component.id()] = null; this.childNameIndex_[toTitleCase$1(component.name())] = null; this.childNameIndex_[toLowerCase(component.name())] = null; const compEl = component.el(); if (compEl && compEl.parentNode === this.contentEl()) { this.contentEl().removeChild(component.el()); } } /** * Add and initialize default child `Component`s based upon options. */ initChildren() { const children = this.options_.children; if (children) { const parentOptions = this.options_; const handleAdd = (child) => { const name = child.name; let opts = child.opts; if (parentOptions[name] !== void 0) { opts = parentOptions[name]; } if (opts === false) { return; } if (opts === true) { opts = {}; } opts.playerOptions = this.options_.playerOptions; const newChild = this.addChild(name, opts); if (newChild) { this[name] = newChild; } }; let workingChildren; const Tech2 = _Component$1.getComponent("Tech"); if (Array.isArray(children)) { workingChildren = children; } else { workingChildren = Object.keys(children); } workingChildren.concat(Object.keys(this.options_).filter(function(child) { return !workingChildren.some(function(wchild) { if (typeof wchild === "string") { return child === wchild; } return child === wchild.name; }); })).map((child) => { let name; let opts; if (typeof child === "string") { name = child; opts = children[name] || this.options_[name] || {}; } else { name = child.name; opts = child; } return { name, opts }; }).filter((child) => { const c = _Component$1.getComponent(child.opts.componentClass || toTitleCase$1(child.name)); return c && !Tech2.isTech(c); }).forEach(handleAdd); } } /** * Builds the default DOM class name. Should be overridden by sub-components. * * @return {string} * The DOM class name for this object. * * @abstract */ buildCSSClass() { return ""; } /** * Bind a listener to the component's ready state. * Different from event listeners in that if the ready event has already happened * it will trigger the function immediately. * * @param {ReadyCallback} fn * Function that gets called when the `Component` is ready. */ ready(fn, sync = false) { if (!fn) { return; } if (!this.isReady_) { this.readyQueue_ = this.readyQueue_ || []; this.readyQueue_.push(fn); return; } if (sync) { fn.call(this); } else { this.setTimeout(fn, 1); } } /** * Trigger all the ready listeners for this `Component`. * * @fires Component#ready */ triggerReady() { this.isReady_ = true; this.setTimeout(function() { const readyQueue = this.readyQueue_; this.readyQueue_ = []; if (readyQueue && readyQueue.length > 0) { readyQueue.forEach(function(fn) { fn.call(this); }, this); } this.trigger("ready"); }, 1); } /** * Find a single DOM element matching a `selector`. This can be within the `Component`s * `contentEl()` or another custom context. * * @param {string} selector * A valid CSS selector, which will be passed to `querySelector`. * * @param {Element|string} [context=this.contentEl()] * A DOM element within which to query. Can also be a selector string in * which case the first matching element will get used as context. If * missing `this.contentEl()` gets used. If `this.contentEl()` returns * nothing it falls back to `document`. * * @return {Element|null} * the dom element that was found, or null * * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors) */ $(selector, context) { return $(selector, context || this.contentEl()); } /** * Finds all DOM element matching a `selector`. This can be within the `Component`s * `contentEl()` or another custom context. * * @param {string} selector * A valid CSS selector, which will be passed to `querySelectorAll`. * * @param {Element|string} [context=this.contentEl()] * A DOM element within which to query. Can also be a selector string in * which case the first matching element will get used as context. If * missing `this.contentEl()` gets used. If `this.contentEl()` returns * nothing it falls back to `document`. * * @return {NodeList} * a list of dom elements that were found * * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors) */ $$(selector, context) { return $$(selector, context || this.contentEl()); } /** * Check if a component's element has a CSS class name. * * @param {string} classToCheck * CSS class name to check. * * @return {boolean} * - True if the `Component` has the class. * - False if the `Component` does not have the class` */ hasClass(classToCheck) { return hasClass(this.el_, classToCheck); } /** * Add a CSS class name to the `Component`s element. * * @param {...string} classesToAdd * One or more CSS class name to add. */ addClass(...classesToAdd) { addClass(this.el_, ...classesToAdd); } /** * Remove a CSS class name from the `Component`s element. * * @param {...string} classesToRemove * One or more CSS class name to remove. */ removeClass(...classesToRemove) { removeClass(this.el_, ...classesToRemove); } /** * Add or remove a CSS class name from the component's element. * - `classToToggle` gets added when {@link Component#hasClass} would return false. * - `classToToggle` gets removed when {@link Component#hasClass} would return true. * * @param {string} classToToggle * The class to add or remove. Passed to DOMTokenList's toggle() * * @param {boolean|Dom.PredicateCallback} [predicate] * A boolean or function that returns a boolean. Passed to DOMTokenList's toggle(). */ toggleClass(classToToggle, predicate) { toggleClass(this.el_, classToToggle, predicate); } /** * Show the `Component`s element if it is hidden by removing the * 'vjs-hidden' class name from it. */ show() { this.removeClass("vjs-hidden"); } /** * Hide the `Component`s element if it is currently showing by adding the * 'vjs-hidden` class name to it. */ hide() { this.addClass("vjs-hidden"); } /** * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing' * class name to it. Used during fadeIn/fadeOut. * * @private */ lockShowing() { this.addClass("vjs-lock-showing"); } /** * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing' * class name from it. Used during fadeIn/fadeOut. * * @private */ unlockShowing() { this.removeClass("vjs-lock-showing"); } /** * Get the value of an attribute on the `Component`s element. * * @param {string} attribute * Name of the attribute to get the value from. * * @return {string|null} * - The value of the attribute that was asked for. * - Can be an empty string on some browsers if the attribute does not exist * or has no value * - Most browsers will return null if the attribute does not exist or has * no value. * * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute} */ getAttribute(attribute) { return getAttribute(this.el_, attribute); } /** * Set the value of an attribute on the `Component`'s element * * @param {string} attribute * Name of the attribute to set. * * @param {string} value * Value to set the attribute to. * * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute} */ setAttribute(attribute, value) { setAttribute(this.el_, attribute, value); } /** * Remove an attribute from the `Component`s element. * * @param {string} attribute * Name of the attribute to remove. * * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute} */ removeAttribute(attribute) { removeAttribute(this.el_, attribute); } /** * Get or set the width of the component based upon the CSS styles. * See {@link Component#dimension} for more detailed information. * * @param {number|string} [num] * The width that you want to set postfixed with '%', 'px' or nothing. * * @param {boolean} [skipListeners] * Skip the componentresize event trigger * * @return {number|undefined} * The width when getting, zero if there is no width */ width(num, skipListeners) { return this.dimension("width", num, skipListeners); } /** * Get or set the height of the component based upon the CSS styles. * See {@link Component#dimension} for more detailed information. * * @param {number|string} [num] * The height that you want to set postfixed with '%', 'px' or nothing. * * @param {boolean} [skipListeners] * Skip the componentresize event trigger * * @return {number|undefined} * The height when getting, zero if there is no height */ height(num, skipListeners) { return this.dimension("height", num, skipListeners); } /** * Set both the width and height of the `Component` element at the same time. * * @param {number|string} width * Width to set the `Component`s element to. * * @param {number|string} height * Height to set the `Component`s element to. */ dimensions(width, height) { this.width(width, true); this.height(height); } /** * Get or set width or height of the `Component` element. This is the shared code * for the {@link Component#width} and {@link Component#height}. * * Things to know: * - If the width or height in an number this will return the number postfixed with 'px'. * - If the width/height is a percent this will return the percent postfixed with '%' * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function * defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`. * See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/} * for more information * - If you want the computed style of the component, use {@link Component#currentWidth} * and {@link {Component#currentHeight} * * @fires Component#componentresize * * @param {string} widthOrHeight 8 'width' or 'height' * * @param {number|string} [num] 8 New dimension * * @param {boolean} [skipListeners] * Skip componentresize event trigger * * @return {number|undefined} * The dimension when getting or 0 if unset */ dimension(widthOrHeight, num, skipListeners) { if (num !== void 0) { if (num === null || num !== num) { num = 0; } if (("" + num).indexOf("%") !== -1 || ("" + num).indexOf("px") !== -1) { this.el_.style[widthOrHeight] = num; } else if (num === "auto") { this.el_.style[widthOrHeight] = ""; } else { this.el_.style[widthOrHeight] = num + "px"; } if (!skipListeners) { this.trigger("componentresize"); } return; } if (!this.el_) { return 0; } const val = this.el_.style[widthOrHeight]; const pxIndex = val.indexOf("px"); if (pxIndex !== -1) { return parseInt(val.slice(0, pxIndex), 10); } return parseInt(this.el_["offset" + toTitleCase$1(widthOrHeight)], 10); } /** * Get the computed width or the height of the component's element. * * Uses `window.getComputedStyle`. * * @param {string} widthOrHeight * A string containing 'width' or 'height'. Whichever one you want to get. * * @return {number} * The dimension that gets asked for or 0 if nothing was set * for that dimension. */ currentDimension(widthOrHeight) { let computedWidthOrHeight = 0; if (widthOrHeight !== "width" && widthOrHeight !== "height") { throw new Error("currentDimension only accepts width or height value"); } computedWidthOrHeight = computedStyle(this.el_, widthOrHeight); computedWidthOrHeight = parseFloat(computedWidthOrHeight); if (computedWidthOrHeight === 0 || isNaN(computedWidthOrHeight)) { const rule = `offset${toTitleCase$1(widthOrHeight)}`; computedWidthOrHeight = this.el_[rule]; } return computedWidthOrHeight; } /** * An object that contains width and height values of the `Component`s * computed style. Uses `window.getComputedStyle`. * * @typedef {Object} Component~DimensionObject * * @property {number} width * The width of the `Component`s computed style. * * @property {number} height * The height of the `Component`s computed style. */ /** * Get an object that contains computed width and height values of the * component's element. * * Uses `window.getComputedStyle`. * * @return {Component~DimensionObject} * The computed dimensions of the component's element. */ currentDimensions() { return { width: this.currentDimension("width"), height: this.currentDimension("height") }; } /** * Get the computed width of the component's element. * * Uses `window.getComputedStyle`. * * @return {number} * The computed width of the component's element. */ currentWidth() { return this.currentDimension("width"); } /** * Get the computed height of the component's element. * * Uses `window.getComputedStyle`. * * @return {number} * The computed height of the component's element. */ currentHeight() { return this.currentDimension("height"); } /** * Retrieves the position and size information of the component's element. * * @return {Object} An object with `boundingClientRect` and `center` properties. * - `boundingClientRect`: An object with properties `x`, `y`, `width`, * `height`, `top`, `right`, `bottom`, and `left`, representing * the bounding rectangle of the element. * - `center`: An object with properties `x` and `y`, representing * the center point of the element. `width` and `height` are set to 0. */ getPositions() { const rect = this.el_.getBoundingClientRect(); const boundingClientRect = { x: rect.x, y: rect.y, width: rect.width, height: rect.height, top: rect.top, right: rect.right, bottom: rect.bottom, left: rect.left }; const center = { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2, width: 0, height: 0, top: rect.top + rect.height / 2, right: rect.left + rect.width / 2, bottom: rect.top + rect.height / 2, left: rect.left + rect.width / 2 }; return { boundingClientRect, center }; } /** * Set the focus to this component */ focus() { this.el_.focus(); } /** * Remove the focus from this component */ blur() { this.el_.blur(); } /** * When this Component receives a `keydown` event which it does not process, * it passes the event to the Player for handling. * * @param {KeyboardEvent} event * The `keydown` event that caused this function to be called. */ handleKeyDown(event) { if (this.player_) { if (event.key !== "Tab" && !(this.player_.options_.playerOptions.spatialNavigation && this.player_.options_.playerOptions.spatialNavigation.enabled)) { event.stopPropagation(); } this.player_.handleKeyDown(event); } } /** * Many components used to have a `handleKeyPress` method, which was poorly * named because it listened to a `keydown` event. This method name now * delegates to `handleKeyDown`. This means anyone calling `handleKeyPress` * will not see their method calls stop working. * * @param {KeyboardEvent} event * The event that caused this function to be called. */ handleKeyPress(event) { this.handleKeyDown(event); } /** * Emit a 'tap' events when touch event support gets detected. This gets used to * support toggling the controls through a tap on the video. They get enabled * because every sub-component would have extra overhead otherwise. * * @protected * @fires Component#tap * @listens Component#touchstart * @listens Component#touchmove * @listens Component#touchleave * @listens Component#touchcancel * @listens Component#touchend */ emitTapEvents() { let touchStart = 0; let firstTouch = null; const tapMovementThreshold = 10; const touchTimeThreshold = 200; let couldBeTap; this.on("touchstart", function(event) { if (event.touches.length === 1) { firstTouch = { pageX: event.touches[0].pageX, pageY: event.touches[0].pageY }; touchStart = import_window6.default.performance.now(); couldBeTap = true; } }); this.on("touchmove", function(event) { if (event.touches.length > 1) { couldBeTap = false; } else if (firstTouch) { const xdiff = event.touches[0].pageX - firstTouch.pageX; const ydiff = event.touches[0].pageY - firstTouch.pageY; const touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff); if (touchDistance > tapMovementThreshold) { couldBeTap = false; } } }); const noTap = function() { couldBeTap = false; }; this.on("touchleave", noTap); this.on("touchcancel", noTap); this.on("touchend", function(event) { firstTouch = null; if (couldBeTap === true) { const touchTime = import_window6.default.performance.now() - touchStart; if (touchTime < touchTimeThreshold) { event.preventDefault(); this.trigger("tap"); } } }); } /** * This function reports user activity whenever touch events happen. This can get * turned off by any sub-components that wants touch events to act another way. * * Report user touch activity when touch events occur. User activity gets used to * determine when controls should show/hide. It is simple when it comes to mouse * events, because any mouse event should show the controls. So we capture mouse * events that bubble up to the player and report activity when that happens. * With touch events it isn't as easy as `touchstart` and `touchend` toggle player * controls. So touch events can't help us at the player level either. * * User activity gets checked asynchronously. So what could happen is a tap event * on the video turns the controls off. Then the `touchend` event bubbles up to * the player. Which, if it reported user activity, would turn the controls right * back on. We also don't want to completely block touch events from bubbling up. * Furthermore a `touchmove` event and anything other than a tap, should not turn * controls back on. * * @listens Component#touchstart * @listens Component#touchmove * @listens Component#touchend * @listens Component#touchcancel */ enableTouchActivity() { if (!this.player() || !this.player().reportUserActivity) { return; } const report = bind_(this.player(), this.player().reportUserActivity); let touchHolding; this.on("touchstart", function() { report(); this.clearInterval(touchHolding); touchHolding = this.setInterval(report, 250); }); const touchEnd = function(event) { report(); this.clearInterval(touchHolding); }; this.on("touchmove", report); this.on("touchend", touchEnd); this.on("touchcancel", touchEnd); } /** * A callback that has no parameters and is bound into `Component`s context. * * @callback Component~GenericCallback * @this Component */ /** * Creates a function that runs after an `x` millisecond timeout. This function is a * wrapper around `window.setTimeout`. There are a few reasons to use this one * instead though: * 1. It gets cleared via {@link Component#clearTimeout} when * {@link Component#dispose} gets called. * 2. The function callback will gets turned into a {@link Component~GenericCallback} * * > Note: You can't use `window.clearTimeout` on the id returned by this function. This * will cause its dispose listener not to get cleaned up! Please use * {@link Component#clearTimeout} or {@link Component#dispose} instead. * * @param {Component~GenericCallback} fn * The function that will be run after `timeout`. * * @param {number} timeout * Timeout in milliseconds to delay before executing the specified function. * * @return {number} * Returns a timeout ID that gets used to identify the timeout. It can also * get used in {@link Component#clearTimeout} to clear the timeout that * was set. * * @listens Component#dispose * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout} */ setTimeout(fn, timeout) { var timeoutId; fn = bind_(this, fn); this.clearTimersOnDispose_(); timeoutId = import_window6.default.setTimeout(() => { if (this.setTimeoutIds_.has(timeoutId)) { this.setTimeoutIds_.delete(timeoutId); } fn(); }, timeout); this.setTimeoutIds_.add(timeoutId); return timeoutId; } /** * Clears a timeout that gets created via `window.setTimeout` or * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout} * use this function instead of `window.clearTimout`. If you don't your dispose * listener will not get cleaned up until {@link Component#dispose}! * * @param {number} timeoutId * The id of the timeout to clear. The return value of * {@link Component#setTimeout} or `window.setTimeout`. * * @return {number} * Returns the timeout id that was cleared. * * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout} */ clearTimeout(timeoutId) { if (this.setTimeoutIds_.has(timeoutId)) { this.setTimeoutIds_.delete(timeoutId); import_window6.default.clearTimeout(timeoutId); } return timeoutId; } /** * Creates a function that gets run every `x` milliseconds. This function is a wrapper * around `window.setInterval`. There are a few reasons to use this one instead though. * 1. It gets cleared via {@link Component#clearInterval} when * {@link Component#dispose} gets called. * 2. The function callback will be a {@link Component~GenericCallback} * * @param {Component~GenericCallback} fn * The function to run every `x` seconds. * * @param {number} interval * Execute the specified function every `x` milliseconds. * * @return {number} * Returns an id that can be used to identify the interval. It can also be be used in * {@link Component#clearInterval} to clear the interval. * * @listens Component#dispose * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval} */ setInterval(fn, interval) { fn = bind_(this, fn); this.clearTimersOnDispose_(); const intervalId = import_window6.default.setInterval(fn, interval); this.setIntervalIds_.add(intervalId); return intervalId; } /** * Clears an interval that gets created via `window.setInterval` or * {@link Component#setInterval}. If you set an interval via {@link Component#setInterval} * use this function instead of `window.clearInterval`. If you don't your dispose * listener will not get cleaned up until {@link Component#dispose}! * * @param {number} intervalId * The id of the interval to clear. The return value of * {@link Component#setInterval} or `window.setInterval`. * * @return {number} * Returns the interval id that was cleared. * * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval} */ clearInterval(intervalId) { if (this.setIntervalIds_.has(intervalId)) { this.setIntervalIds_.delete(intervalId); import_window6.default.clearInterval(intervalId); } return intervalId; } /** * Queues up a callback to be passed to requestAnimationFrame (rAF), but * with a few extra bonuses: * * - Supports browsers that do not support rAF by falling back to * {@link Component#setTimeout}. * * - The callback is turned into a {@link Component~GenericCallback} (i.e. * bound to the component). * * - Automatic cancellation of the rAF callback is handled if the component * is disposed before it is called. * * @param {Component~GenericCallback} fn * A function that will be bound to this component and executed just * before the browser's next repaint. * * @return {number} * Returns an rAF ID that gets used to identify the timeout. It can * also be used in {@link Component#cancelAnimationFrame} to cancel * the animation frame callback. * * @listens Component#dispose * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame} */ requestAnimationFrame(fn) { this.clearTimersOnDispose_(); var id; fn = bind_(this, fn); id = import_window6.default.requestAnimationFrame(() => { if (this.rafIds_.has(id)) { this.rafIds_.delete(id); } fn(); }); this.rafIds_.add(id); return id; } /** * Request an animation frame, but only one named animation * frame will be queued. Another will never be added until * the previous one finishes. * * @param {string} name * The name to give this requestAnimationFrame * * @param {Component~GenericCallback} fn * A function that will be bound to this component and executed just * before the browser's next repaint. */ requestNamedAnimationFrame(name, fn) { if (this.namedRafs_.has(name)) { this.cancelNamedAnimationFrame(name); } this.clearTimersOnDispose_(); fn = bind_(this, fn); const id = this.requestAnimationFrame(() => { fn(); if (this.namedRafs_.has(name)) { this.namedRafs_.delete(name); } }); this.namedRafs_.set(name, id); return name; } /** * Cancels a current named animation frame if it exists. * * @param {string} name * The name of the requestAnimationFrame to cancel. */ cancelNamedAnimationFrame(name) { if (!this.namedRafs_.has(name)) { return; } this.cancelAnimationFrame(this.namedRafs_.get(name)); this.namedRafs_.delete(name); } /** * Cancels a queued callback passed to {@link Component#requestAnimationFrame} * (rAF). * * If you queue an rAF callback via {@link Component#requestAnimationFrame}, * use this function instead of `window.cancelAnimationFrame`. If you don't, * your dispose listener will not get cleaned up until {@link Component#dispose}! * * @param {number} id * The rAF ID to clear. The return value of {@link Component#requestAnimationFrame}. * * @return {number} * Returns the rAF ID that was cleared. * * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/window/cancelAnimationFrame} */ cancelAnimationFrame(id) { if (this.rafIds_.has(id)) { this.rafIds_.delete(id); import_window6.default.cancelAnimationFrame(id); } return id; } /** * A function to setup `requestAnimationFrame`, `setTimeout`, * and `setInterval`, clearing on dispose. * * > Previously each timer added and removed dispose listeners on it's own. * For better performance it was decided to batch them all, and use `Set`s * to track outstanding timer ids. * * @private */ clearTimersOnDispose_() { if (this.clearingTimersOnDispose_) { return; } this.clearingTimersOnDispose_ = true; this.one("dispose", () => { [["namedRafs_", "cancelNamedAnimationFrame"], ["rafIds_", "cancelAnimationFrame"], ["setTimeoutIds_", "clearTimeout"], ["setIntervalIds_", "clearInterval"]].forEach(([idName, cancelName]) => { this[idName].forEach((val, key) => this[cancelName](key)); }); this.clearingTimersOnDispose_ = false; }); } /** * Decide whether an element is actually disabled or not. * * @function isActuallyDisabled * @param element {Node} * @return {boolean} * * @see {@link https://html.spec.whatwg.org/multipage/semantics-other.html#concept-element-disabled} */ getIsDisabled() { return Boolean(this.el_.disabled); } /** * Decide whether the element is expressly inert or not. * * @see {@link https://html.spec.whatwg.org/multipage/interaction.html#expressly-inert} * @function isExpresslyInert * @param element {Node} * @return {boolean} */ getIsExpresslyInert() { return this.el_.inert && !this.el_.ownerDocument.documentElement.inert; } /** * Determine whether or not this component can be considered as focusable component. * * @param {HTMLElement} el - The HTML element representing the component. * @return {boolean} * If the component can be focused, will be `true`. Otherwise, `false`. */ getIsFocusable(el) { const element = el || this.el_; return element.tabIndex >= 0 && !(this.getIsDisabled() || this.getIsExpresslyInert()); } /** * Determine whether or not this component is currently visible/enabled/etc... * * @param {HTMLElement} el - The HTML element representing the component. * @return {boolean} * If the component can is currently visible & enabled, will be `true`. Otherwise, `false`. */ getIsAvailableToBeFocused(el) { function isVisibleStyleProperty(element) { const elementStyle = import_window6.default.getComputedStyle(element, null); const thisVisibility = elementStyle.getPropertyValue("visibility"); const thisDisplay = elementStyle.getPropertyValue("display"); const invisibleStyle = ["hidden", "collapse"]; return thisDisplay !== "none" && !invisibleStyle.includes(thisVisibility); } function isBeingRendered(element) { if (!isVisibleStyleProperty(element.parentElement)) { return false; } if (!isVisibleStyleProperty(element) || element.style.opacity === "0" || import_window6.default.getComputedStyle(element).height === "0px" || import_window6.default.getComputedStyle(element).width === "0px") { return false; } return true; } function isVisible(element) { if (element.offsetWidth + element.offsetHeight + element.getBoundingClientRect().height + element.getBoundingClientRect().width === 0) { return false; } const elementCenter = { x: element.getBoundingClientRect().left + element.offsetWidth / 2, y: element.getBoundingClientRect().top + element.offsetHeight / 2 }; if (elementCenter.x < 0) { return false; } if (elementCenter.x > (import_document.default.documentElement.clientWidth || import_window6.default.innerWidth)) { return false; } if (elementCenter.y < 0) { return false; } if (elementCenter.y > (import_document.default.documentElement.clientHeight || import_window6.default.innerHeight)) { return false; } let pointContainer = import_document.default.elementFromPoint(elementCenter.x, elementCenter.y); while (pointContainer) { if (pointContainer === element) { return true; } if (pointContainer.parentNode) { pointContainer = pointContainer.parentNode; } else { return false; } } } if (!el) { el = this.el(); } if (isVisible(el) && isBeingRendered(el) && (!el.parentElement || el.tabIndex >= 0)) { return true; } return false; } /** * Register a `Component` with `videojs` given the name and the component. * * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s * should be registered using {@link Tech.registerTech} or * {@link videojs:videojs.registerTech}. * * > NOTE: This function can also be seen on videojs as * {@link videojs:videojs.registerComponent}. * * @param {string} name * The name of the `Component` to register. * * @param {Component} ComponentToRegister * The `Component` class to register. * * @return {Component} * The `Component` that was registered. */ static registerComponent(name, ComponentToRegister) { if (typeof name !== "string" || !name) { throw new Error(`Illegal component name, "${name}"; must be a non-empty string.`); } const Tech2 = _Component$1.getComponent("Tech"); const isTech = Tech2 && Tech2.isTech(ComponentToRegister); const isComp = _Component$1 === ComponentToRegister || _Component$1.prototype.isPrototypeOf(ComponentToRegister.prototype); if (isTech || !isComp) { let reason; if (isTech) { reason = "techs must be registered using Tech.registerTech()"; } else { reason = "must be a Component subclass"; } throw new Error(`Illegal component, "${name}"; ${reason}.`); } name = toTitleCase$1(name); if (!_Component$1.components_) { _Component$1.components_ = {}; } const Player2 = _Component$1.getComponent("Player"); if (name === "Player" && Player2 && Player2.players) { const players = Player2.players; const playerNames = Object.keys(players); if (players && playerNames.length > 0) { for (let i = 0; i < playerNames.length; i++) { if (players[playerNames[i]] !== null) { throw new Error("Can not register Player component after player has been created."); } } } } _Component$1.components_[name] = ComponentToRegister; _Component$1.components_[toLowerCase(name)] = ComponentToRegister; return ComponentToRegister; } /** * Get a `Component` based on the name it was registered with. * * @param {string} name * The Name of the component to get. * * @return {typeof Component} * The `Component` that got registered under the given name. */ static getComponent(name) { if (!name || !_Component$1.components_) { return; } return _Component$1.components_[name]; } }; Component$1.registerComponent("Component", Component$1); function rangeCheck(fnName, index, maxIndex) { if (typeof index !== "number" || index < 0 || index > maxIndex) { throw new Error(`Failed to execute '${fnName}' on 'TimeRanges': The index provided (${index}) is non-numeric or out of bounds (0-${maxIndex}).`); } } function getRange(fnName, valueIndex, ranges, rangeIndex) { rangeCheck(fnName, rangeIndex, ranges.length - 1); return ranges[rangeIndex][valueIndex]; } function createTimeRangesObj(ranges) { let timeRangesObj; if (ranges === void 0 || ranges.length === 0) { timeRangesObj = { length: 0, start() { throw new Error("This TimeRanges object is empty"); }, end() { throw new Error("This TimeRanges object is empty"); } }; } else { timeRangesObj = { length: ranges.length, start: getRange.bind(null, "start", 0, ranges), end: getRange.bind(null, "end", 1, ranges) }; } if (import_window6.default.Symbol && import_window6.default.Symbol.iterator) { timeRangesObj[import_window6.default.Symbol.iterator] = () => (ranges || []).values(); } return timeRangesObj; } function createTimeRanges$1(start, end) { if (Array.isArray(start)) { return createTimeRangesObj(start); } else if (start === void 0 || end === void 0) { return createTimeRangesObj(); } return createTimeRangesObj([[start, end]]); } var defaultImplementation = function(seconds, guide) { seconds = seconds < 0 ? 0 : seconds; let s = Math.floor(seconds % 60); let m = Math.floor(seconds / 60 % 60); let h = Math.floor(seconds / 3600); const gm = Math.floor(guide / 60 % 60); const gh = Math.floor(guide / 3600); if (isNaN(seconds) || seconds === Infinity) { h = m = s = "-"; } h = h > 0 || gh > 0 ? h + ":" : ""; m = ((h || gm >= 10) && m < 10 ? "0" + m : m) + ":"; s = s < 10 ? "0" + s : s; return h + m + s; }; var implementation = defaultImplementation; function setFormatTime(customImplementation) { implementation = customImplementation; } function resetFormatTime() { implementation = defaultImplementation; } function formatTime(seconds, guide = seconds) { return implementation(seconds, guide); } var Time = Object.freeze({ __proto__: null, createTimeRanges: createTimeRanges$1, createTimeRange: createTimeRanges$1, setFormatTime, resetFormatTime, formatTime }); function bufferedPercent(buffered, duration2) { let bufferedDuration = 0; let start; let end; if (!duration2) { return 0; } if (!buffered || !buffered.length) { buffered = createTimeRanges$1(0, 0); } for (let i = 0; i < buffered.length; i++) { start = buffered.start(i); end = buffered.end(i); if (end > duration2) { end = duration2; } bufferedDuration += end - start; } return bufferedDuration / duration2; } function MediaError(value) { if (value instanceof MediaError) { return value; } if (typeof value === "number") { this.code = value; } else if (typeof value === "string") { this.message = value; } else if (isObject2(value)) { if (typeof value.code === "number") { this.code = value.code; } Object.assign(this, value); } if (!this.message) { this.message = MediaError.defaultMessages[this.code] || ""; } } MediaError.prototype.code = 0; MediaError.prototype.message = ""; MediaError.prototype.status = null; MediaError.prototype.metadata = null; MediaError.errorTypes = ["MEDIA_ERR_CUSTOM", "MEDIA_ERR_ABORTED", "MEDIA_ERR_NETWORK", "MEDIA_ERR_DECODE", "MEDIA_ERR_SRC_NOT_SUPPORTED", "MEDIA_ERR_ENCRYPTED"]; MediaError.defaultMessages = { 1: "You aborted the media playback", 2: "A network error caused the media download to fail part-way.", 3: "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.", 4: "The media could not be loaded, either because the server or network failed or because the format is not supported.", 5: "The media is encrypted and we do not have the keys to decrypt it." }; MediaError.MEDIA_ERR_CUSTOM = 0; MediaError.prototype.MEDIA_ERR_CUSTOM = 0; MediaError.MEDIA_ERR_ABORTED = 1; MediaError.prototype.MEDIA_ERR_ABORTED = 1; MediaError.MEDIA_ERR_NETWORK = 2; MediaError.prototype.MEDIA_ERR_NETWORK = 2; MediaError.MEDIA_ERR_DECODE = 3; MediaError.prototype.MEDIA_ERR_DECODE = 3; MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4; MediaError.prototype.MEDIA_ERR_SRC_NOT_SUPPORTED = 4; MediaError.MEDIA_ERR_ENCRYPTED = 5; MediaError.prototype.MEDIA_ERR_ENCRYPTED = 5; function isPromise(value) { return value !== void 0 && value !== null && typeof value.then === "function"; } function silencePromise(value) { if (isPromise(value)) { value.then(null, (e) => { }); } } var trackToJson_ = function(track) { const ret = ["kind", "label", "language", "id", "inBandMetadataTrackDispatchType", "mode", "src"].reduce((acc, prop, i) => { if (track[prop]) { acc[prop] = track[prop]; } return acc; }, { cues: track.cues && Array.prototype.map.call(track.cues, function(cue) { return { startTime: cue.startTime, endTime: cue.endTime, text: cue.text, id: cue.id }; }) }); return ret; }; var textTracksToJson = function(tech) { const trackEls = tech.$$("track"); const trackObjs = Array.prototype.map.call(trackEls, (t) => t.track); const tracks = Array.prototype.map.call(trackEls, function(trackEl) { const json = trackToJson_(trackEl.track); if (trackEl.src) { json.src = trackEl.src; } return json; }); return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function(track) { return trackObjs.indexOf(track) === -1; }).map(trackToJson_)); }; var jsonToTextTracks = function(json, tech) { json.forEach(function(track) { const addedTrack = tech.addRemoteTextTrack(track).track; if (!track.src && track.cues) { track.cues.forEach((cue) => addedTrack.addCue(cue)); } }); return tech.textTracks(); }; var textTrackConverter = { textTracksToJson, jsonToTextTracks, trackToJson_ }; var MODAL_CLASS_NAME = "vjs-modal-dialog"; var ModalDialog = class extends Component$1 { /** * Creates an instance of this class. * * @param {Player} player * The `Player` that this class should be attached to. * * @param {Object} [options] * The key/value store of player options. * * @param {ContentDescriptor} [options.content=undefined] * Provide customized content for this modal. * * @param {string} [options.description] * A text description for the modal, primarily for accessibility. * * @param {boolean} [options.fillAlways=false] * Normally, modals are automatically filled only the first time * they open. This tells the modal to refresh its content * every time it opens. * * @param {string} [options.label] * A text label for the modal, primarily for accessibility. * * @param {boolean} [options.pauseOnOpen=true] * If `true`, playback will will be paused if playing when * the modal opens, and resumed when it closes. * * @param {boolean} [options.temporary=true] * If `true`, the modal can only be opened once; it will be * disposed as soon as it's closed. * * @param {boolean} [options.uncloseable=false] * If `true`, the user will not be able to close the modal * through the UI in the normal ways. Programmatic closing is * still possible. */ constructor(player, options) { super(player, options); this.handleKeyDown_ = (e) => this.handleKeyDown(e); this.close_ = (e) => this.close(e); this.opened_ = this.hasBeenOpened_ = this.hasBeenFilled_ = false; this.closeable(!this.options_.uncloseable); this.content(this.options_.content); this.contentEl_ = createEl("div", { className: `${MODAL_CLASS_NAME}-content` }, { role: "document" }); this.descEl_ = createEl("p", { className: `${MODAL_CLASS_NAME}-description vjs-control-text`, id: this.el().getAttribute("aria-describedby") }); textContent(this.descEl_, this.description()); this.el_.appendChild(this.descEl_); this.el_.appendChild(this.contentEl_); } /** * Create the `ModalDialog`'s DOM element * * @return {Element} * The DOM element that gets created. */ createEl() { return super.createEl("div", { className: this.buildCSSClass(), tabIndex: -1 }, { "aria-describedby": `${this.id()}_description`, "aria-hidden": "true", "aria-label": this.label(), "role": "dialog", "aria-live": "polite" }); } dispose() { this.contentEl_ = null; this.descEl_ = null; this.previouslyActiveEl_ = null; super.dispose(); } /** * Builds the default DOM `className`. * * @return {string} * The DOM `className` for this object. */ buildCSSClass() { return `${MODAL_CLASS_NAME} vjs-hidden ${super.buildCSSClass()}`; } /** * Returns the label string for this modal. Primarily used for accessibility. * * @return {string} * the localized or raw label of this modal. */ label() { return this.localize(this.options_.label || "Modal Window"); } /** * Returns the description string for this modal. Primarily used for * accessibility. * * @return {string} * The localized or raw description of this modal. */ description() { let desc = this.options_.description || this.localize("This is a modal window."); if (this.closeable()) { desc += " " + this.localize("This modal can be closed by pressing the Escape key or activating the close button."); } return desc; } /** * Opens the modal. * * @fires ModalDialog#beforemodalopen * @fires ModalDialog#modalopen */ open() { if (this.opened_) { if (this.options_.fillAlways) { this.fill(); } return; } const player = this.player(); this.trigger("beforemodalopen"); this.opened_ = true; if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) { this.fill(); } this.wasPlaying_ = !player.paused(); if (this.options_.pauseOnOpen && this.wasPlaying_) { player.pause(); } this.on("keydown", this.handleKeyDown_); this.hadControls_ = player.controls(); player.controls(false); this.show(); this.conditionalFocus_(); this.el().setAttribute("aria-hidden", "false"); this.trigger("modalopen"); this.hasBeenOpened_ = true; } /** * If the `ModalDialog` is currently open or closed. * * @param {boolean} [value] * If given, it will open (`true`) or close (`false`) the modal. * * @return {boolean} * the current open state of the modaldialog */ opened(value) { if (typeof value === "boolean") { this[value ? "open" : "close"](); } return this.opened_; } /** * Closes the modal, does nothing if the `ModalDialog` is * not open. * * @fires ModalDialog#beforemodalclose * @fires ModalDialog#modalclose */ close() { if (!this.opened_) { return; } const player = this.player(); this.trigger("beforemodalclose"); this.opened_ = false; if (this.wasPlaying_ && this.options_.pauseOnOpen) { player.play(); } this.off("keydown", this.handleKeyDown_); if (this.hadControls_) { player.controls(true); } this.hide(); this.el().setAttribute("aria-hidden", "true"); this.trigger({ type: "modalclose", bubbles: true }); this.conditionalBlur_(); if (this.options_.temporary) { this.dispose(); } } /** * Check to see if the `ModalDialog` is closeable via the UI. * * @param {boolean} [value] * If given as a boolean, it will set the `closeable` option. * * @return {boolean} * Returns the final value of the closable option. */ closeable(value) { if (typeof value === "boolean") { const closeable = this.closeable_ = !!value; let close = this.getChild("closeButton"); if (closeable && !close) { const temp = this.contentEl_; this.contentEl_ = this.el_; close = this.addChild("closeButton", { controlText: "Close Modal Dialog" }); this.contentEl_ = temp; this.on(close, "close", this.close_); } if (!closeable && close) { this.off(close, "close", this.close_); this.removeChild(close); close.dispose(); } } return this.closeable_; } /** * Fill the modal's content element with the modal's "content" option. * The content element will be emptied before this change takes place. */ fill() { this.fillWith(this.content()); } /** * Fill the modal's content element with arbitrary content. * The content element will be emptied before this change takes place. * * @fires ModalDialog#beforemodalfill * @fires ModalDialog#modalfill * * @param {ContentDescriptor} [content] * The same rules apply to this as apply to the `content` option. */ fillWith(content) { const contentEl = this.contentEl(); const parentEl = contentEl.parentNode; const nextSiblingEl = contentEl.nextSibling; this.trigger("beforemodalfill"); this.hasBeenFilled_ = true; parentEl.removeChild(contentEl); this.empty(); insertContent(contentEl, content); this.trigger("modalfill"); if (nextSiblingEl) { parentEl.insertBefore(contentEl, nextSiblingEl); } else { parentEl.appendChild(contentEl); } const closeButton = this.getChild("closeButton"); if (closeButton) { parentEl.appendChild(closeButton.el_); } this.trigger("aftermodalfill"); } /** * Empties the content element. This happens anytime the modal is filled. * * @fires ModalDialog#beforemodalempty * @fires ModalDialog#modalempty */ empty() { this.trigger("beforemodalempty"); emptyEl(this.contentEl()); this.trigger("modalempty"); } /** * Gets or sets the modal content, which gets normalized before being * rendered into the DOM. * * This does not update the DOM or fill the modal, but it is called during * that process. * * @param {ContentDescriptor} [value] * If defined, sets the internal content value to be used on the * next call(s) to `fill`. This value is normalized before being * inserted. To "clear" the internal content value, pass `null`. * * @return {ContentDescriptor} * The current content of the modal dialog */ content(value) { if (typeof value !== "undefined") { this.content_ = value; } return this.content_; } /** * conditionally focus the modal dialog if focus was previously on the player. * * @private */ conditionalFocus_() { const activeEl = import_document.default.activeElement; const playerEl = this.player_.el_; this.previouslyActiveEl_ = null; if (playerEl.contains(activeEl) || playerEl === activeEl) { this.previouslyActiveEl_ = activeEl; this.focus(); } } /** * conditionally blur the element and refocus the last focused element * * @private */ conditionalBlur_() { if (this.previouslyActiveEl_) { this.previouslyActiveEl_.focus(); this.previouslyActiveEl_ = null; } } /** * Keydown handler. Attached when modal is focused. * * @listens keydown */ handleKeyDown(event) { this.trigger({ type: "modalKeydown", originalEvent: event, target: this, bubbles: true }); event.stopPropagation(); if (event.key === "Escape" && this.closeable()) { event.preventDefault(); this.close(); return; } if (event.key !== "Tab") { return; } const focusableEls = this.focusableEls_(); const activeEl = this.el_.querySelector(":focus"); let focusIndex; for (let i = 0; i < focusableEls.length; i++) { if (activeEl === focusableEls[i]) { focusIndex = i; break; } } if (import_document.default.activeElement === this.el_) { focusIndex = 0; } if (event.shiftKey && focusIndex === 0) { focusableEls[focusableEls.length - 1].focus(); event.preventDefault(); } else if (!event.shiftKey && focusIndex === focusableEls.length - 1) { focusableEls[0].focus(); event.preventDefault(); } } /** * get all focusable elements * * @private */ focusableEls_() { const allChildren = this.el_.querySelectorAll("*"); return Array.prototype.filter.call(allChildren, (child) => { return (child instanceof import_window6.default.HTMLAnchorElement || child instanceof import_window6.default.HTMLAreaElement) && child.hasAttribute("href") || (child instanceof import_window6.default.HTMLInputElement || child instanceof import_window6.default.HTMLSelectElement || child instanceof import_window6.default.HTMLTextAreaElement || child instanceof import_window6.default.HTMLButtonElement) && !child.hasAttribute("disabled") || child instanceof import_window6.default.HTMLIFrameElement || child instanceof import_window6.default.HTMLObjectElement || child instanceof import_window6.default.HTMLEmbedElement || child.hasAttribute("tabindex") && child.getAttribute("tabindex") !== -1 || child.hasAttribute("contenteditable"); }); } }; ModalDialog.prototype.options_ = { pauseOnOpen: true, temporary: true }; Component$1.registerComponent("ModalDialog", ModalDialog); var TrackList = class extends EventTarget$2 { /** * Create an instance of this class * * @param { Track[] } tracks * A list of tracks to initialize the list with. * * @abstract */ constructor(tracks = []) { super(); this.tracks_ = []; Object.defineProperty(this, "length", { get() { return this.tracks_.length; } }); for (let i = 0; i < tracks.length; i++) { this.addTrack(tracks[i]); } } /** * Add a {@link Track} to the `TrackList` * * @param {Track} track * The audio, video, or text track to add to the list. * * @fires TrackList#addtrack */ addTrack(track) { const index = this.tracks_.length; if (!("" + index in this)) { Object.defineProperty(this, index, { get() { return this.tracks_[index]; } }); } if (this.tracks_.indexOf(track) === -1) { this.tracks_.push(track); this.trigger({ track, type: "addtrack", target: this }); } track.labelchange_ = () => { this.trigger({ track, type: "labelchange", target: this }); }; if (isEvented(track)) { track.addEventListener("labelchange", track.labelchange_); } } /** * Remove a {@link Track} from the `TrackList` * * @param {Track} rtrack * The audio, video, or text track to remove from the list. * * @fires TrackList#removetrack */ removeTrack(rtrack) { let track; for (let i = 0, l = this.length; i < l; i++) { if (this[i] === rtrack) { track = this[i]; if (track.off) { track.off(); } this.tracks_.splice(i, 1); break; } } if (!track) { return; } this.trigger({ track, type: "removetrack", target: this }); } /** * Get a Track from the TrackList by a tracks id * * @param {string} id - the id of the track to get * @method getTrackById * @return {Track} * @private */ getTrackById(id) { let result = null; for (let i = 0, l = this.length; i < l; i++) { const track = this[i]; if (track.id === id) { result = track; break; } } return result; } }; TrackList.prototype.allowedEvents_ = { change: "change", addtrack: "addtrack", removetrack: "removetrack", labelchange: "labelchange" }; for (const event in TrackList.prototype.allowedEvents_) { TrackList.prototype["on" + event] = null; } var disableOthers$1 = function(list, track) { for (let i = 0; i < list.length; i++) { if (!Object.keys(list[i]).length || track.id === list[i].id) { continue; } list[i].enabled = false; } }; var AudioTrackList = class extends TrackList { /** * Create an instance of this class. * * @param {AudioTrack[]} [tracks=[]] * A list of `AudioTrack` to instantiate the list with. */ constructor(tracks = []) { for (let i = tracks.length - 1; i >= 0; i--) { if (tracks[i].enabled) { disableOthers$1(tracks, tracks[i]); break; } } super(tracks); this.changing_ = false; } /** * Add an {@link AudioTrack} to the `AudioTrackList`. * * @param {AudioTrack} track * The AudioTrack to add to the list * * @fires TrackList#addtrack */ addTrack(track) { if (track.enabled) { disableOthers$1(this, track); } super.addTrack(track); if (!track.addEventListener) { return; } track.enabledChange_ = () => { if (this.changing_) { return; } this.changing_ = true; disableOthers$1(this, track); this.changing_ = false; this.trigger("change"); }; track.addEventListener("enabledchange", track.enabledChange_); } removeTrack(rtrack) { super.removeTrack(rtrack); if (rtrack.removeEventListener && rtrack.enabledChange_) { rtrack.removeEventListener("enabledchange", rtrack.enabledChange_); rtrack.enabledChange_ = null; } } }; var disableOthers = function(list, track) { for (let i = 0; i < list.length; i++) { if (!Object.keys(list[i]).length || track.id === list[i].id) { continue; } list[i].selected = false; } }; var VideoTrackList = class extends TrackList { /** * Create an instance of this class. * * @param {VideoTrack[]} [tracks=[]] * A list of `VideoTrack` to instantiate the list with. */ constructor(tracks = []) { for (let i = tracks.length - 1; i >= 0; i--) { if (tracks[i].selected) { disableOthers(tracks, tracks[i]); break; } } super(tracks); this.changing_ = false; Object.defineProperty(this, "selectedIndex", { get() { for (let i = 0; i < this.length; i++) { if (this[i].selected) { return i; } } return -1; }, set() { } }); } /** * Add a {@link VideoTrack} to the `VideoTrackList`. * * @param {VideoTrack} track * The VideoTrack to add to the list * * @fires TrackList#addtrack */ addTrack(track) { if (track.selected) { disableOthers(this, track); } super.addTrack(track); if (!track.addEventListener) { return; } track.selectedChange_ = () => { if (this.changing_) { return; } this.changing_ = true; disableOthers(this, track); this.changing_ = false; this.trigger("change"); }; track.addEventListener("selectedchange", track.selectedChange_); } removeTrack(rtrack) { super.removeTrack(rtrack); if (rtrack.removeEventListener && rtrack.selectedChange_) { rtrack.removeEventListener("selectedchange", rtrack.selectedChange_); rtrack.selectedChange_ = null; } } }; var TextTrackList = class extends TrackList { /** * Add a {@link TextTrack} to the `TextTrackList` * * @param {TextTrack} track * The text track to add to the list. * * @fires TrackList#addtrack */ addTrack(track) { super.addTrack(track); if (!this.queueChange_) { this.queueChange_ = () => this.queueTrigger("change"); } if (!this.triggerSelectedlanguagechange) { this.triggerSelectedlanguagechange_ = () => this.trigger("selectedlanguagechange"); } track.addEventListener("modechange", this.queueChange_); const nonLanguageTextTrackKind = ["metadata", "chapters"]; if (nonLanguageTextTrackKind.indexOf(track.kind) === -1) { track.addEventListener("modechange", this.triggerSelectedlanguagechange_); } } removeTrack(rtrack) { super.removeTrack(rtrack); if (rtrack.removeEventListener) { if (this.queueChange_) { rtrack.removeEventListener("modechange", this.queueChange_); } if (this.selectedlanguagechange_) { rtrack.removeEventListener("modechange", this.triggerSelectedlanguagechange_); } } } }; var HtmlTrackElementList = class { /** * Create an instance of this class. * * @param {HtmlTrackElement[]} [tracks=[]] * A list of `HtmlTrackElement` to instantiate the list with. */ constructor(trackElements = []) { this.trackElements_ = []; Object.defineProperty(this, "length", { get() { return this.trackElements_.length; } }); for (let i = 0, length = trackElements.length; i < length; i++) { this.addTrackElement_(trackElements[i]); } } /** * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList` * * @param {HtmlTrackElement} trackElement * The track element to add to the list. * * @private */ addTrackElement_(trackElement) { const index = this.trackElements_.length; if (!("" + index in this)) { Object.defineProperty(this, index, { get() { return this.trackElements_[index]; } }); } if (this.trackElements_.indexOf(trackElement) === -1) { this.trackElements_.push(trackElement); } } /** * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an * {@link TextTrack}. * * @param {TextTrack} track * The track associated with a track element. * * @return {HtmlTrackElement|undefined} * The track element that was found or undefined. * * @private */ getTrackElementByTrack_(track) { let trackElement_; for (let i = 0, length = this.trackElements_.length; i < length; i++) { if (track === this.trackElements_[i].track) { trackElement_ = this.trackElements_[i]; break; } } return trackElement_; } /** * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList` * * @param {HtmlTrackElement} trackElement * The track element to remove from the list. * * @private */ removeTrackElement_(trackElement) { for (let i = 0, length = this.trackElements_.length; i < length; i++) { if (trackElement === this.trackElements_[i]) { if (this.trackElements_[i].track && typeof this.trackElements_[i].track.off === "function") { this.trackElements_[i].track.off(); } if (typeof this.trackElements_[i].off === "function") { this.trackElements_[i].off(); } this.trackElements_.splice(i, 1); break; } } } }; var TextTrackCueList = class _TextTrackCueList { /** * Create an instance of this class.. * * @param {Array} cues * A list of cues to be initialized with */ constructor(cues) { _TextTrackCueList.prototype.setCues_.call(this, cues); Object.defineProperty(this, "length", { get() { return this.length_; } }); } /** * A setter for cues in this list. Creates getters * an an index for the cues. * * @param {Array} cues * An array of cues to set * * @private */ setCues_(cues) { const oldLength = this.length || 0; let i = 0; const l = cues.length; this.cues_ = cues; this.length_ = cues.length; const defineProp = function(index) { if (!("" + index in this)) { Object.defineProperty(this, "" + index, { get() { return this.cues_[index]; } }); } }; if (oldLength < l) { i = oldLength; for (; i < l; i++) { defineProp.call(this, i); } } } /** * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id. * * @param {string} id * The id of the cue that should be searched for. * * @return {TextTrackCueList~TextTrackCue|null} * A single cue or null if none was found. */ getCueById(id) { let result = null; for (let i = 0, l = this.length; i < l; i++) { const cue = this[i]; if (cue.id === id) { result = cue; break; } } return result; } }; var VideoTrackKind = { alternative: "alternative", captions: "captions", main: "main", sign: "sign", subtitles: "subtitles", commentary: "commentary" }; var AudioTrackKind = { "alternative": "alternative", "descriptions": "descriptions", "main": "main", "main-desc": "main-desc", "translation": "translation", "commentary": "commentary" }; var TextTrackKind = { subtitles: "subtitles", captions: "captions", descriptions: "descriptions", chapters: "chapters", metadata: "metadata" }; var TextTrackMode = { disabled: "disabled", hidden: "hidden", showing: "showing" }; var Track = class extends EventTarget$2 { /** * Create an instance of this class. * * @param {Object} [options={}] * Object of option names and values * * @param {string} [options.kind=''] * A valid kind for the track type you are creating. * * @param {string} [options.id='vjs_track_' + Guid.newGUID()] * A unique id for this AudioTrack. * * @param {string} [options.label=''] * The menu label for this track. * * @param {string} [options.language=''] * A valid two character language code. * * @abstract */ constructor(options = {}) { super(); const trackProps = { id: options.id || "vjs_track_" + newGUID(), kind: options.kind || "", language: options.language || "" }; let label = options.label || ""; for (const key in trackProps) { Object.defineProperty(this, key, { get() { return trackProps[key]; }, set() { } }); } Object.defineProperty(this, "label", { get() { return label; }, set(newLabel) { if (newLabel !== label) { label = newLabel; this.trigger("labelchange"); } } }); } }; var parseUrl = function(url) { return new URL(url, import_document.default.baseURI); }; var getAbsoluteURL = function(url) { return new URL(url, import_document.default.baseURI).href; }; var getFileExtension = function(path) { if (typeof path === "string") { const splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/; const pathParts = splitPathRe.exec(path); if (pathParts) { return pathParts.pop().toLowerCase(); } } return ""; }; var isCrossOrigin = function(url, winLoc = import_window6.default.location) { return parseUrl(url).origin !== winLoc.origin; }; var Url = Object.freeze({ __proto__: null, parseUrl, getAbsoluteURL, getFileExtension, isCrossOrigin }); var parseCues = function(srcContent, track) { const parser5 = new import_window6.default.WebVTT.Parser(import_window6.default, import_window6.default.vttjs, import_window6.default.WebVTT.StringDecoder()); const errors2 = []; parser5.oncue = function(cue) { track.addCue(cue); }; parser5.onparsingerror = function(error) { errors2.push(error); }; parser5.onflush = function() { track.trigger({ type: "loadeddata", target: track }); }; parser5.parse(srcContent); if (errors2.length > 0) { if (import_window6.default.console && import_window6.default.console.groupCollapsed) { import_window6.default.console.groupCollapsed(`Text Track parsing errors for ${track.src}`); } errors2.forEach((error) => log$1.error(error)); if (import_window6.default.console && import_window6.default.console.groupEnd) { import_window6.default.console.groupEnd(); } } parser5.flush(); }; var loadTrack = function(src, track) { const opts = { uri: src }; const crossOrigin = isCrossOrigin(src); if (crossOrigin) { opts.cors = crossOrigin; } const withCredentials = track.tech_.crossOrigin() === "use-credentials"; if (withCredentials) { opts.withCredentials = withCredentials; } (0, import_xhr.default)(opts, bind_(this, function(err, response, responseBody) { if (err) { return log$1.error(err, response); } track.loaded_ = true; if (typeof import_window6.default.WebVTT !== "function") { if (track.tech_) { track.tech_.any(["vttjsloaded", "vttjserror"], (event) => { if (event.type === "vttjserror") { log$1.error(`vttjs failed to load, stopping trying to process ${track.src}`); return; } return parseCues(responseBody, track); }); } } else { parseCues(responseBody, track); } })); }; var TextTrack = class extends Track { /** * Create an instance of this class. * * @param {Object} options={} * Object of option names and values * * @param {Tech} options.tech * A reference to the tech that owns this TextTrack. * * @param {TextTrack~Kind} [options.kind='subtitles'] * A valid text track kind. * * @param {TextTrack~Mode} [options.mode='disabled'] * A valid text track mode. * * @param {string} [options.id='vjs_track_' + Guid.newGUID()] * A unique id for this TextTrack. * * @param {string} [options.label=''] * The menu label for this track. * * @param {string} [options.language=''] * A valid two character language code. * * @param {string} [options.srclang=''] * A valid two character language code. An alternative, but deprioritized * version of `options.language` * * @param {string} [options.src] * A url to TextTrack cues. * * @param {boolean} [options.default] * If this track should default to on or off. */ constructor(options = {}) { if (!options.tech) { throw new Error("A tech was not provided."); } const settings = merge$1(options, { kind: TextTrackKind[options.kind] || "subtitles", language: options.language || options.srclang || "" }); let mode = TextTrackMode[settings.mode] || "disabled"; const default_ = settings.default; if (settings.kind === "metadata" || settings.kind === "chapters") { mode = "hidden"; } super(settings); this.tech_ = settings.tech; this.cues_ = []; this.activeCues_ = []; this.preload_ = this.tech_.preloadTextTracks !== false; const cues = new TextTrackCueList(this.cues_); const activeCues = new TextTrackCueList(this.activeCues_); let changed = false; this.timeupdateHandler = bind_(this, function(event = {}) { if (this.tech_.isDisposed()) { return; } if (!this.tech_.isReady_) { if (event.type !== "timeupdate") { this.rvf_ = this.tech_.requestVideoFrameCallback(this.timeupdateHandler); } return; } this.activeCues = this.activeCues; if (changed) { this.trigger("cuechange"); changed = false; } if (event.type !== "timeupdate") { this.rvf_ = this.tech_.requestVideoFrameCallback(this.timeupdateHandler); } }); const disposeHandler = () => { this.stopTracking(); }; this.tech_.one("dispose", disposeHandler); if (mode !== "disabled") { this.startTracking(); } Object.defineProperties(this, { /** * @memberof TextTrack * @member {boolean} default * If this track was set to be on or off by default. Cannot be changed after * creation. * @instance * * @readonly */ default: { get() { return default_; }, set() { } }, /** * @memberof TextTrack * @member {string} mode * Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will * not be set if setting to an invalid mode. * @instance * * @fires TextTrack#modechange */ mode: { get() { return mode; }, set(newMode) { if (!TextTrackMode[newMode]) { return; } if (mode === newMode) { return; } mode = newMode; if (!this.preload_ && mode !== "disabled" && this.cues.length === 0) { loadTrack(this.src, this); } this.stopTracking(); if (mode !== "disabled") { this.startTracking(); } this.trigger("modechange"); } }, /** * @memberof TextTrack * @member {TextTrackCueList} cues * The text track cue list for this TextTrack. * @instance */ cues: { get() { if (!this.loaded_) { return null; } return cues; }, set() { } }, /** * @memberof TextTrack * @member {TextTrackCueList} activeCues * The list text track cues that are currently active for this TextTrack. * @instance */ activeCues: { get() { if (!this.loaded_) { return null; } if (this.cues.length === 0) { return activeCues; } const ct = this.tech_.currentTime(); const active = []; for (let i = 0, l = this.cues.length; i < l; i++) { const cue = this.cues[i]; if (cue.startTime <= ct && cue.endTime >= ct) { active.push(cue); } } changed = false; if (active.length !== this.activeCues_.length) { changed = true; } else { for (let i = 0; i < active.length; i++) { if (this.activeCues_.indexOf(active[i]) === -1) { changed = true; } } } this.activeCues_ = active; activeCues.setCues_(this.activeCues_); return activeCues; }, // /!\ Keep this setter empty (see the timeupdate handler above) set() { } } }); if (settings.src) { this.src = settings.src; if (!this.preload_) { this.loaded_ = true; } if (this.preload_ || settings.kind !== "subtitles" && settings.kind !== "captions") { loadTrack(this.src, this); } } else { this.loaded_ = true; } } startTracking() { this.rvf_ = this.tech_.requestVideoFrameCallback(this.timeupdateHandler); this.tech_.on("timeupdate", this.timeupdateHandler); } stopTracking() { if (this.rvf_) { this.tech_.cancelVideoFrameCallback(this.rvf_); this.rvf_ = void 0; } this.tech_.off("timeupdate", this.timeupdateHandler); } /** * Add a cue to the internal list of cues. * * @param {TextTrack~Cue} cue * The cue to add to our internal list */ addCue(originalCue) { let cue = originalCue; if (!("getCueAsHTML" in cue)) { cue = new import_window6.default.vttjs.VTTCue(originalCue.startTime, originalCue.endTime, originalCue.text); for (const prop in originalCue) { if (!(prop in cue)) { cue[prop] = originalCue[prop]; } } cue.id = originalCue.id; cue.originalCue_ = originalCue; } const tracks = this.tech_.textTracks(); for (let i = 0; i < tracks.length; i++) { if (tracks[i] !== this) { tracks[i].removeCue(cue); } } this.cues_.push(cue); this.cues.setCues_(this.cues_); } /** * Remove a cue from our internal list * * @param {TextTrack~Cue} removeCue * The cue to remove from our internal list */ removeCue(removeCue) { let i = this.cues_.length; while (i--) { const cue = this.cues_[i]; if (cue === removeCue || cue.originalCue_ && cue.originalCue_ === removeCue) { this.cues_.splice(i, 1); this.cues.setCues_(this.cues_); break; } } } }; TextTrack.prototype.allowedEvents_ = { cuechange: "cuechange" }; var AudioTrack = class extends Track { /** * Create an instance of this class. * * @param {Object} [options={}] * Object of option names and values * * @param {AudioTrack~Kind} [options.kind=''] * A valid audio track kind * * @param {string} [options.id='vjs_track_' + Guid.newGUID()] * A unique id for this AudioTrack. * * @param {string} [options.label=''] * The menu label for this track. * * @param {string} [options.language=''] * A valid two character language code. * * @param {boolean} [options.enabled] * If this track is the one that is currently playing. If this track is part of * an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled. */ constructor(options = {}) { const settings = merge$1(options, { kind: AudioTrackKind[options.kind] || "" }); super(settings); let enabled = false; Object.defineProperty(this, "enabled", { get() { return enabled; }, set(newEnabled) { if (typeof newEnabled !== "boolean" || newEnabled === enabled) { return; } enabled = newEnabled; this.trigger("enabledchange"); } }); if (settings.enabled) { this.enabled = settings.enabled; } this.loaded_ = true; } }; var VideoTrack = class extends Track { /** * Create an instance of this class. * * @param {Object} [options={}] * Object of option names and values * * @param {string} [options.kind=''] * A valid {@link VideoTrack~Kind} * * @param {string} [options.id='vjs_track_' + Guid.newGUID()] * A unique id for this AudioTrack. * * @param {string} [options.label=''] * The menu label for this track. * * @param {string} [options.language=''] * A valid two character language code. * * @param {boolean} [options.selected] * If this track is the one that is currently playing. */ constructor(options = {}) { const settings = merge$1(options, { kind: VideoTrackKind[options.kind] || "" }); super(settings); let selected = false; Object.defineProperty(this, "selected", { get() { return selected; }, set(newSelected) { if (typeof newSelected !== "boolean" || newSelected === selected) { return; } selected = newSelected; this.trigger("selectedchange"); } }); if (settings.selected) { this.selected = settings.selected; } } }; var HTMLTrackElement = class _HTMLTrackElement extends EventTarget$2 { /** * Create an instance of this class. * * @param {Object} options={} * Object of option names and values * * @param {Tech} options.tech * A reference to the tech that owns this HTMLTrackElement. * * @param {TextTrack~Kind} [options.kind='subtitles'] * A valid text track kind. * * @param {TextTrack~Mode} [options.mode='disabled'] * A valid text track mode. * * @param {string} [options.id='vjs_track_' + Guid.newGUID()] * A unique id for this TextTrack. * * @param {string} [options.label=''] * The menu label for this track. * * @param {string} [options.language=''] * A valid two character language code. * * @param {string} [options.srclang=''] * A valid two character language code. An alternative, but deprioritized * version of `options.language` * * @param {string} [options.src] * A url to TextTrack cues. * * @param {boolean} [options.default] * If this track should default to on or off. */ constructor(options = {}) { super(); let readyState; const track = new TextTrack(options); this.kind = track.kind; this.src = track.src; this.srclang = track.language; this.label = track.label; this.default = track.default; Object.defineProperties(this, { /** * @memberof HTMLTrackElement * @member {HTMLTrackElement~ReadyState} readyState * The current ready state of the track element. * @instance */ readyState: { get() { return readyState; } }, /** * @memberof HTMLTrackElement * @member {TextTrack} track * The underlying TextTrack object. * @instance * */ track: { get() { return track; } } }); readyState = _HTMLTrackElement.NONE; track.addEventListener("loadeddata", () => { readyState = _HTMLTrackElement.LOADED; this.trigger({ type: "load", target: this }); }); } }; HTMLTrackElement.prototype.allowedEvents_ = { load: "load" }; HTMLTrackElement.NONE = 0; HTMLTrackElement.LOADING = 1; HTMLTrackElement.LOADED = 2; HTMLTrackElement.ERROR = 3; var NORMAL = { audio: { ListClass: AudioTrackList, TrackClass: AudioTrack, capitalName: "Audio" }, video: { ListClass: VideoTrackList, TrackClass: VideoTrack, capitalName: "Video" }, text: { ListClass: TextTrackList, TrackClass: TextTrack, capitalName: "Text" } }; Object.keys(NORMAL).forEach(function(type) { NORMAL[type].getterName = `${type}Tracks`; NORMAL[type].privateName = `${type}Tracks_`; }); var REMOTE = { remoteText: { ListClass: TextTrackList, TrackClass: TextTrack, capitalName: "RemoteText", getterName: "remoteTextTracks", privateName: "remoteTextTracks_" }, remoteTextEl: { ListClass: HtmlTrackElementList, TrackClass: HTMLTrackElement, capitalName: "RemoteTextTrackEls", getterName: "remoteTextTrackEls", privateName: "remoteTextTrackEls_" } }; var ALL = Object.assign({}, NORMAL, REMOTE); REMOTE.names = Object.keys(REMOTE); NORMAL.names = Object.keys(NORMAL); ALL.names = [].concat(REMOTE.names).concat(NORMAL.names); function createTrackHelper(self2, kind, label, language, options = {}) { const tracks = self2.textTracks(); options.kind = kind; if (label) { options.label = label; } if (language) { options.language = language; } options.tech = self2; const track = new ALL.text.TrackClass(options); tracks.addTrack(track); return track; } var Tech = class _Tech extends Component$1 { /** * Create an instance of this Tech. * * @param {Object} [options] * The key/value store of player options. * * @param {Function} [ready] * Callback function to call when the `HTML5` Tech is ready. */ constructor(options = {}, ready = function() { }) { options.reportTouchActivity = false; super(null, options, ready); this.onDurationChange_ = (e) => this.onDurationChange(e); this.trackProgress_ = (e) => this.trackProgress(e); this.trackCurrentTime_ = (e) => this.trackCurrentTime(e); this.stopTrackingCurrentTime_ = (e) => this.stopTrackingCurrentTime(e); this.disposeSourceHandler_ = (e) => this.disposeSourceHandler(e); this.queuedHanders_ = /* @__PURE__ */ new Set(); this.hasStarted_ = false; this.on("playing", function() { this.hasStarted_ = true; }); this.on("loadstart", function() { this.hasStarted_ = false; }); ALL.names.forEach((name) => { const props = ALL[name]; if (options && options[props.getterName]) { this[props.privateName] = options[props.getterName]; } }); if (!this.featuresProgressEvents) { this.manualProgressOn(); } if (!this.featuresTimeupdateEvents) { this.manualTimeUpdatesOn(); } ["Text", "Audio", "Video"].forEach((track) => { if (options[`native${track}Tracks`] === false) { this[`featuresNative${track}Tracks`] = false; } }); if (options.nativeCaptions === false || options.nativeTextTracks === false) { this.featuresNativeTextTracks = false; } else if (options.nativeCaptions === true || options.nativeTextTracks === true) { this.featuresNativeTextTracks = true; } if (!this.featuresNativeTextTracks) { this.emulateTextTracks(); } this.preloadTextTracks = options.preloadTextTracks !== false; this.autoRemoteTextTracks_ = new ALL.text.ListClass(); this.initTrackListeners(); if (!options.nativeControlsForTouch) { this.emitTapEvents(); } if (this.constructor) { this.name_ = this.constructor.name || "Unknown Tech"; } } /** * A special function to trigger source set in a way that will allow player * to re-trigger if the player or tech are not ready yet. * * @fires Tech#sourceset * @param {string} src The source string at the time of the source changing. */ triggerSourceset(src) { if (!this.isReady_) { this.one("ready", () => this.setTimeout(() => this.triggerSourceset(src), 1)); } this.trigger({ src, type: "sourceset" }); } /* Fallbacks for unsupported event types ================================================================================ */ /** * Polyfill the `progress` event for browsers that don't support it natively. * * @see {@link Tech#trackProgress} */ manualProgressOn() { this.on("durationchange", this.onDurationChange_); this.manualProgress = true; this.one("ready", this.trackProgress_); } /** * Turn off the polyfill for `progress` events that was created in * {@link Tech#manualProgressOn} */ manualProgressOff() { this.manualProgress = false; this.stopTrackingProgress(); this.off("durationchange", this.onDurationChange_); } /** * This is used to trigger a `progress` event when the buffered percent changes. It * sets an interval function that will be called every 500 milliseconds to check if the * buffer end percent has changed. * * > This function is called by {@link Tech#manualProgressOn} * * @param {Event} event * The `ready` event that caused this to run. * * @listens Tech#ready * @fires Tech#progress */ trackProgress(event) { this.stopTrackingProgress(); this.progressInterval = this.setInterval(bind_(this, function() { const numBufferedPercent = this.bufferedPercent(); if (this.bufferedPercent_ !== numBufferedPercent) { this.trigger("progress"); } this.bufferedPercent_ = numBufferedPercent; if (numBufferedPercent === 1) { this.stopTrackingProgress(); } }), 500); } /** * Update our internal duration on a `durationchange` event by calling * {@link Tech#duration}. * * @param {Event} event * The `durationchange` event that caused this to run. * * @listens Tech#durationchange */ onDurationChange(event) { this.duration_ = this.duration(); } /** * Get and create a `TimeRange` object for buffering. * * @return {TimeRange} * The time range object that was created. */ buffered() { return createTimeRanges$1(0, 0); } /** * Get the percentage of the current video that is currently buffered. * * @return {number} * A number from 0 to 1 that represents the decimal percentage of the * video that is buffered. * */ bufferedPercent() { return bufferedPercent(this.buffered(), this.duration_); } /** * Turn off the polyfill for `progress` events that was created in * {@link Tech#manualProgressOn} * Stop manually tracking progress events by clearing the interval that was set in * {@link Tech#trackProgress}. */ stopTrackingProgress() { this.clearInterval(this.progressInterval); } /** * Polyfill the `timeupdate` event for browsers that don't support it. * * @see {@link Tech#trackCurrentTime} */ manualTimeUpdatesOn() { this.manualTimeUpdates = true; this.on("play", this.trackCurrentTime_); this.on("pause", this.stopTrackingCurrentTime_); } /** * Turn off the polyfill for `timeupdate` events that was created in * {@link Tech#manualTimeUpdatesOn} */ manualTimeUpdatesOff() { this.manualTimeUpdates = false; this.stopTrackingCurrentTime(); this.off("play", this.trackCurrentTime_); this.off("pause", this.stopTrackingCurrentTime_); } /** * Sets up an interval function to track current time and trigger `timeupdate` every * 250 milliseconds. * * @listens Tech#play * @triggers Tech#timeupdate */ trackCurrentTime() { if (this.currentTimeInterval) { this.stopTrackingCurrentTime(); } this.currentTimeInterval = this.setInterval(function() { this.trigger({ type: "timeupdate", target: this, manuallyTriggered: true }); }, 250); } /** * Stop the interval function created in {@link Tech#trackCurrentTime} so that the * `timeupdate` event is no longer triggered. * * @listens {Tech#pause} */ stopTrackingCurrentTime() { this.clearInterval(this.currentTimeInterval); this.trigger({ type: "timeupdate", target: this, manuallyTriggered: true }); } /** * Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList}, * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech. * * @fires Component#dispose */ dispose() { this.clearTracks(NORMAL.names); if (this.manualProgress) { this.manualProgressOff(); } if (this.manualTimeUpdates) { this.manualTimeUpdatesOff(); } super.dispose(); } /** * Clear out a single `TrackList` or an array of `TrackLists` given their names. * * > Note: Techs without source handlers should call this between sources for `video` * & `audio` tracks. You don't want to use them between tracks! * * @param {string[]|string} types * TrackList names to clear, valid names are `video`, `audio`, and * `text`. */ clearTracks(types) { types = [].concat(types); types.forEach((type) => { const list = this[`${type}Tracks`]() || []; let i = list.length; while (i--) { const track = list[i]; if (type === "text") { this.removeRemoteTextTrack(track); } list.removeTrack(track); } }); } /** * Remove any TextTracks added via addRemoteTextTrack that are * flagged for automatic garbage collection */ cleanupAutoTextTracks() { const list = this.autoRemoteTextTracks_ || []; let i = list.length; while (i--) { const track = list[i]; this.removeRemoteTextTrack(track); } } /** * Reset the tech, which will removes all sources and reset the internal readyState. * * @abstract */ reset() { } /** * Get the value of `crossOrigin` from the tech. * * @abstract * * @see {Html5#crossOrigin} */ crossOrigin() { } /** * Set the value of `crossOrigin` on the tech. * * @abstract * * @param {string} crossOrigin the crossOrigin value * @see {Html5#setCrossOrigin} */ setCrossOrigin() { } /** * Get or set an error on the Tech. * * @param {MediaError} [err] * Error to set on the Tech * * @return {MediaError|null} * The current error object on the tech, or null if there isn't one. */ error(err) { if (err !== void 0) { this.error_ = new MediaError(err); this.trigger("error"); } return this.error_; } /** * Returns the `TimeRange`s that have been played through for the current source. * * > NOTE: This implementation is incomplete. It does not track the played `TimeRange`. * It only checks whether the source has played at all or not. * * @return {TimeRange} * - A single time range if this video has played * - An empty set of ranges if not. */ played() { if (this.hasStarted_) { return createTimeRanges$1(0, 0); } return createTimeRanges$1(); } /** * Start playback * * @abstract * * @see {Html5#play} */ play() { } /** * Set whether we are scrubbing or not * * @abstract * @param {boolean} _isScrubbing * - true for we are currently scrubbing * - false for we are no longer scrubbing * * @see {Html5#setScrubbing} */ setScrubbing(_isScrubbing) { } /** * Get whether we are scrubbing or not * * @abstract * * @see {Html5#scrubbing} */ scrubbing() { } /** * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was * previously called. * * @param {number} _seconds * Set the current time of the media to this. * @fires Tech#timeupdate */ setCurrentTime(_seconds) { if (this.manualTimeUpdates) { this.trigger({ type: "timeupdate", target: this, manuallyTriggered: true }); } } /** * Turn on listeners for {@link VideoTrackList}, {@link {AudioTrackList}, and * {@link TextTrackList} events. * * This adds {@link EventTarget~EventListeners} for `addtrack`, and `removetrack`. * * @fires Tech#audiotrackchange * @fires Tech#videotrackchange * @fires Tech#texttrackchange */ initTrackListeners() { NORMAL.names.forEach((name) => { const props = NORMAL[name]; const trackListChanges = () => { this.trigger(`${name}trackchange`); }; const tracks = this[props.getterName](); tracks.addEventListener("removetrack", trackListChanges); tracks.addEventListener("addtrack", trackListChanges); this.on("dispose", () => { tracks.removeEventListener("removetrack", trackListChanges); tracks.removeEventListener("addtrack", trackListChanges); }); }); } /** * Emulate TextTracks using vtt.js if necessary * * @fires Tech#vttjsloaded * @fires Tech#vttjserror */ addWebVttScript_() { if (import_window6.default.WebVTT) { return; } if (import_document.default.body.contains(this.el())) { if (!this.options_["vtt.js"] && isPlain(import_videojs_vtt.default) && Object.keys(import_videojs_vtt.default).length > 0) { this.trigger("vttjsloaded"); return; } const script = import_document.default.createElement("script"); script.src = this.options_["vtt.js"] || "https://vjs.zencdn.net/vttjs/0.14.1/vtt.min.js"; script.onload = () => { this.trigger("vttjsloaded"); }; script.onerror = () => { this.trigger("vttjserror"); }; this.on("dispose", () => { script.onload = null; script.onerror = null; }); import_window6.default.WebVTT = true; this.el().parentNode.appendChild(script); } else { this.ready(this.addWebVttScript_); } } /** * Emulate texttracks * */ emulateTextTracks() { const tracks = this.textTracks(); const remoteTracks = this.remoteTextTracks(); const handleAddTrack = (e) => tracks.addTrack(e.track); const handleRemoveTrack = (e) => tracks.removeTrack(e.track); remoteTracks.on("addtrack", handleAddTrack); remoteTracks.on("removetrack", handleRemoveTrack); this.addWebVttScript_(); const updateDisplay = () => this.trigger("texttrackchange"); const textTracksChanges = () => { updateDisplay(); for (let i = 0; i < tracks.length; i++) { const track = tracks[i]; track.removeEventListener("cuechange", updateDisplay); if (track.mode === "showing") { track.addEventListener("cuechange", updateDisplay); } } }; textTracksChanges(); tracks.addEventListener("change", textTracksChanges); tracks.addEventListener("addtrack", textTracksChanges); tracks.addEventListener("removetrack", textTracksChanges); this.on("dispose", function() { remoteTracks.off("addtrack", handleAddTrack); remoteTracks.off("removetrack", handleRemoveTrack); tracks.removeEventListener("change", textTracksChanges); tracks.removeEventListener("addtrack", textTracksChanges); tracks.removeEventListener("removetrack", textTracksChanges); for (let i = 0; i < tracks.length; i++) { const track = tracks[i]; track.removeEventListener("cuechange", updateDisplay); } }); } /** * Create and returns a remote {@link TextTrack} object. * * @param {string} kind * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata) * * @param {string} [label] * Label to identify the text track * * @param {string} [language] * Two letter language abbreviation * * @return {TextTrack} * The TextTrack that gets created. */ addTextTrack(kind, label, language) { if (!kind) { throw new Error("TextTrack kind is required but was not provided"); } return createTrackHelper(this, kind, label, language); } /** * Create an emulated TextTrack for use by addRemoteTextTrack * * This is intended to be overridden by classes that inherit from * Tech in order to create native or custom TextTracks. * * @param {Object} options * The object should contain the options to initialize the TextTrack with. * * @param {string} [options.kind] * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata). * * @param {string} [options.label]. * Label to identify the text track * * @param {string} [options.language] * Two letter language abbreviation. * * @return {HTMLTrackElement} * The track element that gets created. */ createRemoteTextTrack(options) { const track = merge$1(options, { tech: this }); return new REMOTE.remoteTextEl.TrackClass(track); } /** * Creates a remote text track object and returns an html track element. * * > Note: This can be an emulated {@link HTMLTrackElement} or a native one. * * @param {Object} options * See {@link Tech#createRemoteTextTrack} for more detailed properties. * * @param {boolean} [manualCleanup=false] * - When false: the TextTrack will be automatically removed from the video * element whenever the source changes * - When True: The TextTrack will have to be cleaned up manually * * @return {HTMLTrackElement} * An Html Track Element. * */ addRemoteTextTrack(options = {}, manualCleanup) { const htmlTrackElement = this.createRemoteTextTrack(options); if (typeof manualCleanup !== "boolean") { manualCleanup = false; } this.remoteTextTrackEls().addTrackElement_(htmlTrackElement); this.remoteTextTracks().addTrack(htmlTrackElement.track); if (manualCleanup === false) { this.ready(() => this.autoRemoteTextTracks_.addTrack(htmlTrackElement.track)); } return htmlTrackElement; } /** * Remove a remote text track from the remote `TextTrackList`. * * @param {TextTrack} track * `TextTrack` to remove from the `TextTrackList` */ removeRemoteTextTrack(track) { const trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track); this.remoteTextTrackEls().removeTrackElement_(trackElement); this.remoteTextTracks().removeTrack(track); this.autoRemoteTextTracks_.removeTrack(track); } /** * Gets available media playback quality metrics as specified by the W3C's Media * Playback Quality API. * * @see [Spec]{@link https://wicg.github.io/media-playback-quality} * * @return {Object} * An object with supported media playback quality metrics * * @abstract */ getVideoPlaybackQuality() { return {}; } /** * Attempt to create a floating video window always on top of other windows * so that users may continue consuming media while they interact with other * content sites, or applications on their device. * * @see [Spec]{@link https://wicg.github.io/picture-in-picture} * * @return {Promise|undefined} * A promise with a Picture-in-Picture window if the browser supports * Promises (or one was passed in as an option). It returns undefined * otherwise. * * @abstract */ requestPictureInPicture() { return Promise.reject(); } /** * A method to check for the value of the 'disablePictureInPicture'